/*
 * 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 com.android.calendar.R;
import com.android.calendar.Utils;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.provider.CalendarContract.Calendars;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ListAdapter;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class SelectCalendarsSimpleAdapter extends BaseAdapter implements ListAdapter {
    private static final String TAG = "SelectCalendarsAdapter";
    private static int SELECTED_COLOR_CHIP_SIZE = 16;
    private static int UNSELECTED_COLOR_CHIP_SIZE = 10;
    private static int COLOR_CHIP_LEFT_MARGIN = 20;
    private static int COLOR_CHIP_RIGHT_MARGIN = 8;
    private static int COLOR_CHIP_TOP_OFFSET = 5;
    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 LayoutInflater mInflater;
    Resources mRes;
    private int mLayout;
    private int mOrientation;
    private CalendarRow[] mData;
    private Cursor mCursor;
    private int mRowCount = 0;

    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) {
        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;
            SELECTED_COLOR_CHIP_SIZE *= mScale;
            UNSELECTED_COLOR_CHIP_SIZE *= mScale;
            COLOR_CHIP_LEFT_MARGIN *= mScale;
            COLOR_CHIP_RIGHT_MARGIN *= mScale;
            COLOR_CHIP_TOP_OFFSET *= mScale;
            BOTTOM_ITEM_HEIGHT *= mScale;
            NORMAL_ITEM_HEIGHT *= mScale;
        }
    }

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

    public View getView(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);
        } else {
            view = convertView;
        }

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

        View colorView = view.findViewById(R.id.color);
        colorView.setBackgroundColor(color);

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

            int textColor;
            if (selected) {
                textColor = mColorCalendarVisible;
            } else {
                textColor = mColorCalendarHidden;
            }
            calendarName.setTextColor(textColor);
            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
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    SELECTED_COLOR_CHIP_SIZE, SELECTED_COLOR_CHIP_SIZE);
            params.leftMargin = COLOR_CHIP_LEFT_MARGIN;
            params.rightMargin = COLOR_CHIP_RIGHT_MARGIN;
            // This offset is needed because the assets include the bottom of the
            // previous item
            params.topMargin = COLOR_CHIP_TOP_OFFSET;
            if (!selected) {
                params.height = UNSELECTED_COLOR_CHIP_SIZE;
                params.width = UNSELECTED_COLOR_CHIP_SIZE;
                params.leftMargin += (SELECTED_COLOR_CHIP_SIZE - UNSELECTED_COLOR_CHIP_SIZE) / 2;
                params.topMargin += (SELECTED_COLOR_CHIP_SIZE - UNSELECTED_COLOR_CHIP_SIZE) / 2;
            }
            colorView.setLayoutParams(params);

            Drawable bg = getBackground(position, selected);
            view.setBackgroundDrawable(bg);
            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]);
    }

    public int getCount() {
        return mRowCount;
    }

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

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