ConversationDialogActivity.java revision cfd74d65d832137e20e193c960802afba73b5d38
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/*
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Copyright (C) 2008 The Android Open Source Project
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * you may not use this file except in compliance with the License.
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * You may obtain a copy of the License at
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * See the License for the specific language governing permissions and
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * limitations under the License.
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)package com.replica.replicaisland;
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import java.util.ArrayList;
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.app.Activity;
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.content.Context;
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.content.Intent;
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.graphics.Canvas;
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.graphics.Paint;
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.graphics.drawable.AnimationDrawable;
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.os.Bundle;
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.os.SystemClock;
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.text.SpannableStringBuilder;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.text.TextUtils;
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.util.AttributeSet;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.view.MotionEvent;
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.view.View;
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.widget.ImageView;
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import android.widget.TextView;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import com.replica.replicaisland.ConversationUtils.Conversation;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import com.replica.replicaisland.ConversationUtils.ConversationPage;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)public class ConversationDialogActivity extends Activity {
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private final static float TEXT_CHARACTER_DELAY = 0.1f;
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private final static int TEXT_CHARACTER_DELAY_MS = (int)(TEXT_CHARACTER_DELAY * 1000);
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private ConversationUtils.Conversation mConversation;
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private ArrayList<ConversationUtils.ConversationPage> mPages;
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private int mCurrentPage;
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private ImageView mOkArrow;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private AnimationDrawable mOkAnimation;
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    @Override
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    protected void onCreate(Bundle savedInstanceState) {
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        super.onCreate(savedInstanceState);
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        setContentView(R.layout.conversation_dialog);
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mOkArrow = (ImageView)findViewById(R.id.ok);
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mOkArrow.setBackgroundResource(R.anim.ui_button);
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		mOkAnimation = (AnimationDrawable) mOkArrow.getBackground();
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		mOkArrow.setVisibility(View.INVISIBLE);
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        final Intent callingIntent = getIntent();
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        final int levelRow = callingIntent.getIntExtra("levelRow", -1);
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        final int levelIndex = callingIntent.getIntExtra("levelIndex", -1);
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        final int index = callingIntent.getIntExtra("index", -1);
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        final int character = callingIntent.getIntExtra("character", 1);
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mPages = null;
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        // LevelTree.get(mLevelRow, mLevelIndex).dialogResources.character2Entry.get(index)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (levelRow != -1 && levelIndex != -1 && index != -1) {
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	if (character == 1) {
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        		mConversation = LevelTree.get(levelRow, levelIndex).dialogResources.character1Conversations.get(index);
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	} else {
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        		mConversation = LevelTree.get(levelRow, levelIndex).dialogResources.character2Conversations.get(index);
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	}
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	TypewriterTextView tv = (TypewriterTextView)findViewById(R.id.typewritertext);
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	tv.setParentActivity(this);
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        } else {
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	// bail
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	finish();
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private void formatPages(Conversation conversation, TextView textView) {
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		Paint paint = new Paint();
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        final int maxWidth = textView.getWidth();
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        final int maxHeight = textView.getHeight();
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        paint.setTextSize(textView.getTextSize());
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        paint.setTypeface(textView.getTypeface());
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        for (int page = conversation.pages.size() - 1; page >= 0 ; page--) {
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	ConversationUtils.ConversationPage currentPage = conversation.pages.get(page);
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	CharSequence text = currentPage.text;
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	// Iterate line by line through the text.  Add \n if it gets too wide,
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	// and split into a new page if it gets too long.
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	int currentOffset = 0;
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	int textLength = text.length();
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	SpannableStringBuilder spannedText = new SpannableStringBuilder(text);
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	int lineCount = 0;
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	final float fontHeight = -paint.ascent() + paint.descent();
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	final int maxLinesPerPage = (int)(maxHeight / fontHeight);
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	CharSequence newline = "\n";
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	int addedPages = 0;
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	int lastPageStart = 0;
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	do {
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        	int fittingChars = paint.breakText(text, currentOffset, textLength, true, maxWidth, null);
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        	if (currentOffset + fittingChars < textLength) {
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		fittingChars -= 2;
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		// Text doesn't fit on the line.  Insert a return after the last space.
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		int lastSpace = TextUtils.lastIndexOf(text, ' ', currentOffset + fittingChars - 1);
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		if (lastSpace == -1) {
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        			// No spaces, just split at the last character.
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        			lastSpace = currentOffset + fittingChars - 1;
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		}
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		spannedText.replace(lastSpace, lastSpace + 1, newline, 0, 1);
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		lineCount++;
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		currentOffset = lastSpace + 1;
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        	} else {
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		lineCount++;
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        		currentOffset = textLength;
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        	}
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        	if (lineCount >= maxLinesPerPage || currentOffset >= textLength) {
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        			lineCount = 0;
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        			if (addedPages == 0) {
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        				// overwrite the original page
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        				currentPage.text = spannedText.subSequence(lastPageStart, currentOffset);
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        			} else {
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        				// split into a new page
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        			ConversationPage newPage = new ConversationPage();
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		                newPage.imageResource = currentPage.imageResource;
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		                newPage.text = spannedText.subSequence(lastPageStart, currentOffset);
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		                newPage.title = currentPage.title;
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		                conversation.pages.add(page + addedPages, newPage);
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        			}
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        			lastPageStart = currentOffset;
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        			addedPages++;
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        		}
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	} while (currentOffset < textLength);
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        // Holy crap we did a lot of allocation there.
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        Runtime.getRuntime().gc();
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	}
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	@Override
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public boolean onTouchEvent(MotionEvent event) {
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (event.getAction() == MotionEvent.ACTION_UP) {
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            TypewriterTextView tv = (TypewriterTextView)findViewById(R.id.typewritertext);
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            if (tv.getRemainingTime() > 0) {
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                tv.snapToEnd();
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            } else {
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                mCurrentPage++;
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                if (mCurrentPage < mPages.size()) {
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    showPage(mPages.get(mCurrentPage));
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                } else {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    finish();
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                }
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            }
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        // Sleep so that the main thread doesn't get flooded with UI events.
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        try {
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            Thread.sleep(32);
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        } catch (InterruptedException e) {
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            // No big deal if this sleep is interrupted.
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        return true;
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    protected void showPage(ConversationUtils.ConversationPage page) {
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        TypewriterTextView tv = (TypewriterTextView)findViewById(R.id.typewritertext);
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        tv.setTypewriterText(page.text);
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		mOkArrow.setVisibility(View.INVISIBLE);
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		mOkAnimation.start();
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		tv.setOkArrow(mOkArrow);
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ImageView image = (ImageView)findViewById(R.id.speaker);
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (page.imageResource != 0) {
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	image.setImageResource(page.imageResource);
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	image.setVisibility(View.VISIBLE);
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        } else {
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	image.setVisibility(View.GONE);
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        TextView title = (TextView)findViewById(R.id.speakername);
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        if (page.title != null) {
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            title.setText(page.title);
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            title.setVisibility(View.VISIBLE);
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        } else {
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	title.setVisibility(View.GONE);
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public void processText() {
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    	if (!mConversation.splittingComplete) {
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    		TextView textView = (TextView)findViewById(R.id.typewritertext);
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    		formatPages(mConversation, textView);
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    		mConversation.splittingComplete = true;
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    	}
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    	if (mPages == null) {
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)	    	mPages = mConversation.pages;
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        showPage(mPages.get(0));
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	        mCurrentPage = 0;
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    	}
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    public static class TypewriterTextView extends TextView {
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        private int mCurrentCharacter;
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        private long mLastTime;
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        private CharSequence mText;
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        private View mOkArrow;
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        private ConversationDialogActivity mParentActivity;  // This really sucks.
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public TypewriterTextView(Context context) {
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            super(context);
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public TypewriterTextView(Context context, AttributeSet attrs) {
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            super(context, attrs);
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public TypewriterTextView(Context context, AttributeSet attrs, int defStyle) {
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            super(context, attrs, defStyle);
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public void setParentActivity(ConversationDialogActivity parent) {
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	mParentActivity = parent;
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public void setTypewriterText(CharSequence text) {
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            mText = text;
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            mCurrentCharacter = 0;
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            mLastTime = 0;
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            postInvalidate();
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public long getRemainingTime() {
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            return (mText.length() - mCurrentCharacter) * TEXT_CHARACTER_DELAY_MS;
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public void snapToEnd() {
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            mCurrentCharacter = mText.length() - 1;
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public void setOkArrow(View arrow) {
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        	mOkArrow = arrow;
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		@Override
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		protected void onSizeChanged(int w, int h, int oldw, int oldh) {
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)			// We need to wait until layout has occurred before we can setup the
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)			// text page.  Ugh.  Bidirectional dependency!
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)			if (mParentActivity != null) {
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)				mParentActivity.processText();
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)			}
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)			super.onSizeChanged(w, h, oldw, oldh);
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		}
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		@Override
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        public void onDraw(Canvas canvas) {
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            final long time = SystemClock.uptimeMillis();
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            final long delta = time - mLastTime;
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            if (delta > TEXT_CHARACTER_DELAY_MS) {
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                if (mText != null) {
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    if (mCurrentCharacter <= mText.length()) {
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        CharSequence subtext = mText.subSequence(0, mCurrentCharacter);
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        setText(subtext, TextView.BufferType.SPANNABLE);
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        mCurrentCharacter++;
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        postInvalidateDelayed(TEXT_CHARACTER_DELAY_MS);
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    } else {
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    	if (mOkArrow != null) {
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    		mOkArrow.setVisibility(View.VISIBLE);
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    	}
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    }
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                }
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            }
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            super.onDraw(canvas);
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        }
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)