/*
 * Copyright (C) 2011 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;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.android.camera.ui.Rotatable;
import com.android.camera.ui.RotateLayout;
import com.android.gallery3d.R;

public class RotateDialogController implements Rotatable {

    @SuppressWarnings("unused")
    private static final String TAG = "RotateDialogController";
    private static final long ANIM_DURATION = 150;  // millis

    private Activity mActivity;
    private int mLayoutResourceID;
    private View mDialogRootLayout;
    private RotateLayout mRotateDialog;
    private View mRotateDialogTitleLayout;
    private View mRotateDialogButtonLayout;
    private TextView mRotateDialogTitle;
    private ProgressBar mRotateDialogSpinner;
    private TextView mRotateDialogText;
    private TextView mRotateDialogButton1;
    private TextView mRotateDialogButton2;

    private Animation mFadeInAnim, mFadeOutAnim;

    public RotateDialogController(Activity a, int layoutResource) {
        mActivity = a;
        mLayoutResourceID = layoutResource;
    }

    private void inflateDialogLayout() {
        if (mDialogRootLayout == null) {
            ViewGroup layoutRoot = (ViewGroup) mActivity.getWindow().getDecorView();
            LayoutInflater inflater = mActivity.getLayoutInflater();
            View v = inflater.inflate(mLayoutResourceID, layoutRoot);
            mDialogRootLayout = v.findViewById(R.id.rotate_dialog_root_layout);
            mRotateDialog = (RotateLayout) v.findViewById(R.id.rotate_dialog_layout);
            mRotateDialogTitleLayout = v.findViewById(R.id.rotate_dialog_title_layout);
            mRotateDialogButtonLayout = v.findViewById(R.id.rotate_dialog_button_layout);
            mRotateDialogTitle = (TextView) v.findViewById(R.id.rotate_dialog_title);
            mRotateDialogSpinner = (ProgressBar) v.findViewById(R.id.rotate_dialog_spinner);
            mRotateDialogText = (TextView) v.findViewById(R.id.rotate_dialog_text);
            mRotateDialogButton1 = (Button) v.findViewById(R.id.rotate_dialog_button1);
            mRotateDialogButton2 = (Button) v.findViewById(R.id.rotate_dialog_button2);

            mFadeInAnim = AnimationUtils.loadAnimation(
                    mActivity, android.R.anim.fade_in);
            mFadeOutAnim = AnimationUtils.loadAnimation(
                    mActivity, android.R.anim.fade_out);
            mFadeInAnim.setDuration(ANIM_DURATION);
            mFadeOutAnim.setDuration(ANIM_DURATION);
        }
    }

    @Override
    public void setOrientation(int orientation, boolean animation) {
        inflateDialogLayout();
        mRotateDialog.setOrientation(orientation, animation);
    }

    public void resetRotateDialog() {
        inflateDialogLayout();
        mRotateDialogTitleLayout.setVisibility(View.GONE);
        mRotateDialogSpinner.setVisibility(View.GONE);
        mRotateDialogButton1.setVisibility(View.GONE);
        mRotateDialogButton2.setVisibility(View.GONE);
        mRotateDialogButtonLayout.setVisibility(View.GONE);
    }

    private void fadeOutDialog() {
        mDialogRootLayout.startAnimation(mFadeOutAnim);
        mDialogRootLayout.setVisibility(View.GONE);
    }

    private void fadeInDialog() {
        mDialogRootLayout.startAnimation(mFadeInAnim);
        mDialogRootLayout.setVisibility(View.VISIBLE);
    }

    public void dismissDialog() {
        if (mDialogRootLayout != null && mDialogRootLayout.getVisibility() != View.GONE) {
            fadeOutDialog();
        }
    }

    public void showAlertDialog(String title, String msg, String button1Text,
                final Runnable r1, String button2Text, final Runnable r2) {
        resetRotateDialog();

        if (title != null) {
            mRotateDialogTitle.setText(title);
            mRotateDialogTitleLayout.setVisibility(View.VISIBLE);
        }

        mRotateDialogText.setText(msg);

        if (button1Text != null) {
            mRotateDialogButton1.setText(button1Text);
            mRotateDialogButton1.setContentDescription(button1Text);
            mRotateDialogButton1.setVisibility(View.VISIBLE);
            mRotateDialogButton1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (r1 != null) r1.run();
                    dismissDialog();
                }
            });
            mRotateDialogButtonLayout.setVisibility(View.VISIBLE);
        }
        if (button2Text != null) {
            mRotateDialogButton2.setText(button2Text);
            mRotateDialogButton2.setContentDescription(button2Text);
            mRotateDialogButton2.setVisibility(View.VISIBLE);
            mRotateDialogButton2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (r2 != null) r2.run();
                    dismissDialog();
                }
            });
            mRotateDialogButtonLayout.setVisibility(View.VISIBLE);
        }

        fadeInDialog();
    }

    public void showWaitingDialog(String msg) {
        resetRotateDialog();

        mRotateDialogText.setText(msg);
        mRotateDialogSpinner.setVisibility(View.VISIBLE);

        fadeInDialog();
    }

    public int getVisibility() {
        if (mDialogRootLayout != null) {
            return mDialogRootLayout.getVisibility();
        }
        return View.INVISIBLE;
    }
}
