/*
 * 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) {
        Integer groupPosition = (Integer) originalView.getTag(R.id.group_position);
        Integer childPosition = (Integer) originalView.getTag(R.id.child_position);

        if (groupPosition == null || childPosition == null) {
            return false;
        }

        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;
    }

}
