/*
 * Copyright (C) 2014 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.widget;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.android.camera.ShutterButton;
import com.android.camera.debug.Log;
import com.android.camera.ui.PreviewOverlay;
import com.android.camera.ui.PreviewStatusListener;
import com.android.camera2.R;

/**
 * ModeOptionsOverlay is a FrameLayout which positions mode options in
 * in the bottom of the preview that is visible above the bottom bar.
 */
public class ModeOptionsOverlay extends FrameLayout
    implements PreviewStatusListener.PreviewAreaChangedListener,
               PreviewOverlay.OnPreviewTouchedListener,
               IndicatorIconController.OnIndicatorVisibilityChangedListener,
               ShutterButton.OnShutterButtonListener {

    private final static Log.Tag TAG = new Log.Tag("ModeOptionsOverlay");

    private static final int BOTTOMBAR_OPTIONS_TIMEOUT_MS = 2000;
    private final static int BOTTOM_RIGHT = Gravity.BOTTOM | Gravity.RIGHT;
    private final static int TOP_RIGHT = Gravity.TOP | Gravity.RIGHT;

    private int mPreviewWidth;
    private int mPreviewHeight;

    private ModeOptions mModeOptions;

    // The mode options toggle can be either a default image, or a
    // group of on screen indicators.
    private FrameLayout mModeOptionsToggle;
    // Default image for mode options toggle.
    private ImageView mThreeDots;
    // Group of on screen indicators for mode options toggle.
    private LinearLayout mIndicators;

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

    @Override
    public void onFinishInflate() {
        mModeOptions = (ModeOptions) findViewById(R.id.mode_options);
        mModeOptions.setClickable(true);
        mModeOptions.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                closeModeOptions();
            }
        });

        mModeOptionsToggle = (FrameLayout) findViewById(R.id.mode_options_toggle);
        mModeOptionsToggle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mModeOptions.animateVisible();
            }
        });
        mModeOptions.setViewToShowHide(mModeOptionsToggle);

        mThreeDots = (ImageView) findViewById(R.id.three_dots);
        mIndicators = (LinearLayout) findViewById(R.id.indicator_icons);
        showCorrectToggleView(mThreeDots, mIndicators);
    }

    @Override
    public void onPreviewTouched(MotionEvent ev) {
        closeModeOptions();
    }

    @Override
    public void onIndicatorVisibilityChanged(View indicator) {
        showCorrectToggleView(mThreeDots, mIndicators);
    }

    @Override
    public void onShutterButtonClick() {
        closeModeOptions();
    }

    @Override
    public void onShutterButtonFocus(boolean pressed) {
    }

    /**
     * Schedule (or re-schedule) the options menu to be closed after a number
     * of milliseconds.  If the options menu is already closed, nothing is
     * scheduled.
     */
    private void closeModeOptions() {
        mModeOptions.animateHidden();
    }

    @Override
    public void onConfigurationChanged(Configuration configuration) {
        super.onConfigurationChanged(configuration);
        checkOrientation(configuration.orientation);
    }

    @Override
    public void onPreviewAreaChanged(RectF previewArea) {
        mPreviewWidth = (int) previewArea.width();
        mPreviewHeight = (int) previewArea.height();
        setLayoutDimensions();
    }

    /**
     * The overlay takes its horizontal dimension from the preview.  The vertical
     * dimension of the overlay is determined by its parent layout, which has
     * knowledge of the bottom bar dimensions.
     */
    private void setLayoutDimensions() {
        if (mPreviewWidth == 0 || mPreviewHeight == 0) {
            return;
        }

        boolean isPortrait = Configuration.ORIENTATION_PORTRAIT
            == getResources().getConfiguration().orientation;

        ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) getLayoutParams();
        if (isPortrait) {
            params.width = mPreviewWidth;
        } else {
            params.height = mPreviewHeight;
        }
        setLayoutParams(params);
    }

    /**
     * Set the layout gravity of the child layout to be bottom or top right
     * depending on orientation.
     */
    private void checkOrientation(int orientation) {
        final boolean isPortrait = Configuration.ORIENTATION_PORTRAIT == orientation;

        FrameLayout.LayoutParams modeOptionsParams
            = (FrameLayout.LayoutParams) mModeOptions.getLayoutParams();
        FrameLayout.LayoutParams modeOptionsToggleParams
            = (FrameLayout.LayoutParams) mModeOptionsToggle.getLayoutParams();

        if (isPortrait) {
            modeOptionsParams.height = modeOptionsParams.width;
            modeOptionsParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
            if (modeOptionsParams.gravity != Gravity.BOTTOM) {
                modeOptionsParams.gravity = Gravity.BOTTOM;
            }

            if (modeOptionsToggleParams.gravity != BOTTOM_RIGHT) {
                modeOptionsToggleParams.gravity = BOTTOM_RIGHT;
            }

            // Remove the rotation on the three dots.
            mThreeDots.setImageMatrix(new Matrix());
        } else if (!isPortrait) {
            modeOptionsParams.width = modeOptionsParams.height;
            modeOptionsParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
            if (modeOptionsParams.gravity != Gravity.RIGHT) {
                modeOptionsParams.gravity = Gravity.RIGHT;
            }

            if (modeOptionsToggleParams.gravity != TOP_RIGHT) {
                modeOptionsToggleParams.gravity = TOP_RIGHT;
            }

            // Rotate the three dots 90 to match portrait.
            Matrix matrix = new Matrix();
            matrix.setRotate(90, mThreeDots.getWidth() / 2 , mThreeDots.getHeight() / 2);
            mThreeDots.setImageMatrix(matrix);
        }

        requestLayout();
    }

    /**
     * Show the correct toggle view: the default view if the group has
     * no visible children, otherwise the default view.
     */
    private void showCorrectToggleView(View defaultView, ViewGroup group) {
        if (getVisibleChildCount(group) > 0) {
            defaultView.setVisibility(View.GONE);
            group.setVisibility(View.VISIBLE);
        } else {
            group.setVisibility(View.GONE);
            defaultView.setVisibility(View.VISIBLE);
        }
    }

    /**
     * Get the number of a ViewGroup's visible children.
     */
    private int getVisibleChildCount(ViewGroup group) {
        int visible = 0;
        for (int i = 0; i < group.getChildCount(); i++) {
            View child = group.getChildAt(i);
            if (child != null && child.getVisibility() == View.VISIBLE) {
                visible++;
            }
        }
        return visible;
    }
}
