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