/*
 * 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.browser.view;

import android.content.Context;
import android.database.DataSetObserver;
import android.provider.BrowserContract;
import android.util.AttributeSet;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.browser.BreadCrumbView;
import com.android.browser.BrowserBookmarksAdapter;
import com.android.browser.R;
import com.android.internal.view.menu.MenuBuilder;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;

public class BookmarkExpandableView extends ExpandableListView
        implements BreadCrumbView.Controller {

    public static final String LOCAL_ACCOUNT_NAME = "local";

    private BookmarkAccountAdapter mAdapter;
    private int mColumnWidth;
    private Context mContext;
    private OnChildClickListener mOnChildClickListener;
    private ContextMenuInfo mContextMenuInfo = null;
    private OnCreateContextMenuListener mOnCreateContextMenuListener;
    private boolean mLongClickable;
    private BreadCrumbView.Controller mBreadcrumbController;
    private int mMaxColumnCount;

    public BookmarkExpandableView(Context context) {
        super(context);
        init(context);
    }

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

    public BookmarkExpandableView(
            Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    void init(Context context) {
        mContext = context;
        setItemsCanFocus(true);
        setLongClickable(false);
        mMaxColumnCount = mContext.getResources()
                .getInteger(R.integer.max_bookmark_columns);
        setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY);
        mAdapter = new BookmarkAccountAdapter(mContext);
        super.setAdapter(mAdapter);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        if (width > 0) {
            mAdapter.measureChildren(width);
            setPadding(mAdapter.mRowPadding, 0, mAdapter.mRowPadding, 0);
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, widthMode);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (width != getMeasuredWidth()) {
            mAdapter.measureChildren(getMeasuredWidth());
        }
    }

    @Override
    public void setAdapter(ExpandableListAdapter adapter) {
        throw new RuntimeException("Not supported");
    }

    public void setColumnWidthFromLayout(int layout) {
        LayoutInflater infalter = LayoutInflater.from(mContext);
        View v = infalter.inflate(layout, this, false);
        v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        mColumnWidth = v.getMeasuredWidth();
    }

    public void clearAccounts() {
        mAdapter.clear();
    }

    public void addAccount(String accountName, BrowserBookmarksAdapter adapter,
            boolean expandGroup) {
        // First, check if it already exists
        int indexOf = mAdapter.mGroups.indexOf(accountName);
        if (indexOf >= 0) {
            BrowserBookmarksAdapter existing = mAdapter.mChildren.get(indexOf);
            if (existing != adapter) {
                existing.unregisterDataSetObserver(mAdapter.mObserver);
                // Replace the existing one
                mAdapter.mChildren.remove(indexOf);
                mAdapter.mChildren.add(indexOf, adapter);
                adapter.registerDataSetObserver(mAdapter.mObserver);
            }
        } else {
            mAdapter.mGroups.add(accountName);
            mAdapter.mChildren.add(adapter);
            adapter.registerDataSetObserver(mAdapter.mObserver);
        }
        mAdapter.notifyDataSetChanged();
        if (expandGroup) {
            expandGroup(mAdapter.getGroupCount() - 1);
        }
    }

    @Override
    public void setOnChildClickListener(OnChildClickListener onChildClickListener) {
        mOnChildClickListener = onChildClickListener;
    }

    @Override
    public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
        mOnCreateContextMenuListener = l;
        if (!mLongClickable) {
            mLongClickable = true;
            if (mAdapter != null) {
                mAdapter.notifyDataSetChanged();
            }
        }
    }

    @Override
    public void createContextMenu(ContextMenu menu) {
        // The below is copied from View - we want to bypass the override
        // in AbsListView

        ContextMenuInfo menuInfo = getContextMenuInfo();

        // Sets the current menu info so all items added to menu will have
        // my extra info set.
        ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo);

        onCreateContextMenu(menu);
        if (mOnCreateContextMenuListener != null) {
            mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo);
        }

        // Clear the extra information so subsequent items that aren't mine don't
        // have my extra info.
        ((MenuBuilder)menu).setCurrentMenuInfo(null);

        if (mParent != null) {
            mParent.createContextMenu(menu);
        }
    }

    @Override
    public boolean showContextMenuForChild(View originalView) {
        int groupPosition = (Integer) originalView.getTag(R.id.group_position);
        int childPosition = (Integer) originalView.getTag(R.id.child_position);

        mContextMenuInfo = new BookmarkContextMenuInfo(childPosition,
                groupPosition);
        if (getParent() != null) {
            getParent().showContextMenuForChild(this);
        }

        return true;
    }

    @Override
    public void onTop(BreadCrumbView view, int level, Object data) {
        if (mBreadcrumbController != null) {
            mBreadcrumbController.onTop(view, level, data);
        }
    }

    public void setBreadcrumbController(BreadCrumbView.Controller controller) {
        mBreadcrumbController = controller;
    }

    @Override
    protected ContextMenuInfo getContextMenuInfo() {
        return mContextMenuInfo;
    }

    public BrowserBookmarksAdapter getChildAdapter(int groupPosition) {
        return mAdapter.mChildren.get(groupPosition);
    }

    private OnClickListener mChildClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (v.getVisibility() != View.VISIBLE) {
                return;
            }
            int groupPosition = (Integer) v.getTag(R.id.group_position);
            int childPosition = (Integer) v.getTag(R.id.child_position);
            if (mAdapter.getGroupCount() <= groupPosition
                    || mAdapter.mChildren.get(groupPosition).getCount() <= childPosition) {
                return;
            }
            long id = mAdapter.mChildren.get(groupPosition).getItemId(childPosition);
            if (mOnChildClickListener != null) {
                mOnChildClickListener.onChildClick(BookmarkExpandableView.this,
                        v, groupPosition, childPosition, id);
            }
        }
    };

    private OnClickListener mGroupOnClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            int groupPosition = (Integer) v.getTag(R.id.group_position);
            if (isGroupExpanded(groupPosition)) {
                collapseGroup(groupPosition);
            } else {
                expandGroup(groupPosition, true);
            }
        }
    };

    public BreadCrumbView getBreadCrumbs(int groupPosition) {
        return mAdapter.getBreadCrumbView(groupPosition);
    }

    public JSONObject saveGroupState() throws JSONException {
        JSONObject obj = new JSONObject();
        int count = mAdapter.getGroupCount();
        for (int i = 0; i < count; i++) {
            String acctName = mAdapter.mGroups.get(i);
            if (!isGroupExpanded(i)) {
                obj.put(acctName != null ? acctName : LOCAL_ACCOUNT_NAME, false);
            }
        }
        return obj;
    }

    class BookmarkAccountAdapter extends BaseExpandableListAdapter {
        ArrayList<BrowserBookmarksAdapter> mChildren;
        ArrayList<String> mGroups;
        HashMap<Integer, BreadCrumbView> mBreadcrumbs =
                new HashMap<Integer, BreadCrumbView>();
        LayoutInflater mInflater;
        int mRowCount = 1; // assume at least 1 child fits in a row
        int mLastViewWidth = -1;
        int mRowPadding = -1;
        DataSetObserver mObserver = new DataSetObserver() {
            @Override
            public void onChanged() {
                notifyDataSetChanged();
            }

            @Override
            public void onInvalidated() {
                notifyDataSetInvalidated();
            }
        };

        public BookmarkAccountAdapter(Context context) {
            mContext = context;
            mInflater = LayoutInflater.from(mContext);
            mChildren = new ArrayList<BrowserBookmarksAdapter>();
            mGroups = new ArrayList<String>();
        }

        public void clear() {
            mGroups.clear();
            mChildren.clear();
            notifyDataSetChanged();
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return mChildren.get(groupPosition).getItem(childPosition);
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition,
                boolean isLastChild, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.bookmark_grid_row, parent, false);
            }
            BrowserBookmarksAdapter childAdapter = mChildren.get(groupPosition);
            int rowCount = mRowCount;
            LinearLayout row = (LinearLayout) convertView;
            if (row.getChildCount() > rowCount) {
                row.removeViews(rowCount, row.getChildCount() - rowCount);
            }
            for (int i = 0; i < rowCount; i++) {
                View cv = null;
                if (row.getChildCount() > i) {
                    cv = row.getChildAt(i);
                }
                int realChildPosition = (childPosition * rowCount) + i;
                if (realChildPosition < childAdapter.getCount()) {
                    View v = childAdapter.getView(realChildPosition, cv, row);
                    v.setTag(R.id.group_position, groupPosition);
                    v.setTag(R.id.child_position, realChildPosition);
                    v.setOnClickListener(mChildClickListener);
                    v.setLongClickable(mLongClickable);
                    if (cv == null) {
                        row.addView(v);
                    } else if (cv != v) {
                        row.removeViewAt(i);
                        row.addView(v, i);
                    } else {
                        cv.setVisibility(View.VISIBLE);
                    }
                } else if (cv != null) {
                    cv.setVisibility(View.GONE);
                }
            }
            return row;
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            BrowserBookmarksAdapter adapter = mChildren.get(groupPosition);
            return (int) Math.ceil(adapter.getCount() / (float)mRowCount);
        }

        @Override
        public Object getGroup(int groupPosition) {
            return mChildren.get(groupPosition);
        }

        @Override
        public int getGroupCount() {
            return mGroups.size();
        }

        public void measureChildren(int viewWidth) {
            if (mLastViewWidth == viewWidth) return;

            int rowCount = viewWidth / mColumnWidth;
            if (mMaxColumnCount > 0) {
                rowCount = Math.min(rowCount, mMaxColumnCount);
            }
            int rowPadding = (viewWidth - (rowCount * mColumnWidth)) / 2;
            boolean notify = rowCount != mRowCount || rowPadding != mRowPadding;
            mRowCount = rowCount;
            mRowPadding = rowPadding;
            mLastViewWidth = viewWidth;
            if (notify) {
                notifyDataSetChanged();
            }
        }

        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded,
                View view, ViewGroup parent) {
            if (view == null) {
                view = mInflater.inflate(R.layout.bookmark_group_view, parent, false);
                view.setOnClickListener(mGroupOnClickListener);
            }
            view.setTag(R.id.group_position, groupPosition);
            FrameLayout crumbHolder = (FrameLayout) view.findViewById(R.id.crumb_holder);
            crumbHolder.removeAllViews();
            BreadCrumbView crumbs = getBreadCrumbView(groupPosition);
            if (crumbs.getParent() != null) {
                ((ViewGroup)crumbs.getParent()).removeView(crumbs);
            }
            crumbHolder.addView(crumbs);
            TextView name = (TextView) view.findViewById(R.id.group_name);
            String groupName = mGroups.get(groupPosition);
            if (groupName == null) {
                groupName = mContext.getString(R.string.local_bookmarks);
            }
            name.setText(groupName);
            return view;
        }

        public BreadCrumbView getBreadCrumbView(int groupPosition) {
            BreadCrumbView crumbs = mBreadcrumbs.get(groupPosition);
            if (crumbs == null) {
                crumbs = (BreadCrumbView)
                        mInflater.inflate(R.layout.bookmarks_header, null);
                crumbs.setController(BookmarkExpandableView.this);
                crumbs.setUseBackButton(true);
                crumbs.setMaxVisible(2);
                String bookmarks = mContext.getString(R.string.bookmarks);
                crumbs.pushView(bookmarks, false,
                        BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER);
                crumbs.setTag(R.id.group_position, groupPosition);
                crumbs.setVisibility(View.GONE);
                mBreadcrumbs.put(groupPosition, crumbs);
            }
            return crumbs;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }
    }

    public static class BookmarkContextMenuInfo implements ContextMenuInfo {

        private BookmarkContextMenuInfo(int childPosition, int groupPosition) {
            this.childPosition = childPosition;
            this.groupPosition = groupPosition;
        }

        public int childPosition;
        public int groupPosition;
    }

}
