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

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;


/**
 * Base class for a title bar used by the browser.
 */
public class TitleBar extends RelativeLayout {

    private static final int PROGRESS_MAX = 100;
    private static final float ANIM_TITLEBAR_DECELERATE = 2.5f;

    private UiController mUiController;
    private BaseUi mBaseUi;
    private FrameLayout mContentView;
    private PageProgressView mProgress;
    private AccessibilityManager mAccessibilityManager;

    private AutologinBar mAutoLogin;
    private NavigationBarBase mNavBar;
    private boolean mUseQuickControls;

    //state
    private boolean mShowing;
    private boolean mInLoad;
    private boolean mSkipTitleBarAnimations;
    private Animator mTitleBarAnimator;
    private boolean mIsFixedTitleBar;

    public TitleBar(Context context, UiController controller, BaseUi ui,
            FrameLayout contentView) {
        super(context, null);
        mUiController = controller;
        mBaseUi = ui;
        mContentView = contentView;
        mAccessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
        initLayout(context);
        setFixedTitleBar();
    }

    private void initLayout(Context context) {
        LayoutInflater factory = LayoutInflater.from(context);
        factory.inflate(R.layout.title_bar, this);
        mProgress = (PageProgressView) findViewById(R.id.progress);
        mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar);
        mNavBar.setTitleBar(this);
    }

    private void inflateAutoLoginBar() {
        if (mAutoLogin != null) {
            return;
        }

        ViewStub stub = (ViewStub) findViewById(R.id.autologin_stub);
        mAutoLogin = (AutologinBar) stub.inflate();
        mAutoLogin.setTitleBar(this);
    }

    @Override
    protected void onConfigurationChanged(Configuration config) {
        super.onConfigurationChanged(config);
        setFixedTitleBar();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mIsFixedTitleBar) {
            int margin = getMeasuredHeight() - calculateEmbeddedHeight();
            mBaseUi.setContentViewMarginTop(-margin);
        } else {
            mBaseUi.setContentViewMarginTop(0);
        }
    }

    private void setFixedTitleBar() {
        // If getParent() returns null, we are initializing
        ViewGroup parent = (ViewGroup)getParent();
        if (mIsFixedTitleBar && parent != null) return;
        mIsFixedTitleBar = true;
        setSkipTitleBarAnimations(true);
        show();
        setSkipTitleBarAnimations(false);
        if (parent != null) {
            parent.removeView(this);
        }
        if (mIsFixedTitleBar) {
            mBaseUi.addFixedTitleBar(this);
        } else {
            mContentView.addView(this, makeLayoutParams());
            mBaseUi.setContentViewMarginTop(0);
        }
    }

    public BaseUi getUi() {
        return mBaseUi;
    }

    public UiController getUiController() {
        return mUiController;
    }

    public void setUseQuickControls(boolean use) {
        mUseQuickControls = use;
        setFixedTitleBar();
        if (use) {
            this.setVisibility(View.GONE);
        } else {
            this.setVisibility(View.VISIBLE);
        }
    }

    void setShowProgressOnly(boolean progress) {
        if (progress && !wantsToBeVisible()) {
            mNavBar.setVisibility(View.GONE);
        } else {
            mNavBar.setVisibility(View.VISIBLE);
        }
    }

    void setSkipTitleBarAnimations(boolean skip) {
        mSkipTitleBarAnimations = skip;
    }

    void setupTitleBarAnimator(Animator animator) {
        Resources res = mContext.getResources();
        int duration = res.getInteger(R.integer.titlebar_animation_duration);
        animator.setInterpolator(new DecelerateInterpolator(
                ANIM_TITLEBAR_DECELERATE));
        animator.setDuration(duration);
    }

    void show() {
        cancelTitleBarAnimation(false);
        if (mUseQuickControls || mSkipTitleBarAnimations) {
            this.setVisibility(View.VISIBLE);
            this.setTranslationY(0);
        } else {
            int visibleHeight = getVisibleTitleHeight();
            float startPos = (-getEmbeddedHeight() + visibleHeight);
            if (getTranslationY() != 0) {
                startPos = Math.max(startPos, getTranslationY());
            }
            mTitleBarAnimator = ObjectAnimator.ofFloat(this,
                    "translationY",
                    startPos, 0);
            setupTitleBarAnimator(mTitleBarAnimator);
            mTitleBarAnimator.start();
        }
        mShowing = true;
    }

    void hide() {
        if (mUseQuickControls) {
            this.setVisibility(View.GONE);
        } else {
            if (mIsFixedTitleBar) return;
            if (!mSkipTitleBarAnimations) {
                cancelTitleBarAnimation(false);
                int visibleHeight = getVisibleTitleHeight();
                mTitleBarAnimator = ObjectAnimator.ofFloat(this,
                        "translationY", getTranslationY(),
                        (-getEmbeddedHeight() + visibleHeight));
                mTitleBarAnimator.addListener(mHideTileBarAnimatorListener);
                setupTitleBarAnimator(mTitleBarAnimator);
                mTitleBarAnimator.start();
            } else {
                onScrollChanged();
            }
        }
        mShowing = false;
    }

    boolean isShowing() {
        return mShowing;
    }

    void cancelTitleBarAnimation(boolean reset) {
        if (mTitleBarAnimator != null) {
            mTitleBarAnimator.cancel();
            mTitleBarAnimator = null;
        }
        if (reset) {
            setTranslationY(0);
        }
    }

    private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() {

        @Override
        public void onAnimationStart(Animator animation) {
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            // update position
            onScrollChanged();
        }

        @Override
        public void onAnimationCancel(Animator animation) {
        }
    };

    private int getVisibleTitleHeight() {
        Tab tab = mBaseUi.getActiveTab();
        WebView webview = tab != null ? tab.getWebView() : null;
        return webview != null ? webview.getVisibleTitleHeight() : 0;
    }

    /**
     * Update the progress, from 0 to 100.
     */
    public void setProgress(int newProgress) {
        if (newProgress >= PROGRESS_MAX) {
            mProgress.setProgress(PageProgressView.MAX_PROGRESS);
            mProgress.setVisibility(View.GONE);
            mInLoad = false;
            mNavBar.onProgressStopped();
            // check if needs to be hidden
            if (!isEditingUrl() && !wantsToBeVisible()) {
                if (mUseQuickControls) {
                    hide();
                } else {
                    mBaseUi.showTitleBarForDuration();
                }
            }
        } else {
            if (!mInLoad) {
                mProgress.setVisibility(View.VISIBLE);
                mInLoad = true;
                mNavBar.onProgressStarted();
            }
            mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
                    / PROGRESS_MAX);
            if (mUseQuickControls && !isEditingUrl()) {
                setShowProgressOnly(true);
            }
            if (!mShowing) {
                show();
            }
        }
    }

    public int getEmbeddedHeight() {
        if (mUseQuickControls || mIsFixedTitleBar) return 0;
        return calculateEmbeddedHeight();
    }

    private int calculateEmbeddedHeight() {
        int height = mNavBar.getHeight();
        if (mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE) {
            height += mAutoLogin.getHeight();
        }
        return height;
    }

    public void updateAutoLogin(Tab tab, boolean animate) {
        if (mAutoLogin == null) {
            if  (tab.getDeviceAccountLogin() == null) {
                return;
            }
            inflateAutoLoginBar();
        }
        mAutoLogin.updateAutoLogin(tab, animate);
    }

    public void showAutoLogin(boolean animate) {
        if (mUseQuickControls) {
            mBaseUi.showTitleBar();
        }
        if (mAutoLogin == null) {
            inflateAutoLoginBar();
        }
        mAutoLogin.setVisibility(View.VISIBLE);
        if (animate) {
            mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
                    getContext(), R.anim.autologin_enter));
        }
    }

    public void hideAutoLogin(boolean animate) {
        if (mUseQuickControls) {
            mBaseUi.hideTitleBar();
            mAutoLogin.setVisibility(View.GONE);
            mBaseUi.refreshWebView();
        } else {
            if (animate) {
                Animation anim = AnimationUtils.loadAnimation(getContext(),
                        R.anim.autologin_exit);
                anim.setAnimationListener(new AnimationListener() {
                    @Override
                    public void onAnimationEnd(Animation a) {
                        mAutoLogin.setVisibility(View.GONE);
                        mBaseUi.refreshWebView();
                    }

                    @Override
                    public void onAnimationStart(Animation a) {
                    }

                    @Override
                    public void onAnimationRepeat(Animation a) {
                    }
                });
                mAutoLogin.startAnimation(anim);
            } else if (mAutoLogin.getAnimation() == null) {
                mAutoLogin.setVisibility(View.GONE);
                mBaseUi.refreshWebView();
            }
        }
    }

    public boolean wantsToBeVisible() {
        return inAutoLogin();
    }

    private boolean inAutoLogin() {
        return mAutoLogin != null && mAutoLogin.getVisibility() == View.VISIBLE;
    }

    public boolean isEditingUrl() {
        return mNavBar.isEditingUrl();
    }

    public WebView getCurrentWebView() {
        Tab t = mBaseUi.getActiveTab();
        if (t != null) {
            return t.getWebView();
        } else {
            return null;
        }
    }

    public PageProgressView getProgressView() {
        return mProgress;
    }

    public NavigationBarBase getNavigationBar() {
        return mNavBar;
    }

    public boolean useQuickControls() {
        return mUseQuickControls;
    }

    public boolean isInLoad() {
        return mInLoad;
    }

    private ViewGroup.LayoutParams makeLayoutParams() {
        return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT);
    }

    @Override
    public View focusSearch(View focused, int dir) {
        WebView web = getCurrentWebView();
        if (FOCUS_DOWN == dir && hasFocus() && web != null
                && web.hasFocusable() && web.getParent() != null) {
            return web;
        }
        return super.focusSearch(focused, dir);
    }

    public void onTabDataChanged(Tab tab) {
        mNavBar.setVisibility(VISIBLE);
    }

    public void onScrollChanged() {
        if (!mShowing && !mIsFixedTitleBar) {
            setTranslationY(getVisibleTitleHeight() - getEmbeddedHeight());
        }
    }

    public void onResume() {
        setFixedTitleBar();
    }

}
