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
17package com.replica.replicaisland;
18
19import java.util.ArrayList;
20
21import org.xmlpull.v1.XmlPullParser;
22
23import android.content.Context;
24import android.content.res.XmlResourceParser;
25
26public final class LevelTree {
27	public static class LevelGroup {
28		public ArrayList<Level> levels = new ArrayList<Level>();
29	}
30
31    public static class Level {
32    	public int resource;
33        public DialogEntry dialogResources;
34        public String name;
35        public String timeStamp;
36        public boolean completed;
37        public boolean inThePast;
38        public boolean diaryCollected;
39        public boolean restartable;
40        public boolean showWaitMessage;
41
42        public Level(int level, DialogEntry dialogs, String title, String time,
43        		boolean pastEvent, boolean restartOnDeath, boolean waitMessage) {
44            resource = level;
45            dialogResources = dialogs;
46            name = title;
47            timeStamp = time;
48            completed = false;
49            inThePast = pastEvent;
50            diaryCollected = false;
51            restartable = restartOnDeath;
52            showWaitMessage = waitMessage;
53        }
54
55    }
56
57    public static class DialogEntry {
58        public int diaryEntry = 0;
59        public int character1Entry = 0;
60        public int character2Entry = 0;
61        public ArrayList<ConversationUtils.Conversation> character1Conversations;
62        public ArrayList<ConversationUtils.Conversation> character2Conversations;
63    }
64    public final static ArrayList<LevelGroup> levels = new ArrayList<LevelGroup>();
65    private static boolean mLoaded = false;
66    private static int mLoadedResource = 0;
67
68    public static final Level get(int row, int index) {
69    	return levels.get(row).levels.get(index);
70    }
71
72    public static final boolean isLoaded(int resource) {
73    	return mLoaded && mLoadedResource == resource;
74    }
75
76    public static final void loadLevelTree(int resource, Context context) {
77        if (levels.size() > 0 && mLoadedResource == resource) {
78        	// already loaded
79        	return;
80        }
81
82    	XmlResourceParser parser = context.getResources().getXml(resource);
83
84        levels.clear();
85
86        LevelGroup currentGroup = null;
87        Level currentLevel = null;
88        DialogEntry currentDialog = null;
89
90        try {
91            int eventType = parser.getEventType();
92            while (eventType != XmlPullParser.END_DOCUMENT) {
93                if(eventType == XmlPullParser.START_TAG) {
94                	if (parser.getName().equals("group")) {
95                		currentGroup = new LevelGroup();
96                		levels.add(currentGroup);
97                		currentLevel = null;
98                		currentDialog = null;
99                	}
100
101                    if (parser.getName().equals("level") && currentGroup != null) {
102                    	int levelResource = 0;
103                    	String titleString = null;
104                    	String timeStamp = null;
105                    	boolean inThePast = false;
106                    	boolean restartable = true;
107                    	boolean showWaitMessage = false;
108                        for(int i=0; i < parser.getAttributeCount(); i++) {
109                    		if (parser.getAttributeName(i).equals("past")) {
110                    			if (parser.getAttributeValue(i).equals("true")) {
111                    				inThePast = true;
112                    			}
113                    		} else if (parser.getAttributeName(i).equals("restartable")) {
114                    			if (parser.getAttributeValue(i).equals("false")) {
115                    				restartable = false;
116                    			}
117                    		} else if (parser.getAttributeName(i).equals("waitmessage")) {
118                    			if (parser.getAttributeValue(i).equals("true")) {
119                    				showWaitMessage = true;
120                    			}
121                    		} else {
122                                final int value = parser.getAttributeResourceValue(i, -1);
123                                if (value != -1) {
124                                    if (parser.getAttributeName(i).equals("resource")) {
125                                        levelResource = value;
126                                    }
127                                    if (parser.getAttributeName(i).equals("title")) {
128                                        titleString = context.getString(value);
129                                    } else if (parser.getAttributeName(i).equals("time")) {
130                                        timeStamp = context.getString(value);
131                                    }
132                                }
133                    		}
134
135                        }
136                        currentDialog = null;
137                        currentLevel = new Level(levelResource, null, titleString, timeStamp, inThePast, restartable, showWaitMessage);
138                        currentGroup.levels.add(currentLevel);
139                    }
140
141                    if (parser.getName().equals("dialog") && currentLevel != null) {
142                    	currentDialog = new DialogEntry();
143                    	currentLevel.dialogResources = currentDialog;
144                    }
145
146                    if (parser.getName().equals("diary") && currentDialog != null) {
147
148                    	for(int i=0; i < parser.getAttributeCount(); i++) {
149                            final int value = parser.getAttributeResourceValue(i, -1);
150                            if (value != -1) {
151                                if (parser.getAttributeName(i).equals("resource")) {
152                                	currentDialog.diaryEntry = value;
153                                }
154
155                            }
156                    	}
157                    }
158
159                    if (parser.getName().equals("character1") && currentDialog != null) {
160                    	for(int i=0; i < parser.getAttributeCount(); i++) {
161                            final int value = parser.getAttributeResourceValue(i, -1);
162                            if (value != -1) {
163                                if (parser.getAttributeName(i).equals("resource")) {
164                                	currentDialog.character1Entry = value;
165                                }
166
167                            }
168                    	}
169                    }
170
171                    if (parser.getName().equals("character2") && currentDialog != null) {
172
173                    	for(int i=0; i < parser.getAttributeCount(); i++) {
174                            final int value = parser.getAttributeResourceValue(i, -1);
175                            if (value != -1) {
176                                if (parser.getAttributeName(i).equals("resource")) {
177                                	currentDialog.character2Entry = value;
178                                }
179
180                            }
181                    	}
182                    }
183
184                }
185                eventType = parser.next();
186            }
187        } catch(Exception e) {
188                DebugLog.e("LevelTree", e.getStackTrace().toString());
189        } finally {
190            parser.close();
191        }
192        mLoaded = true;
193        mLoadedResource = resource;
194    }
195
196    public final static void loadAllDialog(Context context) {
197    	final int levelGroupCount = levels.size();
198    	for (int x = 0; x < levelGroupCount; x++) {
199    		final ArrayList<Level> row = levels.get(x).levels;
200    		final int levelCount = row.size();
201    		for (int y = 0; y < levelCount; y++) {
202    			final Level level = row.get(y);
203    			if (level != null && level.dialogResources != null) {
204    				DialogEntry dialog = level.dialogResources;
205    				if (dialog.character1Entry != 0) {
206    					dialog.character1Conversations = ConversationUtils.loadDialog(dialog.character1Entry, context);
207    				}
208
209    				if (dialog.character2Entry != 0) {
210    					dialog.character2Conversations = ConversationUtils.loadDialog(dialog.character2Entry, context);
211    				}
212    			}
213    		}
214
215    	}
216    }
217
218	public final static void updateCompletedState(int levelRow, int completedLevels) {
219		final int rowCount = levels.size();
220		for (int x = 0; x < rowCount; x++) {
221			final LevelGroup group = levels.get(x);
222			final int levelCount = group.levels.size();
223			for (int y = 0; y < levelCount; y++) {
224				final Level level = group.levels.get(y);
225				if (x < levelRow) {
226					level.completed = true;
227				} else if (x == levelRow) {
228					if ((completedLevels & (1 << y)) != 0) {
229						level.completed = true;
230					}
231				} else {
232					level.completed = false;
233				}
234			}
235		}
236
237	}
238
239	public final static int packCompletedLevels(int levelRow) {
240		int completed = 0;
241		final LevelGroup group = levels.get(levelRow);
242		final int levelCount = group.levels.size();
243		for (int y = 0; y < levelCount; y++) {
244			final Level level = group.levels.get(y);
245			if (level.completed) {
246				completed |= 1 << y;
247			}
248		}
249		return completed;
250	}
251
252	public static boolean levelIsValid(int row, int index) {
253		boolean valid = false;
254		if (row >= 0 && row < levels.size()) {
255			final LevelGroup group = levels.get(row);
256			if (index >=0 && index < group.levels.size()) {
257				valid = true;
258			}
259		}
260
261		return valid;
262	}
263
264	public static boolean rowIsValid(int row) {
265		boolean valid = false;
266		if (row >= 0 && row < levels.size()) {
267			valid = true;
268		}
269
270		return valid;
271	}
272
273}
274