/*
 * Copyright (C) 2008 Esmertec AG.
 * Copyright (C) 2008 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.im.app;

import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.content.ContentQueryMap;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.net.Uri;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CursorTreeAdapter;
import android.widget.TextView;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;

import com.android.im.IImConnection;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
import com.android.im.provider.Imps;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

public class ContactListTreeAdapter extends BaseExpandableListAdapter
        implements AbsListView.OnScrollListener{

    private static final String[] CONTACT_LIST_PROJECTION = {
            Imps.ContactList._ID,
            Imps.ContactList.NAME,
    };

    private static final int COLUMN_CONTACT_LIST_ID = 0;
    private static final int COLUMN_CONTACT_LIST_NAME = 1;

    Activity mActivity;
    SimpleAlertHandler mHandler;
    private LayoutInflater mInflate;
    private long mProviderId;
    long mAccountId;
    Cursor mOngoingConversations;
    Cursor mSubscriptions;
    boolean mDataValid;
    ListTreeAdapter mAdapter;
    private boolean mHideOfflineContacts;

    final MyContentObserver mContentObserver;
    final MyDataSetObserver mDataSetObserver;

    private ArrayList<Integer> mExpandedGroups;

    private static final int TOKEN_CONTACT_LISTS = -1;
    private static final int TOKEN_ONGOING_CONVERSATION = -2;
    private static final int TOKEN_SUBSCRITPTION = -3;

    private static final String NON_CHAT_AND_BLOCKED_CONTACTS = "("
        + Imps.Contacts.LAST_MESSAGE_DATE + " IS NULL) AND ("
        + Imps.Contacts.TYPE + "!=" + Imps.Contacts.TYPE_BLOCKED + ")";

    private static final String CONTACTS_SELECTION = Imps.Contacts.CONTACTLIST
            + "=? AND " + NON_CHAT_AND_BLOCKED_CONTACTS;

    private static final String ONLINE_CONTACT_SELECTION = CONTACTS_SELECTION
            + " AND "+ Imps.Contacts.PRESENCE_STATUS + " != " + Imps.Presence.OFFLINE;

    static final void log(String msg) {
        Log.d(ImApp.LOG_TAG, "<ContactListAdapter>" + msg);
    }

    static final String[] CONTACT_COUNT_PROJECTION = {
        Imps.Contacts.CONTACTLIST,
        Imps.Contacts._COUNT,
    };

    ContentQueryMap mOnlineContactsCountMap;

    // Async QueryHandler
    private final class QueryHandler extends AsyncQueryHandler {
        public QueryHandler(Context context) {
            super(context.getContentResolver());
        }

        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor c) {
            if(Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
                log("onQueryComplete:token=" + token);
            }

            if (token == TOKEN_CONTACT_LISTS) {
                mDataValid = true;
                mAdapter.setGroupCursor(c);
            } else if (token == TOKEN_ONGOING_CONVERSATION) {
                setOngoingConversations(c);
                notifyDataSetChanged();
            } else if (token == TOKEN_SUBSCRITPTION) {
                setSubscriptions(c);
                notifyDataSetChanged();
            } else {
                int count = mAdapter.getGroupCount();
                for (int pos = 0; pos < count; pos++) {
                    long listId = mAdapter.getGroupId(pos);
                    if (listId == token) {
                        mAdapter.setChildrenCursor(pos, c);
                        break;
                    }
                }
            }
        }
    }
    private QueryHandler mQueryHandler;

    private int mScrollState;

    private boolean mAutoRequery;
    private boolean mRequeryPending;

    public ContactListTreeAdapter(IImConnection conn, Activity activity) {
        mActivity = activity;
        mInflate = activity.getLayoutInflater();
        mHandler = new SimpleAlertHandler(activity);

        mAdapter = new ListTreeAdapter(null);

        mContentObserver = new MyContentObserver();
        mDataSetObserver = new MyDataSetObserver();
        mExpandedGroups = new ArrayList<Integer>();
        mQueryHandler = new QueryHandler(activity);

        changeConnection(conn);
    }

    public void changeConnection(IImConnection conn) {
        mQueryHandler.cancelOperation(TOKEN_ONGOING_CONVERSATION);
        mQueryHandler.cancelOperation(TOKEN_SUBSCRITPTION);
        mQueryHandler.cancelOperation(TOKEN_CONTACT_LISTS);

        synchronized (this) {
            if (mOngoingConversations != null) {
                mOngoingConversations.close();
                mOngoingConversations = null;
            }
            if (mSubscriptions != null) {
                mSubscriptions.close();
                mSubscriptions = null;
            }
            if (mOnlineContactsCountMap != null) {
                mOnlineContactsCountMap.close();
            }
        }

        mAdapter.notifyDataSetChanged();
        if (conn != null) {
            try {
                mProviderId = conn.getProviderId();
                mAccountId = conn.getAccountId();
                startQueryOngoingConversations();
                startQueryContactLists();
                startQuerySubscriptions();
            } catch (RemoteException e) {
                // Service died!
            }
        }
    }

    public void setHideOfflineContacts(boolean hide) {
        if (mHideOfflineContacts != hide) {
            mHideOfflineContacts = hide;
            mAdapter.notifyDataSetChanged();
        }
    }

    public void startAutoRequery() {
        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startAutoRequery()");
        }
        mAutoRequery = true;
        if (mRequeryPending) {
            mRequeryPending = false;
            startQueryOngoingConversations();
        }
    }

    private void startQueryContactLists() {
        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startQueryContactLists()");
        }

        Uri uri = Imps.ContactList.CONTENT_URI;
        uri = ContentUris.withAppendedId(uri, mProviderId);
        uri = ContentUris.withAppendedId(uri, mAccountId);

        mQueryHandler.startQuery(TOKEN_CONTACT_LISTS, null, uri, CONTACT_LIST_PROJECTION,
                null, null, Imps.ContactList.DEFAULT_SORT_ORDER);
    }

    void startQueryOngoingConversations() {
        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startQueryOngoingConversations()");
        }

        Uri uri = Imps.Contacts.CONTENT_URI_CHAT_CONTACTS_BY;
        uri = ContentUris.withAppendedId(uri, mProviderId);
        uri = ContentUris.withAppendedId(uri, mAccountId);

        mQueryHandler.startQuery(TOKEN_ONGOING_CONVERSATION, null, uri,
                ContactView.CONTACT_PROJECTION, null, null, Imps.Contacts.DEFAULT_SORT_ORDER);
    }

    void startQuerySubscriptions() {
        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startQuerySubscriptions()");
        }

        Uri uri = Imps.Contacts.CONTENT_URI_CONTACTS_BY;
        uri = ContentUris.withAppendedId(uri, mProviderId);
        uri = ContentUris.withAppendedId(uri, mAccountId);

        mQueryHandler.startQuery(TOKEN_SUBSCRITPTION, null, uri,
                ContactView.CONTACT_PROJECTION,
                String.format("%s=%d AND %s=%d",
                    Imps.Contacts.SUBSCRIPTION_STATUS, Imps.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING,
                    Imps.Contacts.SUBSCRIPTION_TYPE, Imps.Contacts.SUBSCRIPTION_TYPE_FROM),
                null,Imps.Contacts.DEFAULT_SORT_ORDER);
    }

    void startQueryContacts(long listId) {
        if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
            log("startQueryContacts - listId=" + listId);
        }

        String selection = mHideOfflineContacts ? ONLINE_CONTACT_SELECTION : CONTACTS_SELECTION;
        String[] args = { Long.toString(listId) };
        int token = (int)listId;
        mQueryHandler.startQuery(token, null, Imps.Contacts.CONTENT_URI,
                ContactView.CONTACT_PROJECTION, selection, args, Imps.Contacts.DEFAULT_SORT_ORDER);
    }

    public Object getChild(int groupPosition, int childPosition) {
        if (isPosForOngoingConversation(groupPosition)) {
            // No cursor exists for the "Empty" TextView item
            if (getOngoingConversationCount() == 0) return null;
            return moveTo(getOngoingConversations(), childPosition);
        } else if (isPosForSubscription(groupPosition)) {
            return moveTo(getSubscriptions(), childPosition);
        } else {
            return mAdapter.getChild(getChildAdapterPosition(groupPosition), childPosition);
        }
    }

    public long getChildId(int groupPosition, int childPosition) {
        if (isPosForOngoingConversation(groupPosition)) {
            // No cursor id exists for the "Empty" TextView item
            if (getOngoingConversationCount() == 0) return 0;
            return getId(getOngoingConversations(), childPosition);
        } else if (isPosForSubscription(groupPosition)) {
            return getId(getSubscriptions(), childPosition);
        } else {
            return mAdapter.getChildId(getChildAdapterPosition(groupPosition), childPosition);
        }
    }

    public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
            View convertView, ViewGroup parent) {
        boolean isOngoingConversation = isPosForOngoingConversation(groupPosition);
        boolean displayEmpty = isOngoingConversation && (getOngoingConversationCount() == 0);
        if (isOngoingConversation || isPosForSubscription(groupPosition)) {
            View view = null;
            if (convertView != null) {
                // use the convert view if it matches the type required by displayEmpty
                if (displayEmpty && (convertView instanceof TextView)) {
                    view = convertView;
                    ((TextView) view).setText(mActivity.getText(R.string.empty_conversation_group));
                } else if (!displayEmpty && (convertView instanceof ContactView)) {
                     view = convertView;
                }
            }
            if (view == null) {
                if (displayEmpty) {
                    view = newEmptyView(parent);
                } else {
                    view = newChildView(parent);
                }
            }
            if (!displayEmpty) {
                Cursor cursor = isPosForOngoingConversation(groupPosition)
                        ? getOngoingConversations() : getSubscriptions();
                cursor.moveToPosition(childPosition);
                ((ContactView) view).bind(cursor, null, isScrolling());
            }
            return view;
        } else {
            return mAdapter.getChildView(getChildAdapterPosition(groupPosition), childPosition,
                    isLastChild, convertView, parent);
        }
    }

    public int getChildrenCount(int groupPosition) {
        if (!mDataValid) {
            return 0;
        }
        if (isPosForOngoingConversation(groupPosition)) {
            // if there are no ongoing conversations, we want to display "empty" textview
            int count = getOngoingConversationCount();
            if (count == 0) {
                count = 1;
            }
            return count;
        } else if (isPosForSubscription(groupPosition)) {
            return getSubscriptionCount();
        } else {
            // XXX getChildrenCount() may be called with an invalid groupPosition that is larger
            // than the total number of all groups.
            int position = getChildAdapterPosition(groupPosition);
            if (position >= mAdapter.getGroupCount()) {
                Log.w(ImApp.LOG_TAG, "getChildrenCount out of range");
                return 0;
            }
            return mAdapter.getChildrenCount(position);
        }
    }

    public Object getGroup(int groupPosition) {
        if (isPosForOngoingConversation(groupPosition)
                || isPosForSubscription(groupPosition)) {
            return null;
        } else {
            return mAdapter.getGroup(getChildAdapterPosition(groupPosition));
        }
    }

    public int getGroupCount() {
        if (!mDataValid) {
            return 0;
        }
        int count = mAdapter.getGroupCount();

        // ongoing conversations
        count++;

        if (getSubscriptionCount() > 0) {
            count++;
        }

        return count;
    }

    public long getGroupId(int groupPosition) {
        if (isPosForOngoingConversation(groupPosition) || isPosForSubscription(groupPosition)) {
            return 0;
        } else {
            return mAdapter.getGroupId(getChildAdapterPosition(groupPosition));
        }
    }

    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
            ViewGroup parent) {
        if (isPosForOngoingConversation(groupPosition) || isPosForSubscription(groupPosition)) {
            View v;
            if (convertView != null) {
                v = convertView;
            } else {
                v = newGroupView(parent);
            }

            TextView text1 = (TextView)v.findViewById(R.id.text1);
            TextView text2 = (TextView)v.findViewById(R.id.text2);

            Resources r = v.getResources();
            ImApp app = ImApp.getApplication(mActivity);
            BrandingResources brandingRes = app.getBrandingResource(mProviderId);
            String text = isPosForOngoingConversation(groupPosition) ?
                    brandingRes.getString(
                            BrandingResourceIDs.STRING_ONGOING_CONVERSATION,
                            getOngoingConversationCount()) :
                    r.getString(R.string.subscriptions);
            text1.setText(text);
            text2.setVisibility(View.GONE);
            return v;
        } else {
            return mAdapter.getGroupView(getChildAdapterPosition(groupPosition), isExpanded,
                    convertView, parent);
        }
    }

    public boolean isChildSelectable(int groupPosition, int childPosition) {
        if (isPosForOngoingConversation(groupPosition)) {
            // "Empty" TextView is not selectable
            if (getOngoingConversationCount()==0) return false;
            return true;
        }
        if (isPosForSubscription(groupPosition)) return true;
        return mAdapter.isChildSelectable(getChildAdapterPosition(groupPosition), childPosition);
    }

    public boolean stableIds() {
        return true;
    }

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        mAdapter.registerDataSetObserver(observer);
        super.registerDataSetObserver(observer);
    }

    @Override
    public void unregisterDataSetObserver(DataSetObserver observer) {
        mAdapter.unregisterDataSetObserver(observer);
        super.unregisterDataSetObserver(observer);
    }

    public boolean hasStableIds() {
        return true;
    }

    @Override
    public void onGroupCollapsed(int groupPosition) {
        super.onGroupCollapsed(groupPosition);
        mExpandedGroups.remove(Integer.valueOf(groupPosition));
        int pos = getChildAdapterPosition(groupPosition);
        if (pos >= 0) {
            mAdapter.onGroupCollapsed(pos);
        }
    }

    @Override
    public void onGroupExpanded(int groupPosition) {
        super.onGroupExpanded(groupPosition);
        mExpandedGroups.add(groupPosition);
        int pos = getChildAdapterPosition(groupPosition);
        if (pos >= 0) {
            mAdapter.onGroupExpanded(pos);
        }
    }

    public int[] getExpandedGroups() {
        ArrayList<Integer> expandedGroups = mExpandedGroups;
        int size = expandedGroups.size();
        int[] res = new int[size];
        for (int i = 0; i < size; i++) {
            res[i] = expandedGroups.get(i);
        }
        return res;
    }

    View newChildView(ViewGroup parent) {
        return mInflate.inflate(R.layout.contact_view, parent, false);
    }

    View newEmptyView(ViewGroup parent) {
        return mInflate.inflate(R.layout.empty_conversation_group_view, parent, false);
    }

    View newGroupView(ViewGroup parent) {
        return mInflate.inflate(R.layout.group_view, parent, false);
    }

    private synchronized Cursor getOngoingConversations() {
        if (mOngoingConversations == null) {
            startQueryOngoingConversations();
        }
        return mOngoingConversations;
    }

    synchronized void setOngoingConversations(Cursor c) {
        if (mOngoingConversations != null) {
            mOngoingConversations.unregisterContentObserver(mContentObserver);
            mOngoingConversations.unregisterDataSetObserver(mDataSetObserver);
            mOngoingConversations.close();
        }
        c.registerContentObserver(mContentObserver);
        c.registerDataSetObserver(mDataSetObserver);
        mOngoingConversations = c;
    }

    private int getOngoingConversationCount() {
        Cursor c = getOngoingConversations();
        return c == null ? 0 : c.getCount();
    }

    private synchronized Cursor getSubscriptions() {
        if (mSubscriptions == null) {
            startQuerySubscriptions();
        }
        return mSubscriptions;
    }

    synchronized void setSubscriptions(Cursor c) {
        if (mSubscriptions != null) {
            mSubscriptions.close();
        }
        // we don't need to register observers on mSubscriptions because
        // we already have observers on mOngoingConversations and they
        // will be notified if there is any changes of subscription
        // since the two cursors come from the same table.
        mSubscriptions = c;
    }

    private int getSubscriptionCount() {
        Cursor c = getSubscriptions();
        return c == null ? 0 : c.getCount();
    }

    public boolean isPosForOngoingConversation(int groupPosition) {
        return groupPosition == 0;
    }

    public boolean isPosForSubscription(int groupPosition) {
        return groupPosition == 1 && getSubscriptionCount() > 0;
    }

    private int getChildAdapterPosition(int groupPosition) {
        if (getSubscriptionCount() > 0) {
            return groupPosition - 2;
        } else {
            return groupPosition - 1;
        }
    }

    private Cursor moveTo(Cursor cursor, int position) {
        if (cursor.moveToPosition(position)) {
            return cursor;
        }
        return null;
    }

    private long getId(Cursor cursor, int position) {
        if (cursor.moveToPosition(position)) {
            return cursor.getLong(ContactView.COLUMN_CONTACT_ID);
        }
        return 0;
    }

    class ListTreeAdapter extends CursorTreeAdapter {

        public ListTreeAdapter(Cursor cursor) {
            super(cursor, mActivity);
        }

        @Override
        protected void bindChildView(View view, Context context, Cursor cursor,
                boolean isLastChild) {
            // binding when child is text view for an empty group
            if (view instanceof TextView) {
                ((TextView) view).setText(mActivity.getText(R.string.empty_contact_group));
            } else {
                ((ContactView) view).bind(cursor, null, isScrolling());
            }
        }

        @Override
        protected void bindGroupView(View view, Context context, Cursor cursor,
                boolean isExpanded) {
            TextView text1 = (TextView)view.findViewById(R.id.text1);
            TextView text2 = (TextView)view.findViewById(R.id.text2);
            Resources r = view.getResources();

            text1.setText(cursor.getString(COLUMN_CONTACT_LIST_NAME));
            text2.setVisibility(View.VISIBLE);
            text2.setText(r.getString(R.string.online_count, getOnlineChildCount(cursor)));
        }

        View newEmptyView(ViewGroup parent) {
            return mInflate.inflate(R.layout.empty_contact_group_view, parent, false);
        }

        // if the group is empty, provide a text view. The infrastructure provides a "convertView"
        // as a possible suggestion to reuse an existing view's data. It may be null, it may be a
        // TextView, or it may be a ContactView, so we need to test the possible cases.
        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
                View convertView, ViewGroup parent) {
            // Provide a TextView if the group is empty
            if (super.getChildrenCount(groupPosition)==0) {
                if (convertView != null) {
                    if (convertView instanceof TextView) {
                        ((TextView) convertView).setText(
                                mActivity.getText(R.string.empty_contact_group));
                        return convertView;
                    }
                }
                return newEmptyView(parent);
            }
            if ( !(convertView instanceof ContactView) ) {
                convertView = null;
            }
            return super.getChildView(groupPosition, childPosition, isLastChild, convertView,
                    parent);
        }

        @Override
        protected Cursor getChildrenCursor(Cursor groupCursor) {
            long listId = groupCursor.getLong(COLUMN_CONTACT_LIST_ID);
            startQueryContacts(listId);
            return null;
        }

        // return a TextView for empty groups
        @Override
        protected View newChildView(Context context, Cursor cursor, boolean isLastChild,
                ViewGroup parent) {
            if (cursor.getCount() == 0) {
                return newEmptyView(parent);
            } else {
                return ContactListTreeAdapter.this.newChildView(parent);
            }
        }

        @Override
        protected View newGroupView(Context context, Cursor cursor, boolean isExpanded,
                ViewGroup parent) {
            return ContactListTreeAdapter.this.newGroupView(parent);
        }

        private int getOnlineChildCount(Cursor groupCursor) {
            long listId = groupCursor.getLong(COLUMN_CONTACT_LIST_ID);
            if (mOnlineContactsCountMap == null) {
                String where = Imps.Contacts.ACCOUNT + "=" + mAccountId;
                ContentResolver cr = mActivity.getContentResolver();

                Cursor c = cr.query(Imps.Contacts.CONTENT_URI_ONLINE_COUNT,
                        CONTACT_COUNT_PROJECTION, where, null, null);
                mOnlineContactsCountMap = new ContentQueryMap(c,
                        Imps.Contacts.CONTACTLIST, true, mHandler);
                mOnlineContactsCountMap.addObserver(new Observer(){
                    public void update(Observable observable, Object data) {
                        notifyDataSetChanged();
                    }});
            }
            ContentValues value = mOnlineContactsCountMap.getValues(String.valueOf(listId));
            return  value == null ? 0 : value.getAsInteger(Imps.Contacts._COUNT);
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            int children = super.getChildrenCount(groupPosition);
            if (children == 0) {
                // Count the empty group text item as a child
                return 1;
            }
            return children;
        }

        // Don't allow the empty group text item to be selected
        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return (super.getChildrenCount(groupPosition) > 0);
        }
    }

    private class MyContentObserver extends ContentObserver {

        public MyContentObserver() {
            super(mHandler);
        }

        @Override
        public void onChange(boolean selfChange) {
            if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
                log("MyContentObserver.onChange() autoRequery=" + mAutoRequery);
            }
            // Don't requery when fling. We will schedule a requery when the fling is complete.
            if (isScrolling()) {
                return;
            }
            if (mAutoRequery) {
                startQueryOngoingConversations();
            } else {
                mRequeryPending = true;
            }
        }
    }

    private class MyDataSetObserver extends DataSetObserver {
        public MyDataSetObserver() {
        }

        @Override
        public void onChanged() {
            if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
                log("MyDataSetObserver.onChanged()");
            }

            mDataValid = true;
            notifyDataSetChanged();
        }

        @Override
        public void onInvalidated() {
            if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
                log("MyDataSetObserver.onInvalidated()");
            }

            mDataValid = false;
            notifyDataSetInvalidated();
        }
    }

    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
            int totalItemCount) {
        // no op
    }

    public void onScrollStateChanged(AbsListView view, int scrollState) {
        int oldState = mScrollState;

        mScrollState = scrollState;
        //  If we just finished a fling then some items may not have an icon
        //  So force a full redraw now that the fling is complete
        if (oldState == OnScrollListener.SCROLL_STATE_FLING) {
            notifyDataSetChanged();
        }
    }

    public boolean isScrolling() {
        return mScrollState == OnScrollListener.SCROLL_STATE_FLING;
    }
}
