/*
 * Copyright (C) 2013 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.camera.ui;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;

import com.android.camera.Util;
import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;

public class CameraControls extends RotatableLayout {

    private static final String TAG = "CAM_Controls";

    private View mBackgroundView;
    private View mShutter;
    private View mSwitcher;
    private View mMenu;
    private View mIndicators;
    private View mPreview;
    private Object mDisplayListener = null;
    private int mLastRotation = 0;

    public CameraControls(Context context, AttributeSet attrs) {
        super(context, attrs);
        initDisplayListener();
    }

    public CameraControls(Context context) {
        super(context);
        initDisplayListener();
    }

    public void initDisplayListener() {
        if (ApiHelper.HAS_DISPLAY_LISTENER) {
            mDisplayListener = new DisplayListener() {

                @Override
                public void onDisplayAdded(int arg0) {}

                @Override
                public void onDisplayChanged(int arg0) {
                    checkLayoutFlip();
                }

                @Override
                public void onDisplayRemoved(int arg0) {}
            };
        }
    }

    private void checkLayoutFlip() {
        int currentRotation = Util.getDisplayRotation((Activity) getContext());
        if ((currentRotation - mLastRotation + 360) % 360 == 180) {
            mLastRotation = currentRotation;
            flipChildren();
            getParent().requestLayout();
        }
    }

    @Override
    public void onFinishInflate() {
        super.onFinishInflate();
        mBackgroundView = findViewById(R.id.blocker);
        mSwitcher = findViewById(R.id.camera_switcher);
        mShutter = findViewById(R.id.shutter_button);
        mMenu = findViewById(R.id.menu);
        mIndicators = findViewById(R.id.on_screen_indicators);
        mPreview = findViewById(R.id.preview_thumb);
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        adjustControlsToRightPosition();
        mLastRotation = Util.getDisplayRotation((Activity) getContext());
        if (ApiHelper.HAS_DISPLAY_LISTENER) {
            ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
            .registerDisplayListener((DisplayListener) mDisplayListener, null);
        }
    }

    @Override
    public void onWindowVisibilityChanged(int visibility) {
        if (visibility == View.VISIBLE) {
            // Make sure when coming back from onPause, the layout is rotated correctly
            checkLayoutFlip();
        }
    }

    @Override
    public void onDetachedFromWindow () {
        super.onDetachedFromWindow();
        if (ApiHelper.HAS_DISPLAY_LISTENER) {
            ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
            .unregisterDisplayListener((DisplayListener) mDisplayListener);
        }
    }

    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        mLastRotation = Util.getDisplayRotation((Activity) getContext());
        int orientation = getResources().getConfiguration().orientation;
        int size = getResources().getDimensionPixelSize(R.dimen.camera_controls_size);
        int rotation = getUnifiedRotation();
        adjustBackground();
        // As l,t,r,b are positions relative to parents, we need to convert them
        // to child's coordinates
        r = r - l;
        b = b - t;
        l = 0;
        t = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View v = getChildAt(i);
            v.layout(l, t, r, b);
        }
        Rect shutter = new Rect();
        topRight(mPreview, l, t, r, b);
        if (size > 0) {
            // restrict controls to size
            switch (rotation) {
            case 0:
            case 180:
                l = (l + r - size) / 2;
                r = l + size;
                break;
            case 90:
            case 270:
                t = (t + b - size) / 2;
                b = t + size;
                break;
            }
        }
        center(mShutter, l, t, r, b, orientation, rotation, shutter);
        center(mBackgroundView, l, t, r, b, orientation, rotation, new Rect());
        toLeft(mSwitcher, shutter, rotation);
        toRight(mMenu, shutter, rotation);
        toRight(mIndicators, shutter, rotation);
        View retake = findViewById(R.id.btn_retake);
        if (retake != null) {
            center(retake, shutter, rotation);
            View cancel = findViewById(R.id.btn_cancel);
            toLeft(cancel, shutter, rotation);
            View done = findViewById(R.id.btn_done);
            toRight(done, shutter, rotation);
        }
    }

    private int getUnifiedRotation() {
        // all the layout code assumes camera device orientation to be portrait
        // adjust rotation for landscape
        int orientation = getResources().getConfiguration().orientation;
        int rotation = Util.getDisplayRotation((Activity) getContext());
        int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT
                : Configuration.ORIENTATION_LANDSCAPE;
        if (camOrientation != orientation) {
            return (rotation + 90) % 360;
        }
        return rotation;
    }

    private void center(View v, int l, int t, int r, int b, int orientation, int rotation, Rect result) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
        int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
        int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
        switch (rotation) {
        case 0:
            // phone portrait; controls bottom
            result.left = (r + l) / 2 - tw / 2 + lp.leftMargin;
            result.right = (r + l) / 2 + tw / 2 - lp.rightMargin;
            result.bottom = b - lp.bottomMargin;
            result.top = b - th + lp.topMargin;
            break;
        case 90:
            // phone landscape: controls right
            result.right = r - lp.rightMargin;
            result.left = r - tw + lp.leftMargin;
            result.top = (b + t) / 2 - th / 2 + lp.topMargin;
            result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin;
            break;
        case 180:
            // phone upside down: controls top
            result.left = (r + l) / 2 - tw / 2 + lp.leftMargin;
            result.right = (r + l) / 2 + tw / 2 - lp.rightMargin;
            result.top = t + lp.topMargin;
            result.bottom = t + th - lp.bottomMargin;
            break;
        case 270:
            // reverse landscape: controls left
            result.left = l + lp.leftMargin;
            result.right = l + tw - lp.rightMargin;
            result.top = (b + t) / 2 - th / 2 + lp.topMargin;
            result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin;
            break;
        }
        v.layout(result.left, result.top, result.right, result.bottom);
    }

    private void center(View v, Rect other, int rotation) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
        int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
        int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
        int cx = (other.left + other.right) / 2;
        int cy = (other.top + other.bottom) / 2;
        v.layout(cx - tw / 2 + lp.leftMargin,
                cy - th / 2 + lp.topMargin,
                cx + tw / 2 - lp.rightMargin,
                cy + th / 2 - lp.bottomMargin);
    }

    private void toLeft(View v, Rect other, int rotation) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
        int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
        int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
        int cx = (other.left + other.right) / 2;
        int cy = (other.top + other.bottom) / 2;
        int l = 0, r = 0, t = 0, b = 0;
        switch (rotation) {
        case 0:
            // portrait, to left of anchor at bottom
            l = other.left - tw + lp.leftMargin;
            r = other.left - lp.rightMargin;
            t = cy - th / 2 + lp.topMargin;
            b = cy + th / 2 - lp.bottomMargin;
            break;
        case 90:
            // phone landscape: below anchor on right
            l = cx - tw / 2 + lp.leftMargin;
            r = cx + tw / 2 - lp.rightMargin;
            t = other.bottom + lp.topMargin;
            b = other.bottom + th - lp.bottomMargin;
            break;
        case 180:
            // phone upside down: right of anchor at top
            l = other.right + lp.leftMargin;
            r = other.right + tw - lp.rightMargin;
            t = cy - th / 2 + lp.topMargin;
            b = cy + th / 2 - lp.bottomMargin;
            break;
        case 270:
            // reverse landscape: above anchor on left
            l = cx - tw / 2 + lp.leftMargin;
            r = cx + tw / 2 - lp.rightMargin;
            t = other.top - th + lp.topMargin;
            b = other.top - lp.bottomMargin;
            break;
        }
        v.layout(l, t, r, b);
    }

    private void toRight(View v, Rect other, int rotation) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
        int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
        int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
        int cx = (other.left + other.right) / 2;
        int cy = (other.top + other.bottom) / 2;
        int l = 0, r = 0, t = 0, b = 0;
        switch (rotation) {
        case 0:
            l = other.right + lp.leftMargin;
            r = other.right + tw - lp.rightMargin;
            t = cy - th / 2 + lp.topMargin;
            b = cy + th / 2 - lp.bottomMargin;
            break;
        case 90:
            l = cx - tw / 2 + lp.leftMargin;
            r = cx + tw / 2 - lp.rightMargin;
            t = other.top - th + lp.topMargin;
            b = other.top - lp.bottomMargin;
            break;
        case 180:
            l = other.left - tw + lp.leftMargin;
            r = other.left - lp.rightMargin;
            t = cy - th / 2 + lp.topMargin;
            b = cy + th / 2 - lp.bottomMargin;
            break;
        case 270:
            l = cx - tw / 2 + lp.leftMargin;
            r = cx + tw / 2 - lp.rightMargin;
            t = other.bottom + lp.topMargin;
            b = other.bottom + th - lp.bottomMargin;
            break;
        }
        v.layout(l, t, r, b);
    }

    private void topRight(View v, int l, int t, int r, int b) {
        // layout using the specific margins; the rotation code messes up the others
        int mt = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_top);
        int mr = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_right);
        v.layout(r - v.getMeasuredWidth() - mr, t + mt, r - mr, t + mt + v.getMeasuredHeight());
    }

    // In reverse landscape and reverse portrait, camera controls will be laid out
    // on the wrong side of the screen. We need to make adjustment to move the controls
    // to the USB side
    public void adjustControlsToRightPosition() {
        int orientation = getUnifiedRotation();
        if (orientation >= 180) {
            flipChildren();
        }
    }

    private void adjustBackground() {
        int rotation = getUnifiedRotation();
        // remove current drawable and reset rotation
        mBackgroundView.setBackgroundDrawable(null);
        mBackgroundView.setRotationX(0);
        mBackgroundView.setRotationY(0);
        // if the switcher background is top aligned we need to flip the background
        // drawable vertically; if left aligned, flip horizontally
        switch (rotation) {
            case 180:
                mBackgroundView.setRotationX(180);
                break;
            case 270:
                mBackgroundView.setRotationY(180);
                break;
            default:
                break;
        }
        mBackgroundView.setBackgroundResource(R.drawable.switcher_bg);
    }

}
