/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.keyguard;

import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

import com.android.keyguard.KeyguardActivityLauncher.CameraWidgetInfo;

public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener {
    private static final String TAG = CameraWidgetFrame.class.getSimpleName();
    private static final boolean DEBUG = KeyguardHostView.DEBUG;
    private static final int WIDGET_ANIMATION_DURATION = 250; // ms
    private static final int WIDGET_WAIT_DURATION = 650; // ms
    private static final int RECOVERY_DELAY = 1000; // ms

    interface Callbacks {
        void onLaunchingCamera();
        void onCameraLaunchedSuccessfully();
        void onCameraLaunchedUnsuccessfully();
    }

    private final Handler mHandler = new Handler();
    private final KeyguardActivityLauncher mActivityLauncher;
    private final Callbacks mCallbacks;
    private final CameraWidgetInfo mWidgetInfo;
    private final WindowManager mWindowManager;
    private final Point mRenderedSize = new Point();
    private final int[] mTmpLoc = new int[2];
    private final Rect mTmpRect = new Rect();

    private long mLaunchCameraStart;
    private boolean mActive;
    private boolean mTransitioning;
    private boolean mDown;

    private FixedSizeFrameLayout mPreview;
    private View mFullscreenPreview;

    private final Runnable mTransitionToCameraRunnable = new Runnable() {
        @Override
        public void run() {
            transitionToCamera();
        }};

    private final Runnable mTransitionToCameraEndAction = new Runnable() {
        @Override
        public void run() {
            if (!mTransitioning)
                return;
            Handler worker =  getWorkerHandler() != null ? getWorkerHandler() : mHandler;
            mLaunchCameraStart = SystemClock.uptimeMillis();
            if (DEBUG) Log.d(TAG, "Launching camera at " + mLaunchCameraStart);
            mActivityLauncher.launchCamera(worker, mSecureCameraActivityStartedRunnable);
        }};

    private final Runnable mPostTransitionToCameraEndAction = new Runnable() {
        @Override
        public void run() {
            mHandler.post(mTransitionToCameraEndAction);
        }};

    private final Runnable mRecoverRunnable = new Runnable() {
        @Override
        public void run() {
            recover();
        }};

    private final Runnable mRenderRunnable = new Runnable() {
        @Override
        public void run() {
            render();
        }};

    private final Runnable mSecureCameraActivityStartedRunnable = new Runnable() {
        @Override
        public void run() {
            onSecureCameraActivityStarted();
        }
    };

    private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
        private boolean mShowing;
        void onKeyguardVisibilityChanged(boolean showing) {
            if (mShowing == showing)
                return;
            mShowing = showing;
            CameraWidgetFrame.this.onKeyguardVisibilityChanged(mShowing);
        };
    };

    private static final class FixedSizeFrameLayout extends FrameLayout {
        int width;
        int height;

        FixedSizeFrameLayout(Context context) {
            super(context);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            measureChildren(
                    MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
            setMeasuredDimension(width, height);
        }
    }

    private CameraWidgetFrame(Context context, Callbacks callbacks,
            KeyguardActivityLauncher activityLauncher,
            CameraWidgetInfo widgetInfo, View previewWidget) {
        super(context);
        mCallbacks = callbacks;
        mActivityLauncher = activityLauncher;
        mWidgetInfo = widgetInfo;
        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        KeyguardUpdateMonitor.getInstance(context).registerCallback(mCallback);

        mPreview = new FixedSizeFrameLayout(context);
        mPreview.addView(previewWidget);
        addView(mPreview);

        View clickBlocker = new View(context);
        clickBlocker.setBackgroundColor(Color.TRANSPARENT);
        clickBlocker.setOnClickListener(this);
        addView(clickBlocker);

        setContentDescription(context.getString(R.string.keyguard_accessibility_camera));
        if (DEBUG) Log.d(TAG, "new CameraWidgetFrame instance " + instanceId());
    }

    public static CameraWidgetFrame create(Context context, Callbacks callbacks,
            KeyguardActivityLauncher launcher) {
        if (context == null || callbacks == null || launcher == null)
            return null;

        CameraWidgetInfo widgetInfo = launcher.getCameraWidgetInfo();
        if (widgetInfo == null)
            return null;
        View previewWidget = getPreviewWidget(context, widgetInfo);
        if (previewWidget == null)
            return null;

        return new CameraWidgetFrame(context, callbacks, launcher, widgetInfo, previewWidget);
    }

    private static View getPreviewWidget(Context context, CameraWidgetInfo widgetInfo) {
        return widgetInfo.layoutId > 0 ?
                inflateWidgetView(context, widgetInfo) :
                inflateGenericWidgetView(context);
    }

    private static View inflateWidgetView(Context context, CameraWidgetInfo widgetInfo) {
        if (DEBUG) Log.d(TAG, "inflateWidgetView: " + widgetInfo.contextPackage);
        View widgetView = null;
        Exception exception = null;
        try {
            Context cameraContext = context.createPackageContext(
                    widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED);
            LayoutInflater cameraInflater = (LayoutInflater)
                    cameraContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            cameraInflater = cameraInflater.cloneInContext(cameraContext);
            widgetView = cameraInflater.inflate(widgetInfo.layoutId, null, false);
        } catch (NameNotFoundException e) {
            exception = e;
        } catch (RuntimeException e) {
            exception = e;
        }
        if (exception != null) {
            Log.w(TAG, "Error creating camera widget view", exception);
        }
        return widgetView;
    }

    private static View inflateGenericWidgetView(Context context) {
        if (DEBUG) Log.d(TAG, "inflateGenericWidgetView");
        ImageView iv = new ImageView(context);
        iv.setImageResource(R.drawable.ic_lockscreen_camera);
        iv.setScaleType(ScaleType.CENTER);
        iv.setBackgroundColor(Color.argb(127, 0, 0, 0));
        return iv;
    }

    private void render() {
        final View root = getRootView();
        final int width = root.getWidth();
        final int height = root.getHeight();
        if (mRenderedSize.x == width && mRenderedSize.y == height) {
            if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s", width, height));
            return;
        }
        if (width == 0 || height == 0) {
            return;
        }

        mPreview.width = width;
        mPreview.height = height;
        mPreview.requestLayout();

        final int thisWidth = getWidth() - getPaddingLeft() - getPaddingRight();
        final int thisHeight = getHeight() - getPaddingTop() - getPaddingBottom();

        final float pvScaleX = (float) thisWidth / width;
        final float pvScaleY = (float) thisHeight / height;
        final float pvScale = Math.min(pvScaleX, pvScaleY);

        final int pvWidth = (int) (pvScale * width);
        final int pvHeight = (int) (pvScale * height);

        final float pvTransX = pvWidth < thisWidth ? (thisWidth - pvWidth) / 2 : 0;
        final float pvTransY = pvHeight < thisHeight ? (thisHeight - pvHeight) / 2 : 0;

        mPreview.setPivotX(0);
        mPreview.setPivotY(0);
        mPreview.setScaleX(pvScale);
        mPreview.setScaleY(pvScale);
        mPreview.setTranslationX(pvTransX);
        mPreview.setTranslationY(pvTransY);

        mRenderedSize.set(width, height);
        if (DEBUG) Log.d(TAG, String.format("Rendered camera widget size=%sx%s instance=%s",
                width, height, instanceId()));
    }

    private void transitionToCamera() {
        if (mTransitioning || mDown) return;

        mTransitioning = true;

        enableWindowExitAnimation(false);

        mPreview.getLocationInWindow(mTmpLoc);
        final float pvHeight = mPreview.getHeight() * mPreview.getScaleY();
        final float pvCenter = mTmpLoc[1] + pvHeight / 2f;

        final ViewGroup root = (ViewGroup) getRootView();
        if (mFullscreenPreview == null) {
            mFullscreenPreview = getPreviewWidget(mContext, mWidgetInfo);
            mFullscreenPreview.setClickable(false);
            root.addView(mFullscreenPreview);
        }

        root.getWindowVisibleDisplayFrame(mTmpRect);
        final float fsHeight = mTmpRect.height();
        final float fsCenter = mTmpRect.top + fsHeight / 2;

        final float fsScaleY = pvHeight / fsHeight;
        final float fsTransY = pvCenter - fsCenter;
        final float fsScaleX = mPreview.getScaleX();

        mPreview.setVisibility(View.GONE);
        mFullscreenPreview.setVisibility(View.VISIBLE);
        mFullscreenPreview.setTranslationY(fsTransY);
        mFullscreenPreview.setScaleX(fsScaleX);
        mFullscreenPreview.setScaleY(fsScaleY);
        mFullscreenPreview
            .animate()
            .scaleX(1)
            .scaleY(1)
            .translationX(0)
            .translationY(0)
            .setDuration(WIDGET_ANIMATION_DURATION)
            .withEndAction(mPostTransitionToCameraEndAction)
            .start();
        mCallbacks.onLaunchingCamera();
    }

    private void recover() {
        if (DEBUG) Log.d(TAG, "recovering at " + SystemClock.uptimeMillis());
        mCallbacks.onCameraLaunchedUnsuccessfully();
        reset();
    }

    @Override
    public void setOnLongClickListener(OnLongClickListener l) {
        // ignore
    }

    @Override
    public void onClick(View v) {
        if (DEBUG) Log.d(TAG, "clicked");
        if (mTransitioning) return;
        if (mActive) {
            cancelTransitionToCamera();
            transitionToCamera();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        if (DEBUG) Log.d(TAG, "onDetachedFromWindow: instance " + instanceId()
                + " at " + SystemClock.uptimeMillis());
        super.onDetachedFromWindow();
        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
        cancelTransitionToCamera();
        mHandler.removeCallbacks(mRecoverRunnable);
    }

    @Override
    public void onActive(boolean isActive) {
        mActive = isActive;
        if (mActive) {
            rescheduleTransitionToCamera();
        } else {
            reset();
        }
    }

    @Override
    public boolean onUserInteraction(MotionEvent event) {
        if (mTransitioning) {
            if (DEBUG) Log.d(TAG, "onUserInteraction eaten: mTransitioning");
            return true;
        }

        getLocationOnScreen(mTmpLoc);
        int rawBottom = mTmpLoc[1] + getHeight();
        if (event.getRawY() > rawBottom) {
            if (DEBUG) Log.d(TAG, "onUserInteraction eaten: below widget");
            return true;
        }

        int action = event.getAction();
        mDown = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE;
        if (mActive) {
            rescheduleTransitionToCamera();
        }
        if (DEBUG) Log.d(TAG, "onUserInteraction observed, not eaten");
        return false;
    }

    @Override
    protected void onFocusLost() {
        if (DEBUG) Log.d(TAG, "onFocusLost at " + SystemClock.uptimeMillis());
        cancelTransitionToCamera();
        super.onFocusLost();
    }

    public void onScreenTurnedOff() {
        if (DEBUG) Log.d(TAG, "onScreenTurnedOff");
        reset();
    }

    private void rescheduleTransitionToCamera() {
        if (DEBUG) Log.d(TAG, "rescheduleTransitionToCamera at " + SystemClock.uptimeMillis());
        mHandler.removeCallbacks(mTransitionToCameraRunnable);
        mHandler.postDelayed(mTransitionToCameraRunnable, WIDGET_WAIT_DURATION);
    }

    private void cancelTransitionToCamera() {
        if (DEBUG) Log.d(TAG, "cancelTransitionToCamera at " + SystemClock.uptimeMillis());
        mHandler.removeCallbacks(mTransitionToCameraRunnable);
    }

    private void onCameraLaunched() {
        mCallbacks.onCameraLaunchedSuccessfully();
        reset();
    }

    private void reset() {
        if (DEBUG) Log.d(TAG, "reset at " + SystemClock.uptimeMillis());
        mLaunchCameraStart = 0;
        mTransitioning = false;
        mDown = false;
        cancelTransitionToCamera();
        mHandler.removeCallbacks(mRecoverRunnable);
        mPreview.setVisibility(View.VISIBLE);
        if (mFullscreenPreview != null) {
            mFullscreenPreview.animate().cancel();
            mFullscreenPreview.setVisibility(View.GONE);
        }
        enableWindowExitAnimation(true);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (DEBUG) Log.d(TAG, String.format("onSizeChanged new=%sx%s old=%sx%s at %s",
                w, h, oldw, oldh, SystemClock.uptimeMillis()));
        mHandler.post(mRenderRunnable);
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    public void onBouncerShowing(boolean showing) {
        if (showing) {
            mTransitioning = false;
            mHandler.post(mRecoverRunnable);
        }
    }

    private void enableWindowExitAnimation(boolean isEnabled) {
        View root = getRootView();
        ViewGroup.LayoutParams lp = root.getLayoutParams();
        if (!(lp instanceof WindowManager.LayoutParams))
            return;
        WindowManager.LayoutParams wlp = (WindowManager.LayoutParams) lp;
        int newWindowAnimations = isEnabled ? R.style.Animation_LockScreen : 0;
        if (newWindowAnimations != wlp.windowAnimations) {
            if (DEBUG) Log.d(TAG, "setting windowAnimations to: " + newWindowAnimations
                    + " at " + SystemClock.uptimeMillis());
            wlp.windowAnimations = newWindowAnimations;
            mWindowManager.updateViewLayout(root, wlp);
        }
    }

    private void onKeyguardVisibilityChanged(boolean showing) {
        if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged " + showing
                + " at " + SystemClock.uptimeMillis());
        if (mTransitioning && !showing) {
            mTransitioning = false;
            mHandler.removeCallbacks(mRecoverRunnable);
            if (mLaunchCameraStart > 0) {
                long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart;
                if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime));
                mLaunchCameraStart = 0;
                onCameraLaunched();
            }
        }
    }

    private void onSecureCameraActivityStarted() {
        if (DEBUG) Log.d(TAG, "onSecureCameraActivityStarted at " + SystemClock.uptimeMillis());
        mHandler.postDelayed(mRecoverRunnable, RECOVERY_DELAY);
    }

    private String instanceId() {
        return Integer.toHexString(hashCode());
    }
}
