1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/*
2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
4146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * you may not use this file except in compliance with the License.
6146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * You may obtain a copy of the License at
7146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
8146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project *
10146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * See the License for the specific language governing permissions and
14146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * limitations under the License.
15146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */
16146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
1700b8c1a39d75c1b4626dc987bd1a51cfaf7c9be1Mason Tangpackage com.android.calendar.agenda;
18146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
199a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport com.android.calendar.R;
209a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport com.android.calendar.Utils;
219a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport com.android.calendar.agenda.AgendaWindowAdapter.DayAdapterInfo;
229a88873f9ec97b47aaaaae47208d22b3998b8e99Erik
23146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context;
24146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.database.Cursor;
252d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelsonimport android.graphics.Typeface;
269a88873f9ec97b47aaaaae47208d22b3998b8e99Erikimport android.text.TextUtils;
27146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.DateUtils;
28146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.text.format.Time;
29e692869cbbc3d7430075bb739f0b0fa83cf91feaIsaac Katzenelsonimport android.util.Log;
30146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.LayoutInflater;
31146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.View;
32146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.ViewGroup;
33146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.BaseAdapter;
34146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.TextView;
35146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
36146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.ArrayList;
3713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Formatter;
38146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.Iterator;
39146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport java.util.LinkedList;
4013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chanimport java.util.Locale;
41146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
42146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectpublic class AgendaByDayAdapter extends BaseAdapter {
43146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int TYPE_DAY = 0;
44146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static final int TYPE_MEETING = 1;
4513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan    static final int TYPE_LAST = 2;
46146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
47146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private final Context mContext;
48146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private final AgendaAdapter mAgendaAdapter;
49146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private final LayoutInflater mInflater;
50146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private ArrayList<RowInfo> mRowInfo;
51146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private int mTodayJulianDay;
529a88873f9ec97b47aaaaae47208d22b3998b8e99Erik    private Time mTmpTime;
539a88873f9ec97b47aaaaae47208d22b3998b8e99Erik    private String mTimeZone;
5423f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan    // Note: Formatter is not thread safe. Fine for now as it is only used by the main thread.
5523f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan    private Formatter mFormatter;
5613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan    private StringBuilder mStringBuilder;
57146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
5813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan    static class ViewHolder {
59980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson        TextView dayView;
6013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        TextView dateView;
616467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson        int julianDay;
626467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson        boolean grayed;
6313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan    }
6413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan
659a88873f9ec97b47aaaaae47208d22b3998b8e99Erik    private Runnable mTZUpdater = new Runnable() {
669a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        @Override
679a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        public void run() {
689a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            mTimeZone = Utils.getTimeZone(mContext, this);
699a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            mTmpTime = new Time(mTimeZone);
709a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            notifyDataSetChanged();
719a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        }
729a88873f9ec97b47aaaaae47208d22b3998b8e99Erik    };
739a88873f9ec97b47aaaaae47208d22b3998b8e99Erik
7413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan    public AgendaByDayAdapter(Context context) {
75146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        mContext = context;
7613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        mAgendaAdapter = new AgendaAdapter(context, R.layout.agenda_item);
7713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
7813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        mStringBuilder = new StringBuilder(50);
7913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        mFormatter = new Formatter(mStringBuilder, Locale.getDefault());
809a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        mTimeZone = Utils.getTimeZone(context, mTZUpdater);
819a88873f9ec97b47aaaaae47208d22b3998b8e99Erik        mTmpTime = new Time(mTimeZone);
82146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
83146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
84c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson    public long getInstanceId(int position) {
85c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        if (mRowInfo == null || position >= mRowInfo.size()) {
86c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            return -1;
87c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        }
88c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        return mRowInfo.get(position).mInstanceId;
89c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson    }
9037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson
9137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson    // Returns the position of a header of a specific item
9237f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson    public int getHeaderPosition(int position) {
9337f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        if (mRowInfo == null || position >= mRowInfo.size()) {
9437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson            return -1;
9537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        }
9637f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson
9737f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        for (int i = position; i >=0; i --) {
9837f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson            RowInfo row = mRowInfo.get(i);
9937f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson            if (row != null && row.mType == TYPE_DAY)
10037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson                return i;
10137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        }
10237f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        return -1;
10337f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson    }
10437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson
10537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson    // Returns the number of items in a section defined by a specific header location
10637f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson    public int getHeaderItemsCount(int position) {
10737f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        if (mRowInfo == null) {
10837f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson            return -1;
10937f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        }
11037f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        int count = 0;
11137f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        for (int i = position +1; i < mRowInfo.size(); i++) {
11237f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson            if (mRowInfo.get(i).mType != TYPE_MEETING) {
11337f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson                return count;
11437f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson            }
11537f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson            count ++;
11637f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        }
11737f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson        return count;
11837f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson    }
11937f12e5cee7ed2d354e9366bd6d8e15d1a934f2aIsaac Katzenelson
120146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int getCount() {
121146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (mRowInfo != null) {
122146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return mRowInfo.size();
123146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
124146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return mAgendaAdapter.getCount();
125146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
126146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
127146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public Object getItem(int position) {
128146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (mRowInfo != null) {
129146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            RowInfo row = mRowInfo.get(position);
130146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (row.mType == TYPE_DAY) {
131146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                return row;
132146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            } else {
133980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson                return mAgendaAdapter.getItem(row.mPosition);
134146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
135146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
136146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return mAgendaAdapter.getItem(position);
137146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
138146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
139146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public long getItemId(int position) {
140146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (mRowInfo != null) {
141146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            RowInfo row = mRowInfo.get(position);
142146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (row.mType == TYPE_DAY) {
143c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan                return -position;
144146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            } else {
145980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson                return mAgendaAdapter.getItemId(row.mPosition);
146146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
147146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
148146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return mAgendaAdapter.getItemId(position);
149146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
150146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
151146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    @Override
152146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int getViewTypeCount() {
153146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return TYPE_LAST;
154146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
155146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
156146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    @Override
157146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int getItemViewType(int position) {
158146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return mRowInfo != null && mRowInfo.size() > position ?
159146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                mRowInfo.get(position).mType : TYPE_DAY;
160146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
161146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
1622d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson    public boolean isDayHeaderView(int position) {
1632d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        return (getItemViewType(position) == TYPE_DAY);
1642d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson    }
1652d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson
166146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public View getView(int position, View convertView, ViewGroup parent) {
167146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if ((mRowInfo == null) || (position > mRowInfo.size())) {
168146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // If we have no row info, mAgendaAdapter returns the view.
169146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return mAgendaAdapter.getView(position, convertView, parent);
170146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
171146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
172146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        RowInfo row = mRowInfo.get(position);
173146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (row.mType == TYPE_DAY) {
17413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            ViewHolder holder = null;
17513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            View agendaDayView = null;
17613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            if ((convertView != null) && (convertView.getTag() != null)) {
17713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                // Listview may get confused and pass in a different type of
17813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                // view since we keep shifting data around. Not a big problem.
17913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                Object tag = convertView.getTag();
18013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                if (tag instanceof ViewHolder) {
18113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                    agendaDayView = convertView;
18213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                    holder = (ViewHolder) tag;
1836467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson                    holder.julianDay = row.mDay;
18413850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                }
18513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            }
18613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan
18713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            if (holder == null) {
188146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                // Create a new AgendaView with a ViewHolder for fast access to
189146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                // views w/o calling findViewById()
190146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                holder = new ViewHolder();
191146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                agendaDayView = mInflater.inflate(R.layout.agenda_day, parent, false);
192980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson                holder.dayView = (TextView) agendaDayView.findViewById(R.id.day);
193146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                holder.dateView = (TextView) agendaDayView.findViewById(R.id.date);
1946467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson                holder.julianDay = row.mDay;
1956467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson                holder.grayed = false;
196146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                agendaDayView.setTag(holder);
197146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
198146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
1999a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            // Re-use the member variable "mTime" which is set to the local
2009a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            // time zone.
2019a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            // It's difficult to find and update all these adapters when the
2029a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            // home tz changes so check it here and update if needed.
2039a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            String tz = Utils.getTimeZone(mContext, mTZUpdater);
2049a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            if (!TextUtils.equals(tz, mTmpTime.timezone)) {
2059a88873f9ec97b47aaaaae47208d22b3998b8e99Erik                mTimeZone = tz;
2069a88873f9ec97b47aaaaae47208d22b3998b8e99Erik                mTmpTime = new Time(tz);
2079a88873f9ec97b47aaaaae47208d22b3998b8e99Erik            }
20813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan
209980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            // Build the text for the day of the week.
210980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            // Should be yesterday/today/tomorrow (if applicable) + day of the week
211980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson
212980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            Time date = mTmpTime;
213980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            long millis = date.setJulianDay(row.mDay);
214980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            int flags = DateUtils.FORMAT_SHOW_WEEKDAY;
21513850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            mStringBuilder.setLength(0);
216980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson
2174eb3432c5b0109376bcce9236da71e6fb4324b90RoboErik            String dayViewText = Utils.getDayOfWeekString(row.mDay, mTodayJulianDay, millis,
2184eb3432c5b0109376bcce9236da71e6fb4324b90RoboErik                    mContext);
219980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson
220980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            // Build text for the date
221980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            // Format should be month day
222980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson
223980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            mStringBuilder.setLength(0);
224980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            flags = DateUtils.FORMAT_SHOW_DATE;
225980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            String dateViewText = DateUtils.formatDateRange(mContext, mFormatter, millis, millis,
226980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson                    flags, mTimeZone).toString();
2273cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project
22823f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan            if (AgendaWindowAdapter.BASICLOG) {
229980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson                dayViewText += " P:" + position;
23023f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan                dateViewText += " P:" + position;
23123f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan            }
232980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            holder.dayView.setText(dayViewText);
23323f400cdb34b08d9003f4a96fca5976ad632e4ceMichael Chan            holder.dateView.setText(dateViewText);
2343cfe2e55d8c34849f99f4e8cb847e54076098b8fThe Android Open Source Project
23531412a0fea756e0da0bcbdf3cdffe4efae21cdbeIsaac Katzenelson            // Set the background of the view, it is grayed for day that are in the past and today
23631412a0fea756e0da0bcbdf3cdffe4efae21cdbeIsaac Katzenelson            if (row.mDay > mTodayJulianDay) {
237eedc9fc0631f3c8727df3c0e73474ebcdecd89feRoboErik                agendaDayView.setBackgroundResource(R.drawable.agenda_item_bg_primary);
2386467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson                holder.grayed = false;
239980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            } else {
240eedc9fc0631f3c8727df3c0e73474ebcdecd89feRoboErik                agendaDayView.setBackgroundResource(R.drawable.agenda_item_bg_secondary);
2416467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson                holder.grayed = true;
242980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            }
243146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return agendaDayView;
244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } else if (row.mType == TYPE_MEETING) {
245980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            View itemView = mAgendaAdapter.getView(row.mPosition, convertView, parent);
2464d09b91abf62994cf47ccdbf7e61f60b891f9f61Isaac Katzenelson            AgendaAdapter.ViewHolder holder = ((AgendaAdapter.ViewHolder) itemView.getTag());
2474d09b91abf62994cf47ccdbf7e61f60b891f9f61Isaac Katzenelson            TextView title = holder.title;
24831412a0fea756e0da0bcbdf3cdffe4efae21cdbeIsaac Katzenelson            long eventStartTime = holder.startTimeMilli;
2494d09b91abf62994cf47ccdbf7e61f60b891f9f61Isaac Katzenelson            boolean allDay = holder.allDay;
250c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan            if (AgendaWindowAdapter.BASICLOG) {
2512d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson                title.setText(title.getText() + " P:" + position);
252c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan            } else {
2532d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson                title.setText(title.getText());
254c79507e566895b023ef0eaf6e32cdc402372b7caMichael Chan            }
2552d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson
25631412a0fea756e0da0bcbdf3cdffe4efae21cdbeIsaac Katzenelson            // if event in the past or started already, un-bold the title and set the background
25731412a0fea756e0da0bcbdf3cdffe4efae21cdbeIsaac Katzenelson            if ((!allDay && eventStartTime <= System.currentTimeMillis()) ||
25831412a0fea756e0da0bcbdf3cdffe4efae21cdbeIsaac Katzenelson                    (allDay && row.mDay <= mTodayJulianDay)) {
259eedc9fc0631f3c8727df3c0e73474ebcdecd89feRoboErik                itemView.setBackgroundResource(R.drawable.agenda_item_bg_secondary);
2604d09b91abf62994cf47ccdbf7e61f60b891f9f61Isaac Katzenelson                title.setTypeface(Typeface.DEFAULT);
2616467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson                holder.grayed = true;
2624d09b91abf62994cf47ccdbf7e61f60b891f9f61Isaac Katzenelson            } else {
263eedc9fc0631f3c8727df3c0e73474ebcdecd89feRoboErik                itemView.setBackgroundResource(R.drawable.agenda_item_bg_primary);
2644d09b91abf62994cf47ccdbf7e61f60b891f9f61Isaac Katzenelson                title.setTypeface(Typeface.DEFAULT_BOLD);
2656467afce8cd7df7d013028462fa6ddf450238a43Isaac Katzenelson                holder.grayed = false;
266980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            }
26731412a0fea756e0da0bcbdf3cdffe4efae21cdbeIsaac Katzenelson            holder.julianDay = row.mDay;
268980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            return itemView;
269146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        } else {
270146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Error
271146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            throw new IllegalStateException("Unknown event type:" + row.mType);
272146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
273146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
274146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
275146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public void clearDayHeaderInfo() {
276146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        mRowInfo = null;
277146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
278146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
279dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan    public void changeCursor(DayAdapterInfo info) {
280dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan        calculateDays(info);
281dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan        mAgendaAdapter.changeCursor(info.cursor);
28213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan    }
28313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan
284dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan    public void calculateDays(DayAdapterInfo dayAdapterInfo) {
285dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan        Cursor cursor = dayAdapterInfo.cursor;
286146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        ArrayList<RowInfo> rowInfo = new ArrayList<RowInfo>();
287146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int prevStartDay = -1;
288c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
289c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        Time tempTime = new Time(mTimeZone);
290146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        long now = System.currentTimeMillis();
291c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        tempTime.set(now);
292c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        mTodayJulianDay = Time.getJulianDay(now, tempTime.gmtoff);
293c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
294146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        LinkedList<MultipleDayInfo> multipleDayList = new LinkedList<MultipleDayInfo>();
295146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (int position = 0; cursor.moveToNext(); position++) {
29613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            int startDay = cursor.getInt(AgendaWindowAdapter.INDEX_START_DAY);
297c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            long id = cursor.getLong(AgendaWindowAdapter.INDEX_EVENT_ID);
298c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            long startTime =  cursor.getLong(AgendaWindowAdapter.INDEX_BEGIN);
299c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            long endTime =  cursor.getLong(AgendaWindowAdapter.INDEX_END);
300c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            long instanceId = cursor.getLong(AgendaWindowAdapter.INDEX_INSTANCE_ID);
301c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            boolean allDay = cursor.getInt(AgendaWindowAdapter.INDEX_ALL_DAY) != 0;
302c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            if (allDay) {
303c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                startTime = Utils.convertAlldayUtcToLocal(tempTime, startTime, mTimeZone);
304c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                endTime = Utils.convertAlldayUtcToLocal(tempTime, endTime, mTimeZone);
305c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            }
306dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan            // Skip over the days outside of the adapter's range
307dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan            startDay = Math.max(startDay, dayAdapterInfo.start);
308e692869cbbc3d7430075bb739f0b0fa83cf91feaIsaac Katzenelson            // Make sure event's start time is not before the start of the day
309e692869cbbc3d7430075bb739f0b0fa83cf91feaIsaac Katzenelson            // (setJulianDay sets the time to 12:00am)
310e692869cbbc3d7430075bb739f0b0fa83cf91feaIsaac Katzenelson            long adapterStartTime = tempTime.setJulianDay(startDay);
311e692869cbbc3d7430075bb739f0b0fa83cf91feaIsaac Katzenelson            startTime = Math.max(startTime, adapterStartTime);
312dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan
313146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (startDay != prevStartDay) {
314146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                // Check if we skipped over any empty days
315146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                if (prevStartDay == -1) {
316c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    rowInfo.add(new RowInfo(TYPE_DAY, startDay));
317146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                } else {
318146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // If there are any multiple-day events that span the empty
319146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // range of days, then create day headers and events for
320146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // those multiple-day events.
321146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    boolean dayHeaderAdded = false;
322146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    for (int currentDay = prevStartDay + 1; currentDay <= startDay; currentDay++) {
323146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        dayHeaderAdded = false;
324146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        Iterator<MultipleDayInfo> iter = multipleDayList.iterator();
325146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        while (iter.hasNext()) {
326146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            MultipleDayInfo info = iter.next();
327146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            // If this event has ended then remove it from the
328146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            // list.
329146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            if (info.mEndDay < currentDay) {
330146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                                iter.remove();
331146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                                continue;
332146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            }
333146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
334146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            // If this is the first event for the day, then
335146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            // insert a day header.
336146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            if (!dayHeaderAdded) {
337c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                                rowInfo.add(new RowInfo(TYPE_DAY, currentDay));
338146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                                dayHeaderAdded = true;
339146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                            }
340b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson                            long nextMidnight = Utils.getNextMidnight(tempTime,
341b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson                                    info.mEventStartTimeMilli, mTimeZone);
342b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson
343b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson                            long infoEndTime = (info.mEndDay == currentDay) ?
344b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson                                    info.mEventEndTimeMilli : nextMidnight;
345c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                            rowInfo.add(new RowInfo(TYPE_MEETING, currentDay, info.mPosition,
346c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                                    info.mEventId, info.mEventStartTimeMilli,
347c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                                    infoEndTime, info.mInstanceId, info.mAllDay));
348c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
349b996adff74022fc78ff02c4f7e6149ea6342a7c6Isaac Katzenelson                            info.mEventStartTimeMilli = nextMidnight;
350146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        }
351146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    }
352146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
353146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // If the day header was not added for the start day, then
354146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // add it now.
355146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    if (!dayHeaderAdded) {
356c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        rowInfo.add(new RowInfo(TYPE_DAY, startDay));
357146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    }
358146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
359146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                prevStartDay = startDay;
360146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
361146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
362146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // Add in the event for this cursor position
363c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            rowInfo.add(new RowInfo(TYPE_MEETING, startDay, position, id, startTime, endTime,
364c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    instanceId, allDay));
365146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
366146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // If this event spans multiple days, then add it to the multipleDay
367146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            // list.
36813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            int endDay = cursor.getInt(AgendaWindowAdapter.INDEX_END_DAY);
369dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan
370dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan            // Skip over the days outside of the adapter's range
371dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan            endDay = Math.min(endDay, dayAdapterInfo.end);
372146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (endDay > startDay) {
373c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                multipleDayList.add(new MultipleDayInfo(position, endDay, id,
374c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        Utils.getNextMidnight(tempTime, startTime, mTimeZone),
375c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        endTime, instanceId, allDay));
376146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
377146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
378146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
379146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // There are no more cursor events but we might still have multiple-day
380146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // events left.  So create day headers and events for those.
381146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (prevStartDay > 0) {
382dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan            for (int currentDay = prevStartDay + 1; currentDay <= dayAdapterInfo.end;
383dad908b741d7d0a7e4a573030baeb74319ad9411Michael Chan                    currentDay++) {
384146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                boolean dayHeaderAdded = false;
385146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                Iterator<MultipleDayInfo> iter = multipleDayList.iterator();
386146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                while (iter.hasNext()) {
387146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    MultipleDayInfo info = iter.next();
388146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // If this event has ended then remove it from the
389146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // list.
390146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    if (info.mEndDay < currentDay) {
391146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        iter.remove();
392146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        continue;
393146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    }
394146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
395146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // If this is the first event for the day, then
396146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    // insert a day header.
397146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    if (!dayHeaderAdded) {
398c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        rowInfo.add(new RowInfo(TYPE_DAY, currentDay));
399146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                        dayHeaderAdded = true;
400146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    }
401c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    long nextMidnight = Utils.getNextMidnight(tempTime, info.mEventStartTimeMilli,
402c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                            mTimeZone);
403c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    long infoEndTime =
404c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                            (info.mEndDay == currentDay) ? info.mEventEndTimeMilli : nextMidnight;
405c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    rowInfo.add(new RowInfo(TYPE_MEETING, currentDay, info.mPosition,
406c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                            info.mEventId, info.mEventStartTimeMilli, infoEndTime,
407c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                            info.mInstanceId, info.mAllDay));
408c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
409c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    info.mEventStartTimeMilli = nextMidnight;
410146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
411146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
412146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
413146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        mRowInfo = rowInfo;
414146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
415146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
416146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static class RowInfo {
417146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        // mType is either a day header (TYPE_DAY) or an event (TYPE_MEETING)
418146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        final int mType;
419146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
420980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson        final int mDay;          // Julian day
421980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson        final int mPosition;     // cursor position (not used for TYPE_DAY)
4222d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        // This is used to mark a day header as the first day with events that is "today"
4232d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        // or later. This flag is used by the adapter to create a view with a visual separator
4242d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        // between the past and the present/future
4252d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        boolean mFirstDayAfterYesterday;
426c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        final long mEventId;
427c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        final long mEventStartTimeMilli;
428c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        final long mEventEndTimeMilli;
429c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        final long mInstanceId;
430c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        final boolean mAllDay;
431c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
432c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        RowInfo(int type, int julianDay, int position, long id, long startTime, long endTime,
433c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                long instanceId, boolean allDay) {
434146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            mType = type;
435980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            mDay = julianDay;
436980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson            mPosition = position;
437c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventId = id;
438c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventStartTimeMilli = startTime;
439c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventEndTimeMilli = endTime;
4402d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson            mFirstDayAfterYesterday = false;
441c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mInstanceId = instanceId;
442c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mAllDay = allDay;
443c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        }
444c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
445c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        RowInfo(int type, int julianDay) {
446c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mType = type;
447c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mDay = julianDay;
448c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mPosition = 0;
449c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventId = 0;
450c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventStartTimeMilli = 0;
451c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventEndTimeMilli = 0;
452c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mFirstDayAfterYesterday = false;
453c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mInstanceId = -1;
454c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mAllDay = false;
455146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
456146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
457146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
458146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    private static class MultipleDayInfo {
459146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        final int mPosition;
460146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        final int mEndDay;
461c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        final long mEventId;
462c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        long mEventStartTimeMilli;
463c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        long mEventEndTimeMilli;
464c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        final long mInstanceId;
465c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        final boolean mAllDay;
466c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
467c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        MultipleDayInfo(int position, int endDay, long id, long startTime, long endTime,
468c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                long instanceId, boolean allDay) {
469146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            mPosition = position;
470146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            mEndDay = endDay;
471c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventId = id;
472c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventStartTimeMilli = startTime;
473c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mEventEndTimeMilli = endTime;
474c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mInstanceId = instanceId;
475c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            mAllDay = allDay;
476146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
477146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
478146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
479146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
480c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     * Finds the position in the cursor of the event that best matches the time and Id.
481c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     * It will try to find the event that has the specified id and start time, if such event
482c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     * doesn't exist, it will return the event with a matching id that is closest to the start time.
483c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     * If the id doesn't exist, it will return the event with start time closest to the specified
484c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     * time.
485c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     * @param time - start of event in milliseconds (or any arbitrary time if event id is unknown)
486c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     * @param id - Event id (-1 if unknown).
487c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     * @return Position of event (if found) or position of nearest event according to the time.
488c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     *         Zero if no event found
489146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
490c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson    public int findEventPositionNearestTime(Time time, long id) {
491146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (mRowInfo == null) {
492146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return 0;
493146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
494146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        long millis = time.toMillis(false /* use isDst */);
495c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        long minDistance =  Integer.MAX_VALUE;  // some big number
496c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        long IdFoundMinDistance =  Integer.MAX_VALUE;  // some big number
497146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int minIndex = 0;
498c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        int idFoundMinIndex = 0;
499c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        int eventInTimeIndex = -1;
500c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        int allDayEventInTimeIndex = -1;
501c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        int allDayEventDay = 0;
502c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        int minDay = 0;
503c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        boolean idFound = false;
504146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int len = mRowInfo.size();
505c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
506c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        // Loop through the events and find the best match
507c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        // 1. Event id and start time matches requested id and time
508c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        // 2. Event id matches and closest time
509812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson        // 3. No event id match , time matches a all day event (midnight)
510812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson        // 4. No event id match , time is between event start and end
511812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson        // 5. No event id match , all day event
512812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson        // 6. The closest event to the requested time
513c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
514146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (int index = 0; index < len; index++) {
515146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            RowInfo row = mRowInfo.get(index);
516146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (row.mType == TYPE_DAY) {
517c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                continue;
518c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            }
519c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
520c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            // Found exact match - done
521c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            if (row.mEventId == id) {
522c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                if (row.mEventStartTimeMilli == millis) {
523146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                    return index;
524146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
525c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
526c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                // Not an exact match, Save event index if it is the closest to time so far
527c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                long distance = Math.abs(millis - row.mEventStartTimeMilli);
528146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                if (distance < minDistance) {
529c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    IdFoundMinDistance = distance;
530c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    idFoundMinIndex = index;
531c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                }
532c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                idFound = true;
533c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            }
534c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            if (!idFound) {
535c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                // Found an event that contains the requested time
536c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                if (millis >= row.mEventStartTimeMilli && millis <= row.mEventEndTimeMilli) {
537c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    if (row.mAllDay) {
538812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson                        if (millis == row.mEventStartTimeMilli) {
539812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson                            return index;
540812da1baf2eaf2951dbd849bed1b365bd2581609Isaac Katzenelson                        }
541c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        allDayEventInTimeIndex = index;
542c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        allDayEventDay = row.mDay;
543c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    } else {
544c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        eventInTimeIndex = index;
545c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    }
546c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                } else {
547c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    // Save event index if it is the closest to time so far
548c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    long distance = Math.abs(millis - row.mEventStartTimeMilli);
549c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    if (distance < minDistance) {
550c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        minDistance = distance;
551c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        minIndex = index;
552c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                        minDay = row.mDay;
553c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson                    }
554146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project                }
555146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
556146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
557c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        // We didn't find an exact match so take the best matching event
558c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        if (idFound) {
559c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            return idFoundMinIndex;
560c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        }
561c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        if (eventInTimeIndex != -1) {
562c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            return eventInTimeIndex;
563c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        } else if (allDayEventInTimeIndex != -1 && minDay != allDayEventDay) {
564c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson            return allDayEventInTimeIndex;
565c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson        }
566146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return minIndex;
567146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
568146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
569c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson
570146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
5712d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     * Returns a flag indicating if this position is the first day after "yesterday" that has
5722d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     * events in it.
5732d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     *
5742d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     * @return a flag indicating if this is the "first day after yesterday"
5752d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     */
5762d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson    public boolean isFirstDayAfterYesterday(int position) {
5772d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        int headerPos = getHeaderPosition(position);
5782d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        RowInfo row = mRowInfo.get(headerPos);
5792d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        if (row != null) {
5802d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson            return row.mFirstDayAfterYesterday;
5812d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        }
5822d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        return false;
5832d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson    }
5842d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson
5852d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson    /**
586146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Finds the Julian day containing the event at the given position.
587146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *
588146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @param position the list position of an event
589146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @return the Julian day containing that event
590146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
591146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int findJulianDayFromPosition(int position) {
592146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (mRowInfo == null || position < 0) {
593146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return 0;
594146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
595146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
596146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        int len = mRowInfo.size();
597146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (position >= len) return 0;  // no row info at this position
598146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
599146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        for (int index = position; index >= 0; index--) {
600146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            RowInfo row = mRowInfo.get(index);
601146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (row.mType == TYPE_DAY) {
602980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson                return row.mDay;
603146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
604146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
605146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return 0;
606146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
607146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
608146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    /**
6092d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     * Marks the current row as the first day that has events after "yesterday".
6102d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     * Used to mark the separation between the past and the present/future
6112d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     *
6122d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     * @param position in the adapter
6132d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson     */
6142d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson    public void setAsFirstDayAfterYesterday(int position) {
6152d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        if (mRowInfo == null || position < 0 || position > mRowInfo.size()) {
6162d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson            return;
6172d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        }
6182d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        RowInfo row = mRowInfo.get(position);
6192d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson        row.mFirstDayAfterYesterday = true;
6202d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson    }
6212d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson
6222d49da2fe5626ee6e3610dc8df23e16e768bc61fIsaac Katzenelson    /**
623146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * Converts a list position to a cursor position.  The list contains
624146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * day headers as well as events.  The cursor contains only events.
625146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     *
626146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @param listPos the list position of an event
627146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     * @return the corresponding cursor position of that event
628c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     *         if the position point to day header , it will give the position of the next event
629c1fae4df6202ac82c3facd76e5f33c7cbacb39d1Isaac Katzenelson     *         negated.
630146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project     */
631146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public int getCursorPosition(int listPos) {
632146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (mRowInfo != null && listPos >= 0) {
633146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            RowInfo row = mRowInfo.get(listPos);
634146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            if (row.mType == TYPE_MEETING) {
635980d530f002b335916e8b31662e50a94b43cae18Isaac Katzenelson                return row.mPosition;
63613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan            } else {
63713850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                int nextPos = listPos + 1;
63813850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                if (nextPos < mRowInfo.size()) {
63913850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                    nextPos = getCursorPosition(nextPos);
64013850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                    if (nextPos >= 0) {
64113850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                        return -nextPos;
64213850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                    }
64313850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan                }
644146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            }
645146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
64613850936e579386a0f2ee589607bbf8b7cf1a7d4Michael Chan        return Integer.MIN_VALUE;
647146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
648146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
649146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    @Override
650146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public boolean areAllItemsEnabled() {
651146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return false;
652146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
653146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project
654146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    @Override
655146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    public boolean isEnabled(int position) {
656146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        if (mRowInfo != null && position < mRowInfo.size()) {
657146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            RowInfo row = mRowInfo.get(position);
658146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project            return row.mType == TYPE_MEETING;
659146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        }
660146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project        return true;
661146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project    }
662146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project}
663