/*
 * 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.calendar.selectcalendars;

import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.app.FragmentManager;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.graphics.Rect;
import android.net.Uri;
import android.provider.CalendarContract.Calendars;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.TouchDelegate;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CursorTreeAdapter;
import android.widget.TextView;

import com.android.calendar.CalendarColorPickerDialog;
import com.android.calendar.R;
import com.android.calendar.Utils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class SelectSyncedCalendarsMultiAccountAdapter extends CursorTreeAdapter implements
        View.OnClickListener {

    private static final String TAG = "Calendar";
    private static final String COLOR_PICKER_DIALOG_TAG = "ColorPickerDialog";

    private static final String IS_PRIMARY = "\"primary\"";
    private static final String CALENDARS_ORDERBY = IS_PRIMARY + " DESC,"
            + Calendars.CALENDAR_DISPLAY_NAME + " COLLATE NOCASE";
    private static final String ACCOUNT_SELECTION = Calendars.ACCOUNT_NAME + "=?"
            + " AND " + Calendars.ACCOUNT_TYPE + "=?";

    private final LayoutInflater mInflater;
    private final ContentResolver mResolver;
    private final SelectSyncedCalendarsMultiAccountActivity mActivity;
    private final FragmentManager mFragmentManager;
    private final boolean mIsTablet;
    private CalendarColorPickerDialog mColorPickerDialog;
    private final View mView;
    private final static Runnable mStopRefreshing = new Runnable() {
        @Override
        public void run() {
            mRefresh = false;
        }
    };
    private Map<String, AuthenticatorDescription> mTypeToAuthDescription
        = new HashMap<String, AuthenticatorDescription>();
    protected AuthenticatorDescription[] mAuthDescs;

    // These track changes to the synced state of calendars
    private Map<Long, Boolean> mCalendarChanges
        = new HashMap<Long, Boolean>();
    private Map<Long, Boolean> mCalendarInitialStates
        = new HashMap<Long, Boolean>();

    // Flag for when the cursors have all been closed to ensure no race condition with queries.
    private boolean mClosedCursorsFlag;

    // This is for keeping MatrixCursor copies so that we can requery in the background.
    private Map<String, Cursor> mChildrenCursors
        = new HashMap<String, Cursor>();

    private AsyncCalendarsUpdater mCalendarsUpdater;
    // This is to keep our update tokens separate from other tokens. Since we cancel old updates
    // when a new update comes in, we'd like to leave a token space that won't be canceled.
    private static final int MIN_UPDATE_TOKEN = 1000;
    private static int mUpdateToken = MIN_UPDATE_TOKEN;
    // How long to wait between requeries of the calendars to see if anything has changed.
    private static final int REFRESH_DELAY = 5000;
    // How long to keep refreshing for
    private static final int REFRESH_DURATION = 60000;
    private static boolean mRefresh = true;

    private static String mSyncedText;
    private static String mNotSyncedText;

    // This is to keep track of whether or not multiple calendars have the same display name
    private static HashMap<String, Boolean> mIsDuplicateName = new HashMap<String, Boolean>();

    private int mColorViewTouchAreaIncrease;

    private static final String[] PROJECTION = new String[] {
      Calendars._ID,
      Calendars.ACCOUNT_NAME,
      Calendars.OWNER_ACCOUNT,
      Calendars.CALENDAR_DISPLAY_NAME,
      Calendars.CALENDAR_COLOR,
      Calendars.VISIBLE,
      Calendars.SYNC_EVENTS,
      "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + IS_PRIMARY,
    };
    //Keep these in sync with the projection
    private static final int ID_COLUMN = 0;
    private static final int ACCOUNT_COLUMN = 1;
    private static final int OWNER_COLUMN = 2;
    private static final int NAME_COLUMN = 3;
    private static final int COLOR_COLUMN = 4;
    private static final int SELECTED_COLUMN = 5;
    private static final int SYNCED_COLUMN = 6;
    private static final int PRIMARY_COLUMN = 7;

    private static final int TAG_ID_CALENDAR_ID = R.id.calendar;
    private static final int TAG_ID_SYNC_CHECKBOX = R.id.sync;

    private class AsyncCalendarsUpdater extends AsyncQueryHandler {

        public AsyncCalendarsUpdater(ContentResolver cr) {
            super(cr);
        }

        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
            if(cursor == null) {
                return;
            }
            synchronized(mChildrenCursors) {
                if (mClosedCursorsFlag || (mActivity != null && mActivity.isFinishing())) {
                    cursor.close();
                    return;
                }
            }

            Cursor currentCursor = mChildrenCursors.get(cookie);
            // Check if the new cursor has the same content as our old cursor
            if (currentCursor != null) {
                if (Utils.compareCursors(currentCursor, cursor)) {
                    cursor.close();
                    return;
                }
            }
            // If not then make a new matrix cursor for our Map
            MatrixCursor newCursor = Utils.matrixCursorFromCursor(cursor);
            cursor.close();
            // And update our list of duplicated names
            Utils.checkForDuplicateNames(mIsDuplicateName, newCursor, NAME_COLUMN);

            mChildrenCursors.put((String)cookie, newCursor);
            try {
                setChildrenCursor(token, newCursor);
            } catch (NullPointerException e) {
                Log.w(TAG, "Adapter expired, try again on the next query: " + e);
            }
            // Clean up our old cursor if we had one. We have to do this after setting the new
            // cursor so that our view doesn't throw on an invalid cursor.
            if (currentCursor != null) {
                currentCursor.close();
            }
        }
    }

    /**
     * Method for changing the sync state when a calendar's button is pressed.
     *
     * This gets called when the CheckBox for a calendar is clicked. It toggles
     * the sync state for the associated calendar and saves a change of state to
     * a hashmap. It also compares against the original value and removes any
     * changes from the hashmap if this is back at its initial state.
     */
    @Override
    public void onClick(View v) {
        long id = (Long) v.getTag(TAG_ID_CALENDAR_ID);
        boolean newState;
        boolean initialState = mCalendarInitialStates.get(id);
        if (mCalendarChanges.containsKey(id)) {
            // Negate to reflect the click
            newState = !mCalendarChanges.get(id);
        } else {
            // Negate to reflect the click
            newState = !initialState;
        }

        if (newState == initialState) {
            mCalendarChanges.remove(id);
        } else {
            mCalendarChanges.put(id, newState);
        }

        ((CheckBox) v.getTag(TAG_ID_SYNC_CHECKBOX)).setChecked(newState);
        setText(v, R.id.status, newState ? mSyncedText : mNotSyncedText);
    }

    public SelectSyncedCalendarsMultiAccountAdapter(Context context, Cursor acctsCursor,
            SelectSyncedCalendarsMultiAccountActivity act) {
        super(acctsCursor, context);
        mSyncedText = context.getString(R.string.synced);
        mNotSyncedText = context.getString(R.string.not_synced);

        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mResolver = context.getContentResolver();
        mActivity = act;
        mFragmentManager = act.getFragmentManager();
        mColorPickerDialog = (CalendarColorPickerDialog)
                mFragmentManager.findFragmentByTag(COLOR_PICKER_DIALOG_TAG);
        mIsTablet = Utils.getConfigBool(context, R.bool.tablet_config);

        if (mCalendarsUpdater == null) {
            mCalendarsUpdater = new AsyncCalendarsUpdater(mResolver);
        }

        if (acctsCursor == null || acctsCursor.getCount() == 0) {
            Log.i(TAG, "SelectCalendarsAdapter: No accounts were returned!");
        }
        // Collect proper description for account types
        mAuthDescs = AccountManager.get(context).getAuthenticatorTypes();
        for (int i = 0; i < mAuthDescs.length; i++) {
            mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
        }
        mView = mActivity.getExpandableListView();
        mRefresh = true;
        mClosedCursorsFlag = false;

        mColorViewTouchAreaIncrease = context.getResources()
                .getDimensionPixelSize(R.dimen.color_view_touch_area_increase);
    }

    public void startRefreshStopDelay() {
        mRefresh = true;
        mView.postDelayed(mStopRefreshing, REFRESH_DURATION);
    }

    public void cancelRefreshStopDelay() {
        mView.removeCallbacks(mStopRefreshing);
    }

    /*
     * Write back the changes that have been made. The sync code will pick up any changes and
     * do updates on its own.
     */
    public void doSaveAction() {
        // Cancel the previous operation
        mCalendarsUpdater.cancelOperation(mUpdateToken);
        mUpdateToken++;
        // This is to allow us to do queries and updates with the same AsyncQueryHandler without
        // accidently canceling queries.
        if(mUpdateToken < MIN_UPDATE_TOKEN) {
            mUpdateToken = MIN_UPDATE_TOKEN;
        }

        Iterator<Long> changeKeys = mCalendarChanges.keySet().iterator();
        while (changeKeys.hasNext()) {
            long id = changeKeys.next();
            boolean newSynced = mCalendarChanges.get(id);

            Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, id);
            ContentValues values = new ContentValues();
            values.put(Calendars.VISIBLE, newSynced ? 1 : 0);
            values.put(Calendars.SYNC_EVENTS, newSynced ? 1 : 0);
            mCalendarsUpdater.startUpdate(mUpdateToken, id, uri, values, null, null);
        }
    }

    private static void setText(View view, int id, String text) {
        if (TextUtils.isEmpty(text)) {
            return;
        }
        TextView textView = (TextView) view.findViewById(id);
        textView.setText(text);
    }

    /**
     * Gets the label associated with a particular account type. If none found, return null.
     * @param accountType the type of account
     * @return a CharSequence for the label or null if one cannot be found.
     */
    protected CharSequence getLabelForType(final String accountType) {
        CharSequence label = null;
        if (mTypeToAuthDescription.containsKey(accountType)) {
             try {
                 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
                 Context authContext = mActivity.createPackageContext(desc.packageName, 0);
                 label = authContext.getResources().getText(desc.labelId);
             } catch (PackageManager.NameNotFoundException e) {
                 Log.w(TAG, "No label for account type " + ", type " + accountType);
             }
        }
        return label;
    }

    @Override
    protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {
        final long id = cursor.getLong(ID_COLUMN);
        String name = cursor.getString(NAME_COLUMN);
        String owner = cursor.getString(OWNER_COLUMN);
        int color = Utils.getDisplayColorFromColor(cursor.getInt(COLOR_COLUMN));

        final View colorSquare = view.findViewById(R.id.color);
        colorSquare.setBackgroundColor(color);
        final View delegateParent = (View) colorSquare.getParent();
        delegateParent.post(new Runnable() {

            @Override
            public void run() {
                final Rect r = new Rect();
                colorSquare.getHitRect(r);
                r.top -= mColorViewTouchAreaIncrease;
                r.bottom += mColorViewTouchAreaIncrease;
                r.left -= mColorViewTouchAreaIncrease;
                r.right += mColorViewTouchAreaIncrease;
                delegateParent.setTouchDelegate(new TouchDelegate(r, colorSquare));
            }
        });
        colorSquare.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (mColorPickerDialog == null) {
                    mColorPickerDialog = CalendarColorPickerDialog.newInstance(id, mIsTablet);
                } else {
                    mColorPickerDialog.setCalendarId(id);
                }
                mFragmentManager.executePendingTransactions();
                if (!mColorPickerDialog.isAdded()) {
                    mColorPickerDialog.show(mFragmentManager, COLOR_PICKER_DIALOG_TAG);
                }
            }
        });
        if (mIsDuplicateName.containsKey(name) && mIsDuplicateName.get(name) &&
                !name.equalsIgnoreCase(owner)) {
            name = new StringBuilder(name)
                    .append(Utils.OPEN_EMAIL_MARKER)
                    .append(owner)
                    .append(Utils.CLOSE_EMAIL_MARKER)
                    .toString();
        }
        setText(view, R.id.calendar, name);

        // First see if the user has already changed the state of this calendar
        Boolean sync = mCalendarChanges.get(id);
        if (sync == null) {
            sync = cursor.getInt(SYNCED_COLUMN) == 1;
            mCalendarInitialStates.put(id, sync);
        }

        CheckBox button = (CheckBox) view.findViewById(R.id.sync);
        button.setChecked(sync);
        setText(view, R.id.status, sync ? mSyncedText : mNotSyncedText);

        view.setTag(TAG_ID_CALENDAR_ID, id);
        view.setTag(TAG_ID_SYNC_CHECKBOX, button);
        view.setOnClickListener(this);
    }

    @Override
    protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) {
        int accountColumn = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME);
        int accountTypeColumn = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE);
        String account = cursor.getString(accountColumn);
        String accountType = cursor.getString(accountTypeColumn);
        CharSequence accountLabel = getLabelForType(accountType);
        setText(view, R.id.account, account);
        if (accountLabel != null) {
            setText(view, R.id.account_type, accountLabel.toString());
        }
    }

    @Override
    protected Cursor getChildrenCursor(Cursor groupCursor) {
        int accountColumn = groupCursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME);
        int accountTypeColumn = groupCursor.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE);
        String account = groupCursor.getString(accountColumn);
        String accountType = groupCursor.getString(accountTypeColumn);
        //Get all the calendars for just this account.
        Cursor childCursor = mChildrenCursors.get(accountType + "#" + account);
        new RefreshCalendars(groupCursor.getPosition(), account, accountType).run();
        return childCursor;
    }

    @Override
    protected View newChildView(Context context, Cursor cursor, boolean isLastChild,
            ViewGroup parent) {
        return mInflater.inflate(R.layout.calendar_sync_item, parent, false);
    }

    @Override
    protected View newGroupView(Context context, Cursor cursor, boolean isExpanded,
            ViewGroup parent) {
        return mInflater.inflate(R.layout.account_item, parent, false);
    }

    public void closeChildrenCursors() {
        synchronized (mChildrenCursors) {
            for (String key : mChildrenCursors.keySet()) {
                Cursor cursor = mChildrenCursors.get(key);
                if (!cursor.isClosed()) {
                    cursor.close();
                }
            }
            mChildrenCursors.clear();
            mClosedCursorsFlag = true;
        }
    }

    private class RefreshCalendars implements Runnable {

        int mToken;
        String mAccount;
        String mAccountType;

        public RefreshCalendars(int token, String account, String accountType) {
            mToken = token;
            mAccount = account;
            mAccountType = accountType;
        }

        @Override
        public void run() {
            mCalendarsUpdater.cancelOperation(mToken);
            // Set up a refresh for some point in the future if we haven't stopped updates yet
            if(mRefresh) {
                mView.postDelayed(new RefreshCalendars(mToken, mAccount, mAccountType),
                        REFRESH_DELAY);
            }
            mCalendarsUpdater.startQuery(mToken,
                    mAccountType + "#" + mAccount,
                    Calendars.CONTENT_URI, PROJECTION,
                    ACCOUNT_SELECTION,
                    new String[] { mAccount, mAccountType } /*selectionArgs*/,
                    CALENDARS_ORDERBY);
        }
    }
}
