/*
 * 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.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Simple bread crumb view
 * Use setController to receive callbacks from user interactions
 * Use pushView, popView, clear, and getTopData to change/access the view stack
 */
public class BreadCrumbView extends LinearLayout implements OnClickListener {
    private static final int DIVIDER_PADDING = 12; // dips
    private static final int CRUMB_PADDING = 8; // dips

    public interface Controller {
        public void onTop(BreadCrumbView view, int level, Object data);
    }

    private ImageButton mBackButton;
    private Controller mController;
    private List<Crumb> mCrumbs;
    private boolean mUseBackButton;
    private Drawable mSeparatorDrawable;
    private float mDividerPadding;
    private int mMaxVisible = -1;
    private Context mContext;
    private int mCrumbPadding;

    /**
     * @param context
     * @param attrs
     * @param defStyle
     */
    public BreadCrumbView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    /**
     * @param context
     * @param attrs
     */
    public BreadCrumbView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    /**
     * @param context
     */
    public BreadCrumbView(Context context) {
        super(context);
        init(context);
    }

    private void init(Context ctx) {
        mContext = ctx;
        setFocusable(true);
        mUseBackButton = false;
        mCrumbs = new ArrayList<Crumb>();
        TypedArray a = mContext.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
        mSeparatorDrawable = a.getDrawable(com.android.internal.R.styleable.Theme_dividerVertical);
        a.recycle();
        float density = mContext.getResources().getDisplayMetrics().density;
        mDividerPadding = DIVIDER_PADDING * density;
        mCrumbPadding = (int) (CRUMB_PADDING * density);
        addBackButton();
    }

    public void setUseBackButton(boolean useflag) {
        mUseBackButton = useflag;
        updateVisible();
    }

    public void setController(Controller ctl) {
        mController = ctl;
    }

    public int getMaxVisible() {
        return mMaxVisible;
    }

    public void setMaxVisible(int max) {
        mMaxVisible = max;
        updateVisible();
    }

    public int getTopLevel() {
        return mCrumbs.size();
    }

    public Object getTopData() {
        Crumb c = getTopCrumb();
        if (c != null) {
            return c.data;
        }
        return null;
    }

    public int size() {
        return mCrumbs.size();
    }

    public void clear() {
        while (mCrumbs.size() > 1) {
            pop(false);
        }
        pop(true);
    }

    public void notifyController() {
        if (mController != null) {
            if (mCrumbs.size() > 0) {
                mController.onTop(this, mCrumbs.size(), getTopCrumb().data);
            } else {
                mController.onTop(this, 0, null);
            }
        }
    }

    public View pushView(String name, Object data) {
        return pushView(name, true, data);
    }

    public View pushView(String name, boolean canGoBack, Object data) {
        Crumb crumb = new Crumb(name, canGoBack, data);
        pushCrumb(crumb);
        return crumb.crumbView;
    }

    public void pushView(View view, Object data) {
        Crumb crumb = new Crumb(view, true, data);
        pushCrumb(crumb);
    }

    public void popView() {
        pop(true);
    }

    private void addBackButton() {
        mBackButton = new ImageButton(mContext);
        mBackButton.setImageResource(R.drawable.ic_back_hierarchy_holo_dark);
        TypedValue outValue = new TypedValue();
        getContext().getTheme().resolveAttribute(
                android.R.attr.selectableItemBackground, outValue, true);
        int resid = outValue.resourceId;
        mBackButton.setBackgroundResource(resid);
        mBackButton.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT));
        mBackButton.setOnClickListener(this);
        mBackButton.setVisibility(View.GONE);
        mBackButton.setContentDescription(mContext.getText(
                R.string.accessibility_button_bookmarks_folder_up));
        addView(mBackButton, 0);
    }

    private void pushCrumb(Crumb crumb) {
        if (mCrumbs.size() > 0) {
            addSeparator();
        }
        mCrumbs.add(crumb);
        addView(crumb.crumbView);
        updateVisible();
        crumb.crumbView.setOnClickListener(this);
    }

    private void addSeparator() {
        View sep = makeDividerView();
        sep.setLayoutParams(makeDividerLayoutParams());
        addView(sep);
    }

    private ImageView makeDividerView() {
        ImageView result = new ImageView(mContext);
        result.setImageDrawable(mSeparatorDrawable);
        result.setScaleType(ImageView.ScaleType.FIT_XY);
        return result;
    }

    private LayoutParams makeDividerLayoutParams() {
        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        params.topMargin = (int) mDividerPadding;
        params.bottomMargin = (int) mDividerPadding;
        return params;
    }

    private void pop(boolean notify) {
        int n = mCrumbs.size();
        if (n > 0) {
            removeLastView();
            if (!mUseBackButton || (n > 1)) {
                // remove separator
                removeLastView();
            }
            mCrumbs.remove(n - 1);
            if (mUseBackButton) {
                Crumb top = getTopCrumb();
                if (top != null && top.canGoBack) {
                    mBackButton.setVisibility(View.VISIBLE);
                } else {
                    mBackButton.setVisibility(View.GONE);
                }
            }
            updateVisible();
            if (notify) {
                notifyController();
            }
        }
    }

    private void updateVisible() {
        // start at index 1 (0 == back button)
        int childIndex = 1;
        if (mMaxVisible >= 0) {
            int invisibleCrumbs = size() - mMaxVisible;
            if (invisibleCrumbs > 0) {
                int crumbIndex = 0;
                while (crumbIndex < invisibleCrumbs) {
                    // Set the crumb to GONE.
                    getChildAt(childIndex).setVisibility(View.GONE);
                    childIndex++;
                    // Each crumb is followed by a separator (except the last
                    // one).  Also make it GONE
                    if (getChildAt(childIndex) != null) {
                        getChildAt(childIndex).setVisibility(View.GONE);
                    }
                    childIndex++;
                    // Move to the next crumb.
                    crumbIndex++;
                }
            }
            // Make sure the last two are visible.
            int childCount = getChildCount();
            while (childIndex < childCount) {
                getChildAt(childIndex).setVisibility(View.VISIBLE);
                childIndex++;
            }
        } else {
            int count = getChildCount();
            for (int i = childIndex; i < count ; i++) {
                getChildAt(i).setVisibility(View.VISIBLE);
            }
        }
        if (mUseBackButton) {
            boolean canGoBack = getTopCrumb() != null ? getTopCrumb().canGoBack : false;
            mBackButton.setVisibility(canGoBack ? View.VISIBLE : View.GONE);
        } else {
            mBackButton.setVisibility(View.GONE);
        }
    }

    private void removeLastView() {
        int ix = getChildCount();
        if (ix > 0) {
            removeViewAt(ix-1);
        }
    }

    Crumb getTopCrumb() {
        Crumb crumb = null;
        if (mCrumbs.size() > 0) {
            crumb = mCrumbs.get(mCrumbs.size() - 1);
        }
        return crumb;
    }

    @Override
    public void onClick(View v) {
        if (mBackButton == v) {
            popView();
            notifyController();
        } else {
            // pop until view matches crumb view
            while (v != getTopCrumb().crumbView) {
                pop(false);
            }
            notifyController();
        }
    }
    @Override
    public int getBaseline() {
        int ix = getChildCount();
        if (ix > 0) {
            // If there is at least one crumb, the baseline will be its
            // baseline.
            return getChildAt(ix-1).getBaseline();
        }
        return super.getBaseline();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = mSeparatorDrawable.getIntrinsicHeight();
        if (getMeasuredHeight() < height) {
            // This should only be an issue if there are currently no separators
            // showing; i.e. if there is one crumb and no back button.
            int mode = View.MeasureSpec.getMode(heightMeasureSpec);
            switch(mode) {
                case View.MeasureSpec.AT_MOST:
                    if (View.MeasureSpec.getSize(heightMeasureSpec) < height) {
                        return;
                    }
                    break;
                case View.MeasureSpec.EXACTLY:
                    return;
                default:
                    break;
            }
            setMeasuredDimension(getMeasuredWidth(), height);
        }
    }

    class Crumb {

        public View crumbView;
        public boolean canGoBack;
        public Object data;

        public Crumb(String title, boolean backEnabled, Object tag) {
            init(makeCrumbView(title), backEnabled, tag);
        }

        public Crumb(View view, boolean backEnabled, Object tag) {
            init(view, backEnabled, tag);
        }

        private void init(View view, boolean back, Object tag) {
            canGoBack = back;
            crumbView = view;
            data = tag;
        }

        private TextView makeCrumbView(String name) {
            TextView tv = new TextView(mContext);
            tv.setTextAppearance(mContext, android.R.style.TextAppearance_Medium);
            tv.setPadding(mCrumbPadding, 0, mCrumbPadding, 0);
            tv.setGravity(Gravity.CENTER_VERTICAL);
            tv.setText(name);
            tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.MATCH_PARENT));
            tv.setSingleLine();
            tv.setEllipsize(TextUtils.TruncateAt.END);
            return tv;
        }

    }

}
