/*
 * Copyright (C) 2007 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;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Calendar.Calendars;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.MenuItem.OnMenuItemClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;


public class SelectCalendarsActivity extends Activity implements ListView.OnItemClickListener {

    private static final String TAG = "Calendar";
    private View mView = null;
    private Cursor mCursor = null;
    private QueryHandler mQueryHandler;
    private SelectCalendarsAdapter mAdapter;
    private static final String[] PROJECTION = new String[] {
        Calendars._ID,
        Calendars.DISPLAY_NAME,
        Calendars.COLOR,
        Calendars.SELECTED,
        Calendars.SYNC_EVENTS
    };

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.calendars_activity);
        getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
                Window.PROGRESS_INDETERMINATE_ON);
        mQueryHandler = new QueryHandler(getContentResolver());
        mView = findViewById(R.id.calendars);
        ListView items = (ListView) mView.findViewById(R.id.items);
        Context context = mView.getContext();
        mCursor = managedQuery(Calendars.CONTENT_URI, PROJECTION,
                Calendars.SYNC_EVENTS + "=1",
                null /* selectionArgs */,
                Calendars.DEFAULT_SORT_ORDER);
                                     
        mAdapter = new SelectCalendarsAdapter(context, mCursor);
        items.setAdapter(mAdapter);
        items.setOnItemClickListener(this);
        
        // Start a background sync to get the list of calendars from the server.
        startCalendarSync();
    }
    
    @Override
    public void onPause() {
        super.onPause();
    }
    
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        CheckBox box = (CheckBox) view.findViewById(R.id.checkbox);
        box.toggle();
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuItem item;
        item = menu.add(0, 0, 0, R.string.add_calendars)
                .setOnMenuItemClickListener(new ChangeCalendarAction(false /* not remove */));
        item.setIcon(android.R.drawable.ic_menu_add);
        
        item = menu.add(0, 0, 0, R.string.remove_calendars)
                .setOnMenuItemClickListener(new ChangeCalendarAction(true /* remove */));
        item.setIcon(android.R.drawable.ic_menu_delete);
        return true;
    }

    /**
     * ChangeCalendarAction is used both for adding and removing calendars.
     * The constructor takes a boolean argument that is false if adding
     * calendars and true if removing calendars.  The user selects calendars
     * to be added or removed from a pop-up list. 
     */
    public class ChangeCalendarAction implements OnMenuItemClickListener,
            DialogInterface.OnClickListener, DialogInterface.OnMultiChoiceClickListener {
        
        int mNumItems;
        long[] mCalendarIds;
        boolean[] mIsChecked;
        ContentResolver mContentResolver;
        boolean mRemove;
        private int mCheckedCount;
        private Button mOkButtonInAddDeleteCalendar;
        
        public ChangeCalendarAction(boolean remove) {
            mContentResolver = SelectCalendarsActivity.this.getContentResolver();
            mRemove = remove;
        }

        /*
         * This is called when the user selects a calendar from either the
         * "Add calendars" or "Remove calendars" popup dialog. 
         */
        public void onClick(DialogInterface dialog, int position, boolean isChecked) {
            mIsChecked[position] = isChecked;
            if (isChecked) {
                mCheckedCount++;
            } else {
                mCheckedCount--;
            }

            mOkButtonInAddDeleteCalendar.setEnabled(mCheckedCount > 0);
        }

        /*
         * This is called when the user presses the OK or Cancel button on the
         * "Add calendars" or "Remove calendars" popup dialog. 
         */
        public void onClick(DialogInterface dialog, int which) {
            // If the user cancelled the dialog, then do nothing.
            if (which == DialogInterface.BUTTON_NEGATIVE) {
                return;
            }
            
            boolean changesFound = false;
            for (int position = 0; position < mNumItems; position++) {
                // If this calendar wasn't selected, then skip it.
                if (!mIsChecked[position]) {
                    continue;
                }
                changesFound = true;
                
                long id = mCalendarIds[position];
                Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, id);
                ContentValues values = new ContentValues();
                int selected = 1;
                if (mRemove) {
                    selected = 0;
                }
                values.put(Calendars.SELECTED, selected);
                values.put(Calendars.SYNC_EVENTS, selected);
                mContentResolver.update(uri, values, null, null);
            }
            
            // If there were any changes, then update the list of calendars
            // that are synced.
            if (changesFound) {
                mCursor.requery();
            }
        }
        
        public boolean onMenuItemClick(MenuItem item) {
            AlertDialog.Builder builder = new AlertDialog.Builder(SelectCalendarsActivity.this);
            String selection;
            if (mRemove) {
                builder.setTitle(R.string.remove_calendars)
                    .setIcon(android.R.drawable.ic_dialog_alert);
                selection = Calendars.SYNC_EVENTS + "=1";
            } else {
                builder.setTitle(R.string.add_calendars);
                selection = Calendars.SYNC_EVENTS + "=0";
            }
            ContentResolver cr = getContentResolver();
            // TODO this can cause ANRs http://b/1736511
            Cursor cursor = cr.query(Calendars.CONTENT_URI, PROJECTION,
                    selection, null /* selectionArgs */,
                    Calendars.DEFAULT_SORT_ORDER);
            if (cursor == null) {
                Log.w(TAG, "Cannot get cursor for calendars");
                return true;
            }

            int count = cursor.getCount();
            mNumItems = count;
            CharSequence[] calendarNames = new CharSequence[count];
            mCalendarIds = new long[count];
            mIsChecked = new boolean[count];
            mCheckedCount = 0;
            try {
                int pos = 0;
                while (cursor.moveToNext()) {
                    mCalendarIds[pos] = cursor.getLong(0);
                    calendarNames[pos] = cursor.getString(1);
                    pos += 1;
                }
            } finally {
                cursor.close();
            }
            
            AlertDialog dialog = builder.setMultiChoiceItems(calendarNames, null, this)
                .setPositiveButton(android.R.string.ok, this)
                .setNegativeButton(android.R.string.cancel, this).create();
            dialog.show();
            mOkButtonInAddDeleteCalendar = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
            mOkButtonInAddDeleteCalendar.setEnabled(false);

            return true;
        }
    }
    
    private class QueryHandler extends AsyncQueryHandler {
        public QueryHandler(ContentResolver cr) {
            super(cr);
        }

        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
            getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
                    Window.PROGRESS_VISIBILITY_OFF);

            // If the Activity is finishing, then close the cursor.
            // Otherwise, use the new cursor in the adapter.
            if (isFinishing()) {
                stopManagingCursor(cursor);
                cursor.close();
            } else {
                if (cursor.getCount() == 0) {
                    // There are no calendars.  This might happen if we lost
                    // the wireless connection (in airplane mode, for example).
                    // Leave the current list of calendars alone and pop up
                    // a dialog explaining that the connection is down.
                    // But allow the user to add and remove calendars.
                    return;
                }
                if (mCursor != null) {
                    stopManagingCursor(mCursor);
                }
                mCursor = cursor;
                startManagingCursor(cursor);
                mAdapter.changeCursor(cursor);
            }
        }
    }

    // This class implements the menu option "Refresh list from server".
    // (No longer used.)
    public class RefreshAction implements Runnable {
        public void run() {
            startCalendarSync();
        }
    }
    
    // startCalendarSync() checks the server for an updated list of Calendars
    // (in the background) using an AsyncQueryHandler.
    //
    // Calendars are never removed from the phone due to a server sync.
    // But if a Calendar is added on the web (and it is selected and not
    // hidden) then it will be added to the list of calendars on the phone
    // (when this asynchronous query finishes).  When a new calendar from the
    // web is added to the phone, then the events for that calendar are also
    // downloaded from the web.
    // 
    // This sync is done automatically in the background when the
    // SelectCalendars activity is started.
    private void startCalendarSync() {
        getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS,
                Window.PROGRESS_VISIBILITY_ON);

        // TODO: make sure the user has login info.
        
        Uri uri = Calendars.LIVE_CONTENT_URI;
        mQueryHandler.startQuery(0, null, uri, PROJECTION,
                Calendars.SYNC_EVENTS + "=1",
                null, Calendars.DEFAULT_SORT_ORDER);
    }
}
