First step in unbundling Calendar

Change-Id: I12cf0e4141c069514dec78344592532848983abc
diff --git a/src/com/android/calendar/DayOfMonthCursor.java b/src/com/android/calendar/DayOfMonthCursor.java
new file mode 100644
index 0000000..f727669
--- /dev/null
+++ b/src/com/android/calendar/DayOfMonthCursor.java
@@ -0,0 +1,189 @@
+/*
+ * 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.util.MonthDisplayHelper;
+
+/**
+ * Helps control and display a month view of a calendar that has a current
+ * selected day.
+ * <ul>
+ *   <li>Keeps track of current month, day, year</li>
+ *   <li>Keeps track of current cursor position (row, column)</li>
+ *   <li>Provides methods to help display the calendar</li>
+ *   <li>Provides methods to move the cursor up / down / left / right.</li>
+ * </ul>
+ *
+ * This should be used by anyone who presents a month view to users and wishes
+ * to behave consistently with other widgets and apps; if we ever change our
+ * mind about when to flip the month, we can change it here only.
+ *
+ * @hide
+ */
+public class DayOfMonthCursor extends MonthDisplayHelper {
+
+    private int mRow;
+    private int mColumn;
+
+    /**
+     * @param year The initial year.
+     * @param month The initial month.
+     * @param dayOfMonth The initial dayOfMonth.
+     * @param weekStartDay What dayOfMonth of the week the week should start,
+     *   in terms of {@link java.util.Calendar} constants such as
+     *   {@link java.util.Calendar#SUNDAY}.
+     */
+    public DayOfMonthCursor(int year, int month, int dayOfMonth, int weekStartDay) {
+        super(year, month, weekStartDay);
+        mRow = getRowOf(dayOfMonth);
+        mColumn = getColumnOf(dayOfMonth);
+    }
+
+
+    public int getSelectedRow() {
+        return mRow;
+    }
+
+    public int getSelectedColumn() {
+        return mColumn;
+    }
+
+    public void setSelectedRowColumn(int row, int col) {
+        mRow = row;
+        mColumn = col;
+    }
+
+    public int getSelectedDayOfMonth() {
+        return getDayAt(mRow, mColumn);
+    }
+
+    /**
+     * @return 0 if the selection is in the current month, otherwise -1 or +1
+     * depending on whether the selection is in the first or last row.
+     */
+    public int getSelectedMonthOffset() {
+        if (isWithinCurrentMonth(mRow, mColumn)) {
+            return 0;
+        }
+        if (mRow == 0) {
+            return -1;
+        }
+        return 1;
+    }
+
+    public void setSelectedDayOfMonth(int dayOfMonth) {
+        mRow = getRowOf(dayOfMonth);
+        mColumn = getColumnOf(dayOfMonth);
+    }
+
+    public boolean isSelected(int row, int column) {
+        return (mRow == row) && (mColumn == column);
+    }
+
+    /**
+     * Move up one box, potentially flipping to the previous month.
+     * @return Whether the month was flipped to the previous month
+     *   due to the move.
+     */
+    public boolean up() {
+        if (isWithinCurrentMonth(mRow - 1, mColumn)) {
+            // within current month, just move up
+            mRow--;
+            return false;
+        }
+        // flip back to previous month, same column, first position within month
+        previousMonth();
+        mRow = 5;
+        while(!isWithinCurrentMonth(mRow, mColumn)) {
+            mRow--;
+        }
+        return true;
+    }
+
+    /**
+     * Move down one box, potentially flipping to the next month.
+     * @return Whether the month was flipped to the next month
+     *   due to the move.
+     */
+    public boolean down() {
+        if (isWithinCurrentMonth(mRow + 1, mColumn)) {
+            // within current month, just move down
+            mRow++;
+            return false;
+        }
+        // flip to next month, same column, first position within month
+        nextMonth();
+        mRow = 0;
+        while (!isWithinCurrentMonth(mRow, mColumn)) {
+            mRow++;
+        }
+        return true;
+    }
+
+    /**
+     * Move left one box, potentially flipping to the previous month.
+     * @return Whether the month was flipped to the previous month
+     *   due to the move.
+     */
+    public boolean left() {
+        if (mColumn == 0) {
+            mRow--;
+            mColumn = 6;
+        } else {
+            mColumn--;
+        }
+
+        if (isWithinCurrentMonth(mRow, mColumn)) {
+            return false;
+        }
+
+        // need to flip to last day of previous month
+        previousMonth();
+        int lastDay = getNumberOfDaysInMonth();
+        mRow = getRowOf(lastDay);
+        mColumn = getColumnOf(lastDay);
+        return true;
+    }
+
+    /**
+     * Move right one box, potentially flipping to the next month.
+     * @return Whether the month was flipped to the next month
+     *   due to the move.
+     */
+    public boolean right() {
+        if (mColumn == 6) {
+            mRow++;
+            mColumn = 0;
+        } else {
+            mColumn++;
+        }
+
+        if (isWithinCurrentMonth(mRow, mColumn)) {
+            return false;
+        }
+
+        // need to flip to first day of next month
+        nextMonth();
+        mRow = 0;
+        mColumn = 0;
+        while (!isWithinCurrentMonth(mRow, mColumn)) {
+            mColumn++;
+        }
+        return true;
+    }
+
+}