Home | History | Annotate | Download | only in replicaisland
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      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 
     17 package com.replica.replicaisland;
     18 
     19 import android.app.ListActivity;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.media.AudioManager;
     23 import android.os.Bundle;
     24 import android.view.KeyEvent;
     25 import android.view.LayoutInflater;
     26 import android.view.Menu;
     27 import android.view.MenuItem;
     28 import android.view.View;
     29 import android.view.ViewGroup;
     30 import android.view.animation.Animation;
     31 import android.view.animation.AnimationUtils;
     32 import android.widget.ArrayAdapter;
     33 import android.widget.ListView;
     34 import android.widget.TextView;
     35 
     36 import java.lang.reflect.InvocationTargetException;
     37 import java.util.ArrayList;
     38 import java.util.Comparator;
     39 import java.util.List;
     40 
     41 public 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 
    174         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 
    183 
    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();
    258 	            	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 		            }
    267 	            }
    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 
    383