/*
 * Copyright (C) 2006 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 static android.provider.Calendar.EVENT_BEGIN_TIME;
import static android.provider.Calendar.EVENT_END_TIME;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.Calendar.BusyBits;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.DayOfMonthCursor;
import android.util.Log;
import android.util.SparseArray;
import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.PopupWindow;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Calendar;

public class MonthView extends View implements View.OnCreateContextMenuListener {

    private static final boolean PROFILE_LOAD_TIME = false;
    private static final boolean DEBUG_BUSYBITS = false;

    private static float mScale = 0; // Used for supporting different screen densities
    private static int WEEK_GAP = 0;
    private static int MONTH_DAY_GAP = 1;
    private static float HOUR_GAP = 0.5f;

    private static int MONTH_DAY_TEXT_SIZE = 20;
    private static int WEEK_BANNER_HEIGHT = 17;
    private static int WEEK_TEXT_SIZE = 15;
    private static int WEEK_TEXT_PADDING = 3;
    private static int BUSYBIT_WIDTH = 10;
    private static int BUSYBIT_RIGHT_MARGIN = 3;
    private static int BUSYBIT_TOP_BOTTOM_MARGIN = 7;

    private static int HORIZONTAL_FLING_THRESHOLD = 50;

    private int mCellHeight;
    private int mBorder;
    private boolean mLaunchDayView;

    private GestureDetector mGestureDetector;

    private String mDetailedView = CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW;

    private Time mToday;
    private Time mViewCalendar;
    private Time mSavedTime = new Time();   // the time when we entered this view

    // This Time object is used to set the time for the other Month view.
    private Time mOtherViewCalendar = new Time();

    // This Time object is used for temporary calculations and is allocated
    // once to avoid extra garbage collection
    private Time mTempTime = new Time();

    private DayOfMonthCursor mCursor;

    private Drawable mBoxSelected;
    private Drawable mBoxPressed;
    private Drawable mBoxLongPressed;
    private Drawable mDnaEmpty;
    private Drawable mDnaTop;
    private Drawable mDnaMiddle;
    private Drawable mDnaBottom;
    private int mCellWidth;

    private Resources mResources;
    private MonthActivity mParentActivity;
    private Navigator mNavigator;
    private final EventGeometry mEventGeometry;

    // Pre-allocate and reuse
    private Rect mRect = new Rect();

    // The number of hours represented by one busy bit
    private static final int HOURS_PER_BUSY_SLOT = 4;

    // The number of database intervals represented by one busy bit (slot)
    private static final int INTERVALS_PER_BUSY_SLOT = 4 * 60 / BusyBits.MINUTES_PER_BUSY_INTERVAL;

    // The bit mask for coalescing the raw busy bits from the database
    // (1 bit per hour) into the busy bits per slot (4-hour slots).
    private static final int BUSY_SLOT_MASK = (1 << INTERVALS_PER_BUSY_SLOT) - 1;

    // The number of slots in a day
    private static final int SLOTS_PER_DAY = 24 / HOURS_PER_BUSY_SLOT;

    // There is one "busy" bit for each slot of time.
    private byte[][] mBusyBits = new byte[31][SLOTS_PER_DAY];

    // Raw busy bits from database
    private int[] mRawBusyBits = new int[31];
    private int[] mAllDayCounts = new int[31];

    private PopupWindow mPopup;
    private View mPopupView;
    private static final int POPUP_HEIGHT = 100;
    private int mPreviousPopupHeight;
    private static final int POPUP_DISMISS_DELAY = 3000;
    private DismissPopup mDismissPopup = new DismissPopup();

    // For drawing to an off-screen Canvas
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private boolean mRedrawScreen = true;
    private Rect mBitmapRect = new Rect();
    private boolean mAnimating;

    // These booleans disable features that were taken out of the spec.
    private boolean mShowWeekNumbers = false;
    private boolean mShowToast = false;

    // Bitmap caches.
    // These improve performance by minimizing calls to NinePatchDrawable.draw() for common
    // drawables for events and day backgrounds.
    // mEventBitmapCache is indexed by an integer constructed from the bits in the busyBits
    // field. It is not expected to be larger than 12 bits (if so, we should switch to using a Map).
    // mDayBitmapCache is indexed by a unique integer constructed from the width/height.
    private SparseArray<Bitmap> mEventBitmapCache = new SparseArray<Bitmap>(1<<SLOTS_PER_DAY);
    private SparseArray<Bitmap> mDayBitmapCache = new SparseArray<Bitmap>(4);

    private ContextMenuHandler mContextMenuHandler = new ContextMenuHandler();

    /**
     * The selection modes are HIDDEN, PRESSED, SELECTED, and LONGPRESS.
     */
    private static final int SELECTION_HIDDEN = 0;
    private static final int SELECTION_PRESSED = 1;
    private static final int SELECTION_SELECTED = 2;
    private static final int SELECTION_LONGPRESS = 3;

    // Modulo used to pack (width,height) into a unique integer
    private static final int MODULO_SHIFT = 16;

    private int mSelectionMode = SELECTION_HIDDEN;

    /**
     * The first Julian day of the current month.
     */
    private int mFirstJulianDay;

    private final EventLoader mEventLoader;

    private ArrayList<Event> mEvents = new ArrayList<Event>();

    private Drawable mTodayBackground;
    private Drawable mDayBackground;

    // Cached colors
    private int mMonthOtherMonthColor;
    private int mMonthWeekBannerColor;
    private int mMonthOtherMonthBannerColor;
    private int mMonthOtherMonthDayNumberColor;
    private int mMonthDayNumberColor;
    private int mMonthTodayNumberColor;

    public MonthView(MonthActivity activity, Navigator navigator) {
        super(activity);
        if (mScale == 0) {
            mScale = getContext().getResources().getDisplayMetrics().density;
           if (mScale != 1) {
                    WEEK_GAP *= mScale;
                    MONTH_DAY_GAP *= mScale;
                    HOUR_GAP *= mScale;

                    MONTH_DAY_TEXT_SIZE *= mScale;
                    WEEK_BANNER_HEIGHT *= mScale;
                    WEEK_TEXT_SIZE *= mScale;
                    WEEK_TEXT_PADDING *= mScale;
                    BUSYBIT_WIDTH *= mScale;
                    BUSYBIT_RIGHT_MARGIN *= mScale;
                    BUSYBIT_TOP_BOTTOM_MARGIN *= mScale;

                    HORIZONTAL_FLING_THRESHOLD *= mScale;
                }
            }

        mEventLoader = activity.mEventLoader;
        mNavigator = navigator;
        mEventGeometry = new EventGeometry();
        mEventGeometry.setMinEventHeight(1.0f);
        mEventGeometry.setHourGap(HOUR_GAP);
        init(activity);
    }

    private void init(MonthActivity activity) {
        setFocusable(true);
        setClickable(true);
        setOnCreateContextMenuListener(this);
        mParentActivity = activity;
        mViewCalendar = new Time();
        long now = System.currentTimeMillis();
        mViewCalendar.set(now);
        mViewCalendar.monthDay = 1;
        long millis = mViewCalendar.normalize(true /* ignore DST */);
        mFirstJulianDay = Time.getJulianDay(millis, mViewCalendar.gmtoff);
        mViewCalendar.set(now);

        mCursor = new DayOfMonthCursor(mViewCalendar.year,  mViewCalendar.month,
                mViewCalendar.monthDay, mParentActivity.getStartDay());
        mToday = new Time();
        mToday.set(System.currentTimeMillis());

        mResources = activity.getResources();
        mBoxSelected = mResources.getDrawable(R.drawable.month_view_selected);
        mBoxPressed = mResources.getDrawable(R.drawable.month_view_pressed);
        mBoxLongPressed = mResources.getDrawable(R.drawable.month_view_longpress);

        mDnaEmpty = mResources.getDrawable(R.drawable.dna_empty);
        mDnaTop = mResources.getDrawable(R.drawable.dna_1_of_6);
        mDnaMiddle = mResources.getDrawable(R.drawable.dna_2345_of_6);
        mDnaBottom = mResources.getDrawable(R.drawable.dna_6_of_6);
        mTodayBackground = mResources.getDrawable(R.drawable.month_view_today_background);
        mDayBackground = mResources.getDrawable(R.drawable.month_view_background);

        // Cache color lookups
        Resources res = getResources();
        mMonthOtherMonthColor = res.getColor(R.color.month_other_month);
        mMonthWeekBannerColor = res.getColor(R.color.month_week_banner);
        mMonthOtherMonthBannerColor = res.getColor(R.color.month_other_month_banner);
        mMonthOtherMonthDayNumberColor = res.getColor(R.color.month_other_month_day_number);
        mMonthDayNumberColor = res.getColor(R.color.month_day_number);
        mMonthTodayNumberColor = res.getColor(R.color.month_today_number);

        if (mShowToast) {
            LayoutInflater inflater;
            inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mPopupView = inflater.inflate(R.layout.month_bubble, null);
            mPopup = new PopupWindow(activity);
            mPopup.setContentView(mPopupView);
            Resources.Theme dialogTheme = getResources().newTheme();
            dialogTheme.applyStyle(android.R.style.Theme_Dialog, true);
            TypedArray ta = dialogTheme.obtainStyledAttributes(new int[] {
                android.R.attr.windowBackground });
            mPopup.setBackgroundDrawable(ta.getDrawable(0));
            ta.recycle();
        }

        mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                    float velocityY) {
                // The user might do a slow "fling" after touching the screen
                // and we don't want the long-press to pop up a context menu.
                // Setting mLaunchDayView to false prevents the long-press.
                mLaunchDayView = false;
                mSelectionMode = SELECTION_HIDDEN;

                int distanceX = Math.abs((int) e2.getX() - (int) e1.getX());
                int distanceY = Math.abs((int) e2.getY() - (int) e1.getY());
                if (distanceY < HORIZONTAL_FLING_THRESHOLD || distanceY < distanceX) {
                    return false;
                }

                // Switch to a different month
                Time time = mOtherViewCalendar;
                time.set(mViewCalendar);
                if (velocityY < 0) {
                    time.month += 1;
                } else {
                    time.month -= 1;
                }
                time.normalize(true);
                mParentActivity.goTo(time, true);

                return true;
            }

            @Override
            public boolean onDown(MotionEvent e) {
                mLaunchDayView = false;
                return true;
            }

            @Override
            public void onShowPress(MotionEvent e) {
                int x = (int) e.getX();
                int y = (int) e.getY();
                int row = (y - WEEK_GAP) / (WEEK_GAP + mCellHeight);
                int col = (x - mBorder) / (MONTH_DAY_GAP + mCellWidth);
                if (row > 5) {
                    row = 5;
                }
                if (col > 6) {
                    col = 6;
                }

                // Launch the Day/Agenda view when the finger lifts up,
                // unless the finger moves before lifting up.
                mLaunchDayView = true;

                // Highlight the selected day.
                mCursor.setSelectedRowColumn(row, col);
                mSelectionMode = SELECTION_PRESSED;
                mRedrawScreen = true;
                invalidate();
            }

            @Override
            public void onLongPress(MotionEvent e) {
                // If mLaunchDayView is true, then we haven't done any scrolling
                // after touching the screen, so allow long-press to proceed
                // with popping up the context menu.
                if (mLaunchDayView) {
                    mLaunchDayView = false;
                    mSelectionMode = SELECTION_LONGPRESS;
                    mRedrawScreen = true;
                    invalidate();
                    performLongClick();
                }
            }

            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2,
                    float distanceX, float distanceY) {
                // If the user moves his finger after touching, then do not
                // launch the Day view when he lifts his finger.  Also, turn
                // off the selection.
                mLaunchDayView = false;

                if (mSelectionMode != SELECTION_HIDDEN) {
                    mSelectionMode = SELECTION_HIDDEN;
                    mRedrawScreen = true;
                    invalidate();
                }
                return true;
            }

            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                if (mLaunchDayView) {
                    mSelectionMode = SELECTION_SELECTED;
                    mRedrawScreen = true;
                    invalidate();
                    mLaunchDayView = false;
                    int x = (int) e.getX();
                    int y = (int) e.getY();
                    long millis = getSelectedMillisFor(x, y);
                    Utils.startActivity(getContext(), mDetailedView, millis);
                }

                return true;
            }
        });
    }

    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
        MenuItem item;
        
        final long startMillis = getSelectedTimeInMillis();
        final int flags = DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE
                | DateUtils.FORMAT_ABBREV_MONTH;
       
        final String title = DateUtils.formatDateTime(mParentActivity, startMillis, flags);    
        menu.setHeaderTitle(title);
        
        item = menu.add(0, MenuHelper.MENU_DAY, 0, R.string.show_day_view);
        item.setOnMenuItemClickListener(mContextMenuHandler);
        item.setIcon(android.R.drawable.ic_menu_day);
        item.setAlphabeticShortcut('d');

        item = menu.add(0, MenuHelper.MENU_AGENDA, 0, R.string.show_agenda_view);
        item.setOnMenuItemClickListener(mContextMenuHandler);
        item.setIcon(android.R.drawable.ic_menu_agenda);
        item.setAlphabeticShortcut('a');

        item = menu.add(0, MenuHelper.MENU_EVENT_CREATE, 0, R.string.event_create);
        item.setOnMenuItemClickListener(mContextMenuHandler);
        item.setIcon(android.R.drawable.ic_menu_add);
        item.setAlphabeticShortcut('n');
    }

    private class ContextMenuHandler implements MenuItem.OnMenuItemClickListener {
        public boolean onMenuItemClick(MenuItem item) {
            switch (item.getItemId()) {
                case MenuHelper.MENU_DAY: {
                    long startMillis = getSelectedTimeInMillis();
                    Utils.startActivity(mParentActivity, DayActivity.class.getName(), startMillis);
                    break;
                }
                case MenuHelper.MENU_AGENDA: {
                    long startMillis = getSelectedTimeInMillis();
                    Utils.startActivity(mParentActivity, AgendaActivity.class.getName(), startMillis);
                    break;
                }
                case MenuHelper.MENU_EVENT_CREATE: {
                    long startMillis = getSelectedTimeInMillis();
                    long endMillis = startMillis + DateUtils.HOUR_IN_MILLIS;
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setClassName(mContext, EditEvent.class.getName());
                    intent.putExtra(EVENT_BEGIN_TIME, startMillis);
                    intent.putExtra(EVENT_END_TIME, endMillis);
                    mParentActivity.startActivity(intent);
                    break;
                }
                default: {
                    return false;
                }
            }
            return true;
        }
    }

    void reloadEvents() {
        // Get the date for the beginning of the month
        Time monthStart = mTempTime;
        monthStart.set(mViewCalendar);
        monthStart.monthDay = 1;
        monthStart.hour = 0;
        monthStart.minute = 0;
        monthStart.second = 0;
        long millis = monthStart.normalize(true /* ignore isDst */);
        int startDay = Time.getJulianDay(millis, monthStart.gmtoff);

        // Load the busy-bits in the background
        mParentActivity.startProgressSpinner();
        final long startMillis;
        if (PROFILE_LOAD_TIME) {
            startMillis = SystemClock.uptimeMillis();
        } else {
            // To avoid a compiler error that this variable might not be initialized.
            startMillis = 0;
        }
        mEventLoader.loadBusyBitsInBackground(startDay, 31, mRawBusyBits, mAllDayCounts,
                new Runnable() {
            public void run() {
                convertBusyBits();
                if (PROFILE_LOAD_TIME) {
                    long endMillis = SystemClock.uptimeMillis();
                    long elapsed = endMillis - startMillis;
                    Log.i("Cal", (mViewCalendar.month+1) + "/" + mViewCalendar.year + " Month view load busybits: " + elapsed);
                }
                mRedrawScreen = true;
                mParentActivity.stopProgressSpinner();
                invalidate();
            }
        });
    }

    void animationStarted() {
        mAnimating = true;
    }

    void animationFinished() {
        mAnimating = false;
        mRedrawScreen = true;
        invalidate();
    }

    @Override
    protected void onSizeChanged(int width, int height, int oldw, int oldh) {
        drawingCalc(width, height);
        // If the size changed, then we should rebuild the bitmaps...
        clearBitmapCache();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        // No need to hang onto the bitmaps...
        clearBitmapCache();
        if (mBitmap != null) {
            mBitmap.recycle();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mRedrawScreen) {
            if (mCanvas == null) {
                drawingCalc(getWidth(), getHeight());
            }

            // If we are zero-sized, the canvas will remain null so check again
            if (mCanvas != null) {
                // Clear the background
                final Canvas bitmapCanvas = mCanvas;
                bitmapCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
                doDraw(bitmapCanvas);
                mRedrawScreen = false;
            }
        }

        // If we are zero-sized, the bitmap will be null so guard against this
        if (mBitmap != null) {
            canvas.drawBitmap(mBitmap, mBitmapRect, mBitmapRect, null);
        }
    }

    private void doDraw(Canvas canvas) {
        boolean isLandscape = getResources().getConfiguration().orientation
                == Configuration.ORIENTATION_LANDSCAPE;

        Paint p = new Paint();
        Rect r = mRect;
        int columnDay1 = mCursor.getColumnOf(1);

        // Get the Julian day for the date at row 0, column 0.
        int day = mFirstJulianDay - columnDay1;

        int weekNum = 0;
        Calendar calendar = null;
        if (mShowWeekNumbers) {
            calendar = Calendar.getInstance();
            boolean noPrevMonth = (columnDay1 == 0);

            // Compute the week number for the first row.
            weekNum = getWeekOfYear(0, 0, noPrevMonth, calendar);
        }

        for (int row = 0; row < 6; row++) {
            for (int column = 0; column < 7; column++) {
                drawBox(day, weekNum, row, column, canvas, p, r, isLandscape);
                day += 1;
            }

            if (mShowWeekNumbers) {
                weekNum += 1;
                if (weekNum >= 53) {
                    boolean inCurrentMonth = (day - mFirstJulianDay < 31);
                    weekNum = getWeekOfYear(row + 1, 0, inCurrentMonth, calendar);
                }
            }
        }
        
        drawGrid(canvas, p);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mGestureDetector.onTouchEvent(event)) {
            return true;
        }

        return super.onTouchEvent(event);
    }

    private long getSelectedMillisFor(int x, int y) {
        int row = (y - WEEK_GAP) / (WEEK_GAP + mCellHeight);
        int column = (x - mBorder) / (MONTH_DAY_GAP + mCellWidth);
        if (column > 6) {
            column = 6;
        }

        DayOfMonthCursor c = mCursor;
        Time time = mTempTime;
        time.set(mViewCalendar);

        // Compute the day number from the row and column.  If the row and
        // column are in a different month from the current one, then the
        // monthDay might be negative or it might be greater than the number
        // of days in this month, but that is okay because the normalize()
        // method will adjust the month (and year) if necessary.
        time.monthDay = 7 * row + column - c.getOffset() + 1;
        return time.normalize(true);
    }

    /**
     * Create a bitmap at the origin and draw the drawable to it using the bounds specified by rect.
     *
     * @param drawable the drawable we wish to render
     * @param width the width of the resulting bitmap
     * @param height the height of the resulting bitmap
     * @return a new bitmap
     */
    private Bitmap createBitmap(Drawable drawable, int width, int height) {
        // Create a bitmap with the same format as mBitmap (should be Bitmap.Config.ARGB_8888)
        Bitmap bitmap = Bitmap.createBitmap(width, height, mBitmap.getConfig());

        // Draw the drawable into the bitmap at the origin.
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }

    /**
     * Clears the bitmap cache. Generally only needed when the screen size changed.
     */
    private void clearBitmapCache() {
        recycleAndClearBitmapCache(mEventBitmapCache);
        recycleAndClearBitmapCache(mDayBitmapCache);
    }

    private void recycleAndClearBitmapCache(SparseArray<Bitmap> bitmapCache) {
        int size = bitmapCache.size();
        for(int i = 0; i < size; i++) {
            bitmapCache.valueAt(i).recycle();
        }
        bitmapCache.clear();

    }

    /**
     * Draw the grid lines for the calendar
     * @param canvas The canvas to draw on.
     * @param p The paint used for drawing.
     */
    private void drawGrid(Canvas canvas, Paint p) {
        p.setColor(mMonthOtherMonthColor);
        p.setAntiAlias(false);
        
        final int width = getMeasuredWidth();
        final int height = getMeasuredHeight();
        
        for (int row = 0; row < 6; row++) {
            int y = WEEK_GAP + row * (WEEK_GAP + mCellHeight) - 1;
            canvas.drawLine(0, y, width, y, p);
        }
        for (int column = 1; column < 7; column++) {
            int x = mBorder + column * (MONTH_DAY_GAP + mCellWidth) - 1;
            canvas.drawLine(x, WEEK_GAP, x, height, p);
        }
    }
    
    /**
     * Draw a single box onto the canvas.
     * @param day The Julian day.
     * @param weekNum The week number.
     * @param row The row of the box (0-5).
     * @param column The column of the box (0-6).
     * @param canvas The canvas to draw on.
     * @param p The paint used for drawing.
     * @param r The rectangle used for each box.
     * @param isLandscape Is the current orientation landscape.
     */
    private void drawBox(int day, int weekNum, int row, int column, Canvas canvas, Paint p,
            Rect r, boolean isLandscape) {

        // Only draw the selection if we are in the press state or if we have
        // moved the cursor with key input.
        boolean drawSelection = false;
        if (mSelectionMode != SELECTION_HIDDEN) {
            drawSelection = mCursor.isSelected(row, column);
        }

        boolean withinCurrentMonth = mCursor.isWithinCurrentMonth(row, column);
        boolean isToday = false;
        int dayOfBox = mCursor.getDayAt(row, column);
        if (dayOfBox == mToday.monthDay && mCursor.getYear() == mToday.year
                && mCursor.getMonth() == mToday.month) {
            isToday = true;
        }

        int y = WEEK_GAP + row*(WEEK_GAP + mCellHeight);
        int x = mBorder + column*(MONTH_DAY_GAP + mCellWidth);

        r.left = x;
        r.top = y;
        r.right = x + mCellWidth;
        r.bottom = y + mCellHeight;


        // Adjust the left column, right column, and bottom row to leave
        // no border.
        if (column == 0) {
            r.left = -1;
        } else if (column == 6) {
            r.right += mBorder + 2;
        }

        if (row == 5) {
            r.bottom = getMeasuredHeight();
        }

        // Draw the cell contents (excluding monthDay number)
        if (!withinCurrentMonth) {
            // Adjust cell boundaries to compensate for the different border
            // style.
            r.top--;
            if (column != 0) {
                r.left--;
            }
        } else if (drawSelection) {
            if (mSelectionMode == SELECTION_SELECTED) {
                mBoxSelected.setBounds(r);
                mBoxSelected.draw(canvas);
            } else if (mSelectionMode == SELECTION_PRESSED) {
                mBoxPressed.setBounds(r);
                mBoxPressed.draw(canvas);
            } else {
                mBoxLongPressed.setBounds(r);
                mBoxLongPressed.draw(canvas);
            }

            drawEvents(day, canvas, r, p);
            if (!mAnimating) {
                updateEventDetails(day);
            }
        } else {
            // Today gets a different background
            if (isToday) {
                // We could cache this for a little bit more performance, but it's not on the
                // performance radar...
                Drawable background = mTodayBackground;
                background.setBounds(r);
                background.draw(canvas);
            } else {
                // Use the bitmap cache to draw the day background
                int width = r.right - r.left;
                int height = r.bottom - r.top;
                // Compute a unique id that depends on width and height.
                int id = (height << MODULO_SHIFT) | width;
                Bitmap bitmap = mDayBitmapCache.get(id);
                if (bitmap == null) {
                     bitmap = createBitmap(mDayBackground, width, height);
                     mDayBitmapCache.put(id, bitmap);
                }
                canvas.drawBitmap(bitmap, r.left, r.top, p);
            }
            drawEvents(day, canvas, r, p);
        }

        // Draw week number
        if (mShowWeekNumbers && column == 0) {
            // Draw the banner
            p.setStyle(Paint.Style.FILL);
            p.setColor(mMonthWeekBannerColor);
            int right = r.right;
            r.right = right - BUSYBIT_WIDTH - BUSYBIT_RIGHT_MARGIN;
            if (isLandscape) {
                int bottom = r.bottom;
                r.bottom = r.top + WEEK_BANNER_HEIGHT;
                r.left++;
                canvas.drawRect(r, p);
                r.bottom = bottom;
                r.left--;
            } else {
                int top = r.top;
                r.top = r.bottom - WEEK_BANNER_HEIGHT;
                r.left++;
                canvas.drawRect(r, p);
                r.top = top;
                r.left--;
            }
            r.right = right;

            // Draw the number
            p.setColor(mMonthOtherMonthBannerColor);
            p.setAntiAlias(true);
            p.setTypeface(null);
            p.setTextSize(WEEK_TEXT_SIZE);
            p.setTextAlign(Paint.Align.LEFT);

            int textX = r.left + WEEK_TEXT_PADDING;
            int textY;
            if (isLandscape) {
                textY = r.top + WEEK_BANNER_HEIGHT - WEEK_TEXT_PADDING;
            } else {
                textY = r.bottom - WEEK_TEXT_PADDING;
            }

            canvas.drawText(String.valueOf(weekNum), textX, textY, p);
        }

        // Draw the monthDay number
        p.setStyle(Paint.Style.FILL);
        p.setAntiAlias(true);
        p.setTypeface(null);
        p.setTextSize(MONTH_DAY_TEXT_SIZE);

        if (!withinCurrentMonth) {
            p.setColor(mMonthOtherMonthDayNumberColor);
        } else if (drawSelection || !isToday) {
            p.setColor(mMonthDayNumberColor);
        } else {
            p.setColor(mMonthTodayNumberColor);
        }

        p.setTextAlign(Paint.Align.CENTER);
        int right = r.right - BUSYBIT_WIDTH - BUSYBIT_RIGHT_MARGIN;
        int textX = r.left + (right - r.left) / 2; // center of text
        int textY = r.bottom - BUSYBIT_TOP_BOTTOM_MARGIN - 2; // bottom of text
        canvas.drawText(String.valueOf(mCursor.getDayAt(row, column)), textX, textY, p);
    }

    /**
     * Converts the busy bits from the database that use 1-hour intervals to
     * the 4-hour time slots needed in this view.  Also, we map all-day
     * events to the first two 4-hour time slots (that is, an all-day event
     * will look like the first 8 hours from 12am to 8am are busy).  This
     * looks better than setting just the first 4-hour time slot because that
     * is barely visible in landscape mode.
     */
    private void convertBusyBits() {
        if (DEBUG_BUSYBITS) {
            Log.i("Cal", "convertBusyBits() SLOTS_PER_DAY: " + SLOTS_PER_DAY
                    + " BUSY_SLOT_MASK: " + BUSY_SLOT_MASK
                    + " INTERVALS_PER_BUSY_SLOT: " + INTERVALS_PER_BUSY_SLOT);
            for (int day = 0; day < 31; day++) {
                int bits = mRawBusyBits[day];
                String bitString = String.format("0x%06x", bits);
                String valString = "";
                for (int slot = 0; slot < SLOTS_PER_DAY; slot++) {
                    int val = bits & BUSY_SLOT_MASK;
                    bits = bits >>> INTERVALS_PER_BUSY_SLOT;
                    valString += " " + val;
                }
                Log.i("Cal", "[" + day + "] " + bitString + " " + valString
                        + " allday: " + mAllDayCounts[day]);
            }
        }
        for (int day = 0; day < 31; day++) {
            int bits = mRawBusyBits[day];
            for (int slot = 0; slot < SLOTS_PER_DAY; slot++) {
                int val = bits & BUSY_SLOT_MASK;
                bits = bits >>> INTERVALS_PER_BUSY_SLOT;
                if (val == 0) {
                    mBusyBits[day][slot] = 0;
                } else {
                    mBusyBits[day][slot] = 1;
                }
            }
            if (mAllDayCounts[day] > 0) {
                mBusyBits[day][0] = 1;
                mBusyBits[day][1] = 1;
            }
        }
    }

    /**
     * Create a bitmap at the origin for the given set of busyBits.
     *
     * @param busyBits an array of bits with elements set to 1 if we have an event for that slot
     * @param rect the size of the resulting
     * @return a new bitmap
     */
    private Bitmap createEventBitmap(byte[] busyBits, Rect rect) {
        // Compute the size of the smallest bitmap, excluding margins.
        final int left = 0;
        final int right = BUSYBIT_WIDTH;
        final int top = 0;
        final int bottom = (rect.bottom - rect.top) - 2 * BUSYBIT_TOP_BOTTOM_MARGIN;
        final int height = bottom - top;
        final int width = right - left;

        final Drawable dnaEmpty = mDnaEmpty;
        final Drawable dnaTop = mDnaTop;
        final Drawable dnaMiddle = mDnaMiddle;
        final Drawable dnaBottom = mDnaBottom;
        final float slotHeight = (float) height / SLOTS_PER_DAY;

        // Create a bitmap with the same format as mBitmap (should be Bitmap.Config.ARGB_8888)
        Bitmap bitmap = Bitmap.createBitmap(width, height, mBitmap.getConfig());

        // Create a canvas for drawing and draw background (dnaEmpty)
        Canvas canvas = new Canvas(bitmap);
        dnaEmpty.setBounds(left, top, right, bottom);
        dnaEmpty.draw(canvas);

        // The first busy bit is a drawable that is round at the top
        if (busyBits[0] == 1) {
            float rectBottom = top + slotHeight;
            dnaTop.setBounds(left, top, right, (int) rectBottom);
            dnaTop.draw(canvas);
        }

        // The last busy bit is a drawable that is round on the bottom
        int lastIndex = busyBits.length - 1;
        if (busyBits[lastIndex] == 1) {
            float rectTop = bottom - slotHeight;
            dnaBottom.setBounds(left, (int) rectTop, right, bottom);
            dnaBottom.draw(canvas);
        }

        // Draw all intermediate pieces. We could further optimize this to
        // draw runs of bits, but it probably won't yield much more performance.
        float rectTop = top + slotHeight;
        for (int index = 1; index < lastIndex; index++) {
            float rectBottom = rectTop + slotHeight;
            if (busyBits[index] == 1) {
                dnaMiddle.setBounds(left, (int) rectTop, right, (int) rectBottom);
                dnaMiddle.draw(canvas);
            }
            rectTop = rectBottom;
        }
        return bitmap;
    }

    private void drawEvents(int date, Canvas canvas, Rect rect, Paint p) {
        // These are the coordinates of the upper left corner where we'll draw the event bitmap
        int top = rect.top + BUSYBIT_TOP_BOTTOM_MARGIN;
        int right = rect.right - BUSYBIT_RIGHT_MARGIN;
        int left = right - BUSYBIT_WIDTH;

        // Display the busy bits.  Draw a rectangle for each run of 1-bits.
        int day = date - mFirstJulianDay;
        byte[] busyBits = mBusyBits[day];
        int lastIndex = busyBits.length - 1;

        // Cache index is simply all of the bits combined into an integer
        int cacheIndex = 0;
        for (int i = 0 ; i <= lastIndex; i++) cacheIndex |= busyBits[i] << i;
        Bitmap bitmap = mEventBitmapCache.get(cacheIndex);
        if (bitmap == null) {
            // Create a bitmap that we'll reuse for all events with the same
            // combination of busyBits.
            bitmap = createEventBitmap(busyBits, rect);
            mEventBitmapCache.put(cacheIndex, bitmap);
        }
        canvas.drawBitmap(bitmap, left, top, p);
    }

    private boolean isFirstDayOfNextMonth(int row, int column) {
        if (column == 0) {
            column = 6;
            row--;
        } else {
            column--;
        }
        return mCursor.isWithinCurrentMonth(row, column);
    }

    private int getWeekOfYear(int row, int column, boolean isWithinCurrentMonth,
            Calendar calendar) {
        calendar.set(Calendar.DAY_OF_MONTH, mCursor.getDayAt(row, column));
        if (isWithinCurrentMonth) {
            calendar.set(Calendar.MONTH, mCursor.getMonth());
            calendar.set(Calendar.YEAR, mCursor.getYear());
        } else {
            int month = mCursor.getMonth();
            int year = mCursor.getYear();
            if (row < 2) {
                // Previous month
                if (month == 0) {
                    year--;
                    month = 11;
                } else {
                    month--;
                }
            } else {
                // Next month
                if (month == 11) {
                    year++;
                    month = 0;
                } else {
                    month++;
                }
            }
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.YEAR, year);
        }

        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    void setDetailedView(String detailedView) {
        mDetailedView = detailedView;
    }

    void setSelectedTime(Time time) {
        // Save the selected time so that we can restore it later when we switch views.
        mSavedTime.set(time);

        mViewCalendar.set(time);
        mViewCalendar.monthDay = 1;
        long millis = mViewCalendar.normalize(true /* ignore DST */);
        mFirstJulianDay = Time.getJulianDay(millis, mViewCalendar.gmtoff);
        mViewCalendar.set(time);

        mCursor = new DayOfMonthCursor(time.year, time.month, time.monthDay,
                mCursor.getWeekStartDay());

        mRedrawScreen = true;
        invalidate();
    }

    public long getSelectedTimeInMillis() {
        Time time = mTempTime;
        time.set(mViewCalendar);

        time.month += mCursor.getSelectedMonthOffset();
        time.monthDay = mCursor.getSelectedDayOfMonth();

        // Restore the saved hour:minute:second offset from when we entered
        // this view.
        time.second = mSavedTime.second;
        time.minute = mSavedTime.minute;
        time.hour = mSavedTime.hour;
        return time.normalize(true);
    }

    Time getTime() {
        return mViewCalendar;
    }

    public int getSelectionMode() {
        return mSelectionMode;
    }

    public void setSelectionMode(int selectionMode) {
        mSelectionMode = selectionMode;
    }

    private void drawingCalc(int width, int height) {
        mCellHeight = (height - (6 * WEEK_GAP)) / 6;
        mEventGeometry.setHourHeight((mCellHeight - 25.0f * HOUR_GAP) / 24.0f);
        mCellWidth = (width - (6 * MONTH_DAY_GAP)) / 7;
        mBorder = (width - 6 * (mCellWidth + MONTH_DAY_GAP) - mCellWidth) / 2;

        if (mShowToast) {
            mPopup.dismiss();
            mPopup.setWidth(width - 20);
            mPopup.setHeight(POPUP_HEIGHT);
        }

        if (((mBitmap == null)
                    || mBitmap.isRecycled()
                    || (mBitmap.getHeight() != height)
                    || (mBitmap.getWidth() != width))
                && (width > 0) && (height > 0)) {
            if (mBitmap != null) {
                mBitmap.recycle();
            }
            mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mBitmap);
        }

        mBitmapRect.top = 0;
        mBitmapRect.bottom = height;
        mBitmapRect.left = 0;
        mBitmapRect.right = width;
    }

    private void updateEventDetails(int date) {
        if (!mShowToast) {
            return;
        }

        getHandler().removeCallbacks(mDismissPopup);
        ArrayList<Event> events = mEvents;
        int numEvents = events.size();
        if (numEvents == 0) {
            mPopup.dismiss();
            return;
        }

        int eventIndex = 0;
        for (int i = 0; i < numEvents; i++) {
            Event event = events.get(i);

            if (event.startDay > date || event.endDay < date) {
                continue;
            }

            // If we have all the event that we can display, then just count
            // the extra ones.
            if (eventIndex >= 4) {
                eventIndex += 1;
                continue;
            }

            int flags;
            boolean showEndTime = false;
            if (event.allDay) {
                int numDays = event.endDay - event.startDay;
                if (numDays == 0) {
                    flags = DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_DATE
                            | DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_ALL;
                } else {
                    showEndTime = true;
                    flags = DateUtils.FORMAT_UTC | DateUtils.FORMAT_SHOW_DATE
                            | DateUtils.FORMAT_ABBREV_ALL;
                }
            } else {
                flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_CAP_NOON_MIDNIGHT;
                if (DateFormat.is24HourFormat(mContext)) {
                    flags |= DateUtils.FORMAT_24HOUR;
                }
            }

            String timeRange;
            if (showEndTime) {
                timeRange = DateUtils.formatDateRange(mParentActivity,
                        event.startMillis, event.endMillis, flags);
            } else {
                timeRange = DateUtils.formatDateRange(mParentActivity,
                        event.startMillis, event.startMillis, flags);
            }

            TextView timeView = null;
            TextView titleView = null;
            switch (eventIndex) {
                case 0:
                    timeView = (TextView) mPopupView.findViewById(R.id.time0);
                    titleView = (TextView) mPopupView.findViewById(R.id.event_title0);
                    break;
                case 1:
                    timeView = (TextView) mPopupView.findViewById(R.id.time1);
                    titleView = (TextView) mPopupView.findViewById(R.id.event_title1);
                    break;
                case 2:
                    timeView = (TextView) mPopupView.findViewById(R.id.time2);
                    titleView = (TextView) mPopupView.findViewById(R.id.event_title2);
                    break;
                case 3:
                    timeView = (TextView) mPopupView.findViewById(R.id.time3);
                    titleView = (TextView) mPopupView.findViewById(R.id.event_title3);
                    break;
            }

            timeView.setText(timeRange);
            titleView.setText(event.title);
            eventIndex += 1;
        }
        if (eventIndex == 0) {
            // We didn't find any events for this day
            mPopup.dismiss();
            return;
        }

        // Hide the items that have no event information
        View view;
        switch (eventIndex) {
            case 1:
                view = mPopupView.findViewById(R.id.item_layout1);
                view.setVisibility(View.GONE);
                view = mPopupView.findViewById(R.id.item_layout2);
                view.setVisibility(View.GONE);
                view = mPopupView.findViewById(R.id.item_layout3);
                view.setVisibility(View.GONE);
                view = mPopupView.findViewById(R.id.plus_more);
                view.setVisibility(View.GONE);
                break;
            case 2:
                view = mPopupView.findViewById(R.id.item_layout1);
                view.setVisibility(View.VISIBLE);
                view = mPopupView.findViewById(R.id.item_layout2);
                view.setVisibility(View.GONE);
                view = mPopupView.findViewById(R.id.item_layout3);
                view.setVisibility(View.GONE);
                view = mPopupView.findViewById(R.id.plus_more);
                view.setVisibility(View.GONE);
                break;
            case 3:
                view = mPopupView.findViewById(R.id.item_layout1);
                view.setVisibility(View.VISIBLE);
                view = mPopupView.findViewById(R.id.item_layout2);
                view.setVisibility(View.VISIBLE);
                view = mPopupView.findViewById(R.id.item_layout3);
                view.setVisibility(View.GONE);
                view = mPopupView.findViewById(R.id.plus_more);
                view.setVisibility(View.GONE);
                break;
            case 4:
                view = mPopupView.findViewById(R.id.item_layout1);
                view.setVisibility(View.VISIBLE);
                view = mPopupView.findViewById(R.id.item_layout2);
                view.setVisibility(View.VISIBLE);
                view = mPopupView.findViewById(R.id.item_layout3);
                view.setVisibility(View.VISIBLE);
                view = mPopupView.findViewById(R.id.plus_more);
                view.setVisibility(View.GONE);
                break;
            default:
                view = mPopupView.findViewById(R.id.item_layout1);
                view.setVisibility(View.VISIBLE);
                view = mPopupView.findViewById(R.id.item_layout2);
                view.setVisibility(View.VISIBLE);
                view = mPopupView.findViewById(R.id.item_layout3);
                view.setVisibility(View.VISIBLE);
                TextView tv = (TextView) mPopupView.findViewById(R.id.plus_more);
                tv.setVisibility(View.VISIBLE);
                String format = mResources.getString(R.string.plus_N_more);
                String plusMore = String.format(format, eventIndex - 4);
                tv.setText(plusMore);
                break;
        }

        if (eventIndex > 5) {
            eventIndex = 5;
        }
        int popupHeight = 20 * eventIndex + 15;
        mPopup.setHeight(popupHeight);

        if (mPreviousPopupHeight != popupHeight) {
            mPreviousPopupHeight = popupHeight;
            mPopup.dismiss();
        }
        mPopup.showAtLocation(this, Gravity.BOTTOM | Gravity.LEFT, 0, 0);
        postDelayed(mDismissPopup, POPUP_DISMISS_DELAY);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        long duration = event.getEventTime() - event.getDownTime();

        switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_CENTER:
            if (mSelectionMode == SELECTION_HIDDEN) {
                // Don't do anything unless the selection is visible.
                break;
            }

            if (mSelectionMode == SELECTION_PRESSED) {
                // This was the first press when there was nothing selected.
                // Change the selection from the "pressed" state to the
                // the "selected" state.  We treat short-press and
                // long-press the same here because nothing was selected.
                mSelectionMode = SELECTION_SELECTED;
                mRedrawScreen = true;
                invalidate();
                break;
            }

            // Check the duration to determine if this was a short press
            if (duration < ViewConfiguration.getLongPressTimeout()) {
                long millis = getSelectedTimeInMillis();
                Utils.startActivity(getContext(), mDetailedView, millis);
            } else {
                mSelectionMode = SELECTION_LONGPRESS;
                mRedrawScreen = true;
                invalidate();
                performLongClick();
            }
        }
        return super.onKeyUp(keyCode, event);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (mSelectionMode == SELECTION_HIDDEN) {
            if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
                    || keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_UP
                    || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
                // Display the selection box but don't move or select it
                // on this key press.
                mSelectionMode = SELECTION_SELECTED;
                mRedrawScreen = true;
                invalidate();
                return true;
            } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
                // Display the selection box but don't select it
                // on this key press.
                mSelectionMode = SELECTION_PRESSED;
                mRedrawScreen = true;
                invalidate();
                return true;
            }
        }

        mSelectionMode = SELECTION_SELECTED;
        boolean redraw = false;
        Time other = null;

        switch (keyCode) {
        case KeyEvent.KEYCODE_ENTER:
            long millis = getSelectedTimeInMillis();
            Utils.startActivity(getContext(), mDetailedView, millis);
            return true;
        case KeyEvent.KEYCODE_DPAD_UP:
            if (mCursor.up()) {
                other = mOtherViewCalendar;
                other.set(mViewCalendar);
                other.month -= 1;
                other.monthDay = mCursor.getSelectedDayOfMonth();

                // restore the calendar cursor for the animation
                mCursor.down();
            }
            redraw = true;
            break;

        case KeyEvent.KEYCODE_DPAD_DOWN:
            if (mCursor.down()) {
                other = mOtherViewCalendar;
                other.set(mViewCalendar);
                other.month += 1;
                other.monthDay = mCursor.getSelectedDayOfMonth();

                // restore the calendar cursor for the animation
                mCursor.up();
            }
            redraw = true;
            break;

        case KeyEvent.KEYCODE_DPAD_LEFT:
            if (mCursor.left()) {
                other = mOtherViewCalendar;
                other.set(mViewCalendar);
                other.month -= 1;
                other.monthDay = mCursor.getSelectedDayOfMonth();

                // restore the calendar cursor for the animation
                mCursor.right();
            }
            redraw = true;
            break;

        case KeyEvent.KEYCODE_DPAD_RIGHT:
            if (mCursor.right()) {
                other = mOtherViewCalendar;
                other.set(mViewCalendar);
                other.month += 1;
                other.monthDay = mCursor.getSelectedDayOfMonth();

                // restore the calendar cursor for the animation
                mCursor.left();
            }
            redraw = true;
            break;
        }

        if (other != null) {
            other.normalize(true /* ignore DST */);
            mNavigator.goTo(other, true);
        } else if (redraw) {
            mRedrawScreen = true;
            invalidate();
        }

        return redraw;
    }

    class DismissPopup implements Runnable {
        public void run() {
            mPopup.dismiss();
        }
    }

    // This is called when the activity is paused so that the popup can
    // be dismissed.
    void dismissPopup() {
        if (!mShowToast) {
            return;
        }

        // Protect against null-pointer exceptions
        if (mPopup != null) {
            mPopup.dismiss();
        }

        Handler handler = getHandler();
        if (handler != null) {
            handler.removeCallbacks(mDismissPopup);
        }
    }
}
