/*
 * Copyright (C) 2010 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.app.FragmentManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.provider.CalendarContract.Calendars;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.TouchDelegate;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ListAdapter;
import android.widget.TextView;

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

public class SelectCalendarsSimpleAdapter extends BaseAdapter implements ListAdapter {
    private static final String TAG = "SelectCalendarsAdapter";
    private static final String COLOR_PICKER_DIALOG_TAG = "ColorPickerDialog";

    private static int BOTTOM_ITEM_HEIGHT = 64;
    private static int NORMAL_ITEM_HEIGHT = 48;

    private static final int IS_SELECTED = 1 << 0;
    private static final int IS_TOP = 1 << 1;
    private static final int IS_BOTTOM = 1 << 2;
    private static final int IS_BELOW_SELECTED = 1 << 3;

    private CalendarColorPickerDialog mColorPickerDialog;

    private LayoutInflater mInflater;
    Resources mRes;
    private int mLayout;
    private int mOrientation;
    private CalendarRow[] mData;
    private Cursor mCursor;
    private int mRowCount = 0;

    private FragmentManager mFragmentManager;
    private boolean mIsTablet;
    private int mColorViewTouchAreaIncrease;

    private int mIdColumn;
    private int mNameColumn;
    private int mColorColumn;
    private int mVisibleColumn;
    private int mOwnerAccountColumn;
    private static float mScale = 0;
    private int mColorCalendarVisible;
    private int mColorCalendarHidden;
    private int mColorCalendarSecondaryVisible;
    private int mColorCalendarSecondaryHidden;

    private class CalendarRow {
        long id;
        String displayName;
        String ownerAccount;
        int color;
        boolean selected;
    }

    public SelectCalendarsSimpleAdapter(Context context, int layout, Cursor c, FragmentManager fm) {
        super();
        mLayout = layout;
        mOrientation = context.getResources().getConfiguration().orientation;
        initData(c);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mRes = context.getResources();
        mColorCalendarVisible = mRes.getColor(R.color.calendar_visible);
        mColorCalendarHidden = mRes.getColor(R.color.calendar_hidden);
        mColorCalendarSecondaryVisible = mRes.getColor(R.color.calendar_secondary_visible);
        mColorCalendarSecondaryHidden = mRes.getColor(R.color.calendar_secondary_hidden);

        if (mScale == 0) {
            mScale = mRes.getDisplayMetrics().density;
            BOTTOM_ITEM_HEIGHT *= mScale;
            NORMAL_ITEM_HEIGHT *= mScale;
        }

        mFragmentManager = fm;
        mColorPickerDialog = (CalendarColorPickerDialog)
                fm.findFragmentByTag(COLOR_PICKER_DIALOG_TAG);
        mIsTablet = Utils.getConfigBool(context, R.bool.tablet_config);
        mColorViewTouchAreaIncrease = context.getResources()
                .getDimensionPixelSize(R.dimen.color_view_touch_area_increase);
    }

    private static class TabletCalendarItemBackgrounds {
        static private int[] mBackgrounds = null;

        /**
         * Sets up the background drawables for the calendars list
         *
         * @param res The context's resources
         */
        static int[] getBackgrounds() {
            // Not thread safe. Ok if called only from main thread
            if (mBackgrounds != null) {
                return mBackgrounds;
            }

            mBackgrounds = new int[16];

            mBackgrounds[0] = R.drawable.calname_unselected;

            mBackgrounds[IS_SELECTED] = R.drawable.calname_select_underunselected;

            mBackgrounds[IS_SELECTED | IS_BOTTOM] =
                    R.drawable.calname_bottom_select_underunselected;

            mBackgrounds[IS_SELECTED | IS_BOTTOM | IS_BELOW_SELECTED] =
                    R.drawable.calname_bottom_select_underselect;
            mBackgrounds[IS_SELECTED | IS_TOP | IS_BOTTOM | IS_BELOW_SELECTED] = mBackgrounds[
                    IS_SELECTED | IS_BOTTOM | IS_BELOW_SELECTED];
            mBackgrounds[IS_SELECTED | IS_TOP | IS_BOTTOM] = mBackgrounds[IS_SELECTED | IS_BOTTOM
                    | IS_BELOW_SELECTED];

            mBackgrounds[IS_SELECTED | IS_BELOW_SELECTED] = R.drawable.calname_select_underselect;
            mBackgrounds[IS_SELECTED | IS_TOP | IS_BELOW_SELECTED] = mBackgrounds[IS_SELECTED
                    | IS_BELOW_SELECTED];
            mBackgrounds[IS_SELECTED | IS_TOP] = mBackgrounds[IS_SELECTED | IS_BELOW_SELECTED];

            mBackgrounds[IS_BOTTOM] = R.drawable.calname_bottom_unselected;

            mBackgrounds[IS_BOTTOM | IS_BELOW_SELECTED] =
                    R.drawable.calname_bottom_unselected_underselect;
            mBackgrounds[IS_TOP | IS_BOTTOM | IS_BELOW_SELECTED] = mBackgrounds[IS_BOTTOM
                    | IS_BELOW_SELECTED];
            mBackgrounds[IS_TOP | IS_BOTTOM] = mBackgrounds[IS_BOTTOM | IS_BELOW_SELECTED];

            mBackgrounds[IS_BELOW_SELECTED] = R.drawable.calname_unselected_underselect;
            mBackgrounds[IS_TOP | IS_BELOW_SELECTED] = mBackgrounds[IS_BELOW_SELECTED];
            mBackgrounds[IS_TOP] = mBackgrounds[IS_BELOW_SELECTED];
            return mBackgrounds;
        }
    }

    private void initData(Cursor c) {
        if (mCursor != null && c != mCursor) {
            mCursor.close();
        }
        if (c == null) {
            mCursor = c;
            mRowCount = 0;
            mData = null;
            return;
        }
        // TODO create a broadcast listener for ACTION_PROVIDER_CHANGED to update the cursor
        mCursor = c;
        mIdColumn = c.getColumnIndexOrThrow(Calendars._ID);
        mNameColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME);
        mColorColumn = c.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR);
        mVisibleColumn = c.getColumnIndexOrThrow(Calendars.VISIBLE);
        mOwnerAccountColumn = c.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT);

        mRowCount = c.getCount();
        mData = new CalendarRow[(c.getCount())];
        c.moveToPosition(-1);
        int p = 0;
        while (c.moveToNext()) {
            mData[p] = new CalendarRow();
            mData[p].id = c.getLong(mIdColumn);
            mData[p].displayName = c.getString(mNameColumn);
            mData[p].color = c.getInt(mColorColumn);
            mData[p].selected = c.getInt(mVisibleColumn) != 0;
            mData[p].ownerAccount = c.getString(mOwnerAccountColumn);
            p++;
        }
    }

    public void changeCursor(Cursor c) {
        initData(c);
        notifyDataSetChanged();
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        if (position >= mRowCount) {
            return null;
        }
        String name = mData[position].displayName;
        boolean selected = mData[position].selected;

        int color = Utils.getDisplayColorFromColor(mData[position].color);
        View view;
        if (convertView == null) {
            view = mInflater.inflate(mLayout, parent, false);
            final View delegate = view.findViewById(R.id.color);
            final View delegateParent = (View) delegate.getParent();
            delegateParent.post(new Runnable() {

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

        TextView calendarName = (TextView) view.findViewById(R.id.calendar);
        calendarName.setText(name);

        View colorView = view.findViewById(R.id.color);
        colorView.setBackgroundColor(color);
        colorView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mColorPickerDialog == null) {
                    mColorPickerDialog = CalendarColorPickerDialog.newInstance(mData[position].id,
                            mIsTablet);
                } else {
                    mColorPickerDialog.setCalendarId(mData[position].id);
                }
                mFragmentManager.executePendingTransactions();
                if (!mColorPickerDialog.isAdded()) {
                    mColorPickerDialog.show(mFragmentManager, COLOR_PICKER_DIALOG_TAG);
                }
            }
        });

        int textColor;
        if (selected) {
            textColor = mColorCalendarVisible;
        } else {
            textColor = mColorCalendarHidden;
        }
        calendarName.setTextColor(textColor);

        CheckBox syncCheckBox = (CheckBox) view.findViewById(R.id.sync);
        if (syncCheckBox != null) {
            // Full screen layout
            syncCheckBox.setChecked(selected);

            LayoutParams layoutParam = calendarName.getLayoutParams();
            TextView secondaryText = (TextView) view.findViewById(R.id.status);
            if (!TextUtils.isEmpty(mData[position].ownerAccount)
                    && !mData[position].ownerAccount.equals(name)
                    && !mData[position].ownerAccount.endsWith("calendar.google.com")) {
                int secondaryColor;
                if (selected) {
                    secondaryColor = mColorCalendarSecondaryVisible;
                } else {
                    secondaryColor = mColorCalendarSecondaryHidden;
                }
                secondaryText.setText(mData[position].ownerAccount);
                secondaryText.setTextColor(secondaryColor);
                secondaryText.setVisibility(View.VISIBLE);
                layoutParam.height = LayoutParams.WRAP_CONTENT;
            } else {
                secondaryText.setVisibility(View.GONE);
                layoutParam.height = LayoutParams.MATCH_PARENT;
            }

            calendarName.setLayoutParams(layoutParam);

        } else {
            // Tablet layout
            view.findViewById(R.id.color).setEnabled(selected);
            view.setBackgroundDrawable(getBackground(position, selected));
            ViewGroup.LayoutParams newParams = view.getLayoutParams();
            if (position == mData.length - 1) {
                newParams.height = BOTTOM_ITEM_HEIGHT;
            } else {
                newParams.height = NORMAL_ITEM_HEIGHT;
            }
            view.setLayoutParams(newParams);
            CheckBox visibleCheckBox = (CheckBox) view.findViewById(R.id.visible_check_box);
            if (visibleCheckBox != null) {
                visibleCheckBox.setChecked(selected);
            }
        }
        view.invalidate();
        return view;
    }

    /**
     * @param position position of the calendar item
     * @param selected whether it is selected or not
     * @return the drawable to use for this view
     */
    protected Drawable getBackground(int position, boolean selected) {
        int bg;
        bg = selected ? IS_SELECTED : 0;
        bg |= (position == 0 && mOrientation == Configuration.ORIENTATION_LANDSCAPE) ? IS_TOP : 0;
        bg |= position == mData.length - 1 ? IS_BOTTOM : 0;
        bg |= (position > 0 && mData[position - 1].selected) ? IS_BELOW_SELECTED : 0;
        return mRes.getDrawable(TabletCalendarItemBackgrounds.getBackgrounds()[bg]);
    }

    @Override
    public int getCount() {
        return mRowCount;
    }

    @Override
    public Object getItem(int position) {
        if (position >= mRowCount) {
            return null;
        }
        CalendarRow item = mData[position];
        return item;
    }

    @Override
    public long getItemId(int position) {
        if (position >= mRowCount) {
            return 0;
        }
        return mData[position].id;
    }

    public void setVisible(int position, int visible) {
        mData[position].selected = visible != 0;
        notifyDataSetChanged();
    }

    public int getVisible(int position) {
        return mData[position].selected ? 1 : 0;
    }

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