blob: b9c49e78e368d737e60831c15965aed7d5e61bfc [file] [log] [blame]
sm0a9f4cfd74d62010-03-18 09:32:06 +00001/*
sm0a9f43c1e67e2010-04-02 17:29:14 +00002 * Copyright (C) 2010 The Android Open Source Project
sm0a9f4cfd74d62010-03-18 09:32:06 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.replica.replicaisland;
18
19import android.app.ListActivity;
20import android.content.Context;
21import android.content.Intent;
22import android.media.AudioManager;
23import android.os.Bundle;
24import android.view.KeyEvent;
25import android.view.LayoutInflater;
26import android.view.Menu;
27import android.view.MenuItem;
28import android.view.View;
29import android.view.ViewGroup;
30import android.view.animation.Animation;
31import android.view.animation.AnimationUtils;
32import android.widget.ArrayAdapter;
33import android.widget.ListView;
34import android.widget.TextView;
35
sm0a9f4@gmail.com2b1168a2011-01-16 07:13:43 +000036import java.lang.reflect.InvocationTargetException;
sm0a9f4cfd74d62010-03-18 09:32:06 +000037import java.util.ArrayList;
38import java.util.Comparator;
39import java.util.List;
40
41public class LevelSelectActivity extends ListActivity {
42 private final static int UNLOCK_ALL_LEVELS_ID = 0;
43 private final static int UNLOCK_NEXT_LEVEL_ID = 1;
44 private final static LevelDataComparator sLevelComparator = new LevelDataComparator();
45 private ArrayList<LevelMetaData> mLevelData;
46 private Animation mButtonFlickerAnimation;
47 private boolean mLevelSelected;
48
49 private class LevelMetaData {
50 public LevelTree.Level level;
51 public int x;
52 public int y;
53 boolean enabled;
54
55 @Override
56 public String toString() {
57 return level.name;
58 }
59 }
60
61 private class DisableItemArrayAdapter<T> extends ArrayAdapter<T> {
62 private static final int TYPE_ENABLED = 0;
63 private static final int TYPE_DISABLED = 1;
64 private static final int TYPE_COMPLETED = 2;
65 private static final int TYPE_COUNT = 3;
66
67 private int mRowResource;
68 private int mDisabledRowResource;
69 private int mCompletedRowResource;
70 private Context mContext;
71 private int mTextViewResource;
72 private int mTextViewResource2;
73
74 public DisableItemArrayAdapter(Context context, int resource, int disabledResource, int completedResource,
75 int textViewResourceId, int textViewResourceId2, List<T> objects) {
76 super(context, resource, textViewResourceId, objects);
77 mRowResource = resource;
78 mDisabledRowResource = disabledResource;
79 mCompletedRowResource = completedResource;
80 mContext = context;
81 mTextViewResource = textViewResourceId;
82 mTextViewResource2 = textViewResourceId2;
83 }
84
85 @Override
86 public boolean isEnabled(int position) {
87 // TODO: do we have separators in this list?
88 return mLevelData.get(position).enabled;
89 }
90
91
92 @Override
93 public boolean areAllItemsEnabled() {
94 return false;
95 }
96
97 @Override
98 public int getItemViewType(int position) {
99 int type = TYPE_ENABLED;
100 LevelMetaData level = mLevelData.get(position);
101 if (level != null) {
102 if (!level.enabled) {
103 if (level.level.completed) {
104 type = TYPE_COMPLETED;
105 } else {
106 type = TYPE_DISABLED;
107 }
108 }
109 }
110 return type;
111 }
112
113 @Override
114 public int getViewTypeCount() {
115 return TYPE_COUNT;
116 }
117
118 @Override
119 public boolean hasStableIds() {
120 return true;
121 }
122
123 @Override
124 public boolean isEmpty() {
125 return mLevelData.size() > 0;
126 }
127
128 @Override
129 public View getView (int position, View convertView, ViewGroup parent) {
130 View sourceView = null;
131 if (mLevelData.get(position).enabled) {
132 if (convertView != null && convertView.getId() == mRowResource) {
133 sourceView = convertView;
134 } else {
135 sourceView = LayoutInflater.from(mContext).inflate(
136 mRowResource, parent, false);
137 }
138 } else if (mLevelData.get(position).level.completed) {
139 if (convertView != null && convertView.getId() == mCompletedRowResource) {
140 sourceView = convertView;
141 } else {
142 sourceView = LayoutInflater.from(mContext).inflate(
143 mCompletedRowResource, parent, false);
144 }
145 } else {
146 if (convertView != null && convertView.getId() == mDisabledRowResource) {
147 sourceView = convertView;
148 } else {
149 sourceView = LayoutInflater.from(mContext).inflate(
150 mDisabledRowResource, parent, false);
151 }
152 }
153 TextView view = (TextView)sourceView.findViewById(mTextViewResource);
154 if (view != null) {
155 view.setText(mLevelData.get(position).level.name);
156 }
157
158 TextView view2 = (TextView)sourceView.findViewById(mTextViewResource2);
159 if (view2 != null) {
160 view2.setText(mLevelData.get(position).level.timeStamp);
161 }
162 return sourceView;
163 }
164
165 }
166
167 /** Called when the activity is first created. */
168 @Override
169 public void onCreate(Bundle savedInstanceState) {
170 super.onCreate(savedInstanceState);
171 setContentView(R.layout.level_select);
172 mLevelData = new ArrayList<LevelMetaData>();
173
sm0a9f4@gmail.com2b1168a2011-01-16 07:13:43 +0000174 if (getIntent().getBooleanExtra("unlockAll", false)) {
175 generateLevelList(false);
176 for (LevelMetaData level : mLevelData) {
177 level.enabled = true;
178 }
179 } else {
180 generateLevelList(true);
181 }
182
sm0a9f4cfd74d62010-03-18 09:32:06 +0000183
184 DisableItemArrayAdapter<LevelMetaData> adapter = new DisableItemArrayAdapter<LevelMetaData>(
185 this, R.layout.level_select_row, R.layout.level_select_disabled_row, R.layout.level_select_completed_row,
186 R.id.title, R.id.time, mLevelData);
187
188 adapter.sort(sLevelComparator);
189
190 setListAdapter(adapter);
191
192 mButtonFlickerAnimation = AnimationUtils.loadAnimation(this, R.anim.button_flicker);
193
194 mLevelSelected = false;
195
196 // Keep the volume control type consistent across all activities.
197 setVolumeControlStream(AudioManager.STREAM_MUSIC);
198 }
199
200 protected void generateLevelList(boolean onlyAllowThePast) {
201 final int count = LevelTree.levels.size();
202 boolean oneBranchUnlocked = false;
203 for (int x = 0; x < count; x++) {
204 boolean anyUnlocksThisBranch = false;
205 final LevelTree.LevelGroup group = LevelTree.levels.get(x);
206 for (int y = 0; y < group.levels.size(); y++) {
207 LevelTree.Level level = group.levels.get(y);
208 boolean enabled = false;
209 if (!level.completed && !oneBranchUnlocked) {
210 enabled = true;
211 anyUnlocksThisBranch = true;
212 }
213 if (enabled || level.completed || !onlyAllowThePast || (onlyAllowThePast && level.inThePast)) {
214 addItem(level, x, y, enabled);
215 }
216 }
217 if (anyUnlocksThisBranch) {
218 oneBranchUnlocked = true;
219 }
220 }
221 }
222
223 protected void unlockNext() {
224 final int count = LevelTree.levels.size();
225 for (int x = 0; x < count; x++) {
226 final LevelTree.LevelGroup group = LevelTree.levels.get(x);
227 for (int y = 0; y < group.levels.size(); y++) {
228 LevelTree.Level level = group.levels.get(y);
229 if (!level.completed) {
230 level.completed = true;
231 return;
232 }
233 }
234
235 }
236 }
237
238
239 @Override
240 protected void onListItemClick(ListView l, View v, int position, long id) {
241 if (!mLevelSelected) {
242 super.onListItemClick(l, v, position, id);
243 LevelMetaData selectedLevel = mLevelData.get(position);
244 if (selectedLevel.enabled) {
245 mLevelSelected = true;
246 Intent intent = new Intent();
247
248 intent.putExtra("resource", selectedLevel.level.resource);
249 intent.putExtra("row", selectedLevel.x);
250 intent.putExtra("index", selectedLevel.y);
251 TextView text = (TextView)v.findViewById(R.id.title);
252 if (text != null) {
253 text.startAnimation(mButtonFlickerAnimation);
254 mButtonFlickerAnimation.setAnimationListener(new EndActivityAfterAnimation(intent));
255 } else {
256 setResult(RESULT_OK, intent);
257 finish();
sm0a9f4@gmail.com2b1168a2011-01-16 07:13:43 +0000258 if (UIConstants.mOverridePendingTransition != null) {
259 try {
260 UIConstants.mOverridePendingTransition.invoke(LevelSelectActivity.this, R.anim.activity_fade_in, R.anim.activity_fade_out);
261 } catch (InvocationTargetException ite) {
262 DebugLog.d("Activity Transition", "Invocation Target Exception");
263 } catch (IllegalAccessException ie) {
264 DebugLog.d("Activity Transition", "Illegal Access Exception");
265 }
266 }
sm0a9f4cfd74d62010-03-18 09:32:06 +0000267 }
268 }
269 }
270 }
271
272 private void addItem(LevelTree.Level level, int x, int y, boolean enabled) {
273 LevelMetaData data = new LevelMetaData();
274 data.level = level;
275 data.x = x;
276 data.y = y;
277 data.enabled = enabled;
278 mLevelData.add(data);
279 }
280
281 @Override
282 public boolean onCreateOptionsMenu(Menu menu) {
283 super.onCreateOptionsMenu(menu);
284 boolean handled = false;
285 if (AndouKun.VERSION < 0) {
286 menu.add(0, UNLOCK_NEXT_LEVEL_ID, 0, R.string.unlock_next_level);
287 menu.add(0, UNLOCK_ALL_LEVELS_ID, 0, R.string.unlock_levels);
288
289 handled = true;
290 }
291 return handled;
292 }
293
294 @Override
295 public boolean onMenuItemSelected(int featureId, MenuItem item) {
296 switch(item.getItemId()) {
297 case UNLOCK_NEXT_LEVEL_ID:
298 unlockNext();
299 mLevelData.clear();
300 generateLevelList(false);
301 ((ArrayAdapter)getListAdapter()).sort(sLevelComparator);
302 ((ArrayAdapter)getListAdapter()).notifyDataSetChanged();
303
304 return true;
305
306 case UNLOCK_ALL_LEVELS_ID:
307 // Regenerate the level list to remove the past-only filter.
308 mLevelData.clear();
309 generateLevelList(false);
310 for (LevelMetaData level : mLevelData) {
311 level.enabled = true;
312 }
313
314 ((ArrayAdapter)getListAdapter()).sort(sLevelComparator);
315 ((ArrayAdapter)getListAdapter()).notifyDataSetChanged();
316 return true;
317 }
318
319 return super.onMenuItemSelected(featureId, item);
320 }
321
322
323 @Override
324 public boolean onKeyDown(int keyCode, KeyEvent event) {
325 boolean result = false;
326 if (keyCode == KeyEvent.KEYCODE_BACK) {
327 result = true;
328 }
329 return result;
330 }
331
332 @Override
333 public boolean onKeyUp(int keyCode, KeyEvent event) {
334 boolean result = false;
335 if (keyCode == KeyEvent.KEYCODE_BACK) {
336 result = true;
337 }
338 return result;
339 }
340
341
342 /** Comparator for level meta data. */
343 private final static class LevelDataComparator implements Comparator<LevelMetaData> {
344 public int compare(final LevelMetaData object1, final LevelMetaData object2) {
345 int result = 0;
346 if (object1 == null && object2 != null) {
347 result = 1;
348 } else if (object1 != null && object2 == null) {
349 result = -1;
350 } else if (object1 != null && object2 != null) {
351 result = object1.level.timeStamp.compareTo(object2.level.timeStamp);
352 }
353 return result;
354 }
355 }
356
357 protected class EndActivityAfterAnimation implements Animation.AnimationListener {
358 private Intent mIntent;
359
360 EndActivityAfterAnimation(Intent intent) {
361 mIntent = intent;
362 }
363
364
365 public void onAnimationEnd(Animation animation) {
366 setResult(RESULT_OK, mIntent);
367 finish();
368 }
369
370 public void onAnimationRepeat(Animation animation) {
371 // TODO Auto-generated method stub
372
373 }
374
375 public void onAnimationStart(Animation animation) {
376 // TODO Auto-generated method stub
377
378 }
379
380 }
381}
382