/*
* Copyright 2013 Elina Vartiainen and Simon Robinson
*
* This file is part of Com-Me.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ac.robinson.mediaphonejavame.form;
import java.io.InputStream;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
import ac.robinson.mediaphonejavame.MediaPhone;
import ac.robinson.mediaphonejavame.MediaPhoneMidlet;
import ac.robinson.mediaphonejavame.localization.L10nConstants;
import ac.robinson.mediaphonejavame.provider.Frame;
import ac.robinson.mediaphonejavame.provider.Narrative;
import ac.robinson.mediaphonejavame.util.ImageCacheUtilities;
import com.sun.lwuit.Command;
import com.sun.lwuit.Form;
import com.sun.lwuit.Label;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.geom.Dimension;
import com.sun.lwuit.layouts.BoxLayout;
import com.sun.lwuit.plaf.Style;
/**
* Creates a view for playing back the narrative. The animation is created as a set of timer tasks, where each tasks
* represents a frame. The length of the animation is calculated using the length of possible recordings or a default
* value for each frame. The timer tasks are then fired after each other in the same order as in the narrative.
*/
public class PlayNarrativeForm extends Form implements ActionListener {
private Narrative mNarrative;
private Timer mTimer;
private int mStartingFrame;
private Player mPlayer = null;
private InputStream mInputStream = null;
private FileConnection mFileConnection = null;
private Label mImageLabel = new Label();
private Label mAudioLabel = new Label();
private TextArea mTextArea = new TextArea();
public PlayNarrativeForm(Narrative narrative, int currentFrame) {
super();
mNarrative = narrative;
mStartingFrame = currentFrame;
setLayout(new BoxLayout(BoxLayout.Y_AXIS));
mAudioLabel.getStyle().setAlignment(Label.LEFT);
mAudioLabel.setPreferredSize(new Dimension(MediaPhone.COMPONENT_SIZE_SMALL, MediaPhone.COMPONENT_SIZE_SMALL));
mImageLabel.getStyle().setAlignment(Label.CENTER);
mImageLabel.setPreferredSize(new Dimension(160, 120)); // TODO: globals
Style style = mTextArea.getStyle();
style.setAlignment(Label.CENTER);
style.setBorder(null);
mTextArea.setGrowByContent(true);
mTextArea.setEditable(false);
mTextArea.setFocusable(false);
addComponent(mAudioLabel);
addComponent(mImageLabel);
addComponent(mTextArea);
addCommand(new Command(MediaPhone.getString(L10nConstants.keys.BUTTON_BACK),
MediaPhone.id.button_finished_playback));
addCommand(new Command(MediaPhone.getString(L10nConstants.keys.BUTTON_REPLAY),
MediaPhone.id.button_replay_narrative));
addCommandListener(this);
}
public void show() {
startPlayback();
super.show();
}
public void startPlayback() {
setTitle(MediaPhone.getString(L10nConstants.keys.TITLE_PLAYBACK));
if (mTimer != null) {
mTimer.cancel();
}
mTimer = new Timer();
int nextStartTime = 0;
Vector allFrames = mNarrative.getFrames();
for (int i = mStartingFrame, n = allFrames.size(); i < n; i++) {
final Frame currentFrame = (Frame) allFrames.elementAt(i);
final boolean hasAudio = currentFrame.getAudio() != null;
mTimer.schedule(new TimerTask() {
public void run() {
if (currentFrame.getImage() != null) {
// TODO: size to globals
mImageLabel.setIcon(ImageCacheUtilities.getScaledCachedImage(currentFrame.getImage(), 160, 120));
} else {
mImageLabel.setIcon(null);
}
if (hasAudio) {
mAudioLabel.setIcon(ImageCacheUtilities.getScaledCachedSquareImage(
MediaPhone.drawable.ic_audio_playback, MediaPhone.COMPONENT_SIZE_SMALL));
playAudio(currentFrame.getAudio());
} else {
mAudioLabel.setIcon(null);
}
if (currentFrame.getText() != null) {
mTextArea.setText(currentFrame.getText());
} else {
mTextArea.setText("");
}
repaint();
}
}, nextStartTime);
if (hasAudio) {
nextStartTime += currentFrame.getAudioDurationMilliseconds();
} else {
nextStartTime += MediaPhone.DEFAULT_FRAME_DURATION;
}
}
mTimer.schedule(new TimerTask() {
public void run() {
setTitle(MediaPhone.getString(L10nConstants.keys.TITLE_PLAYBACK_COMPLETE));
closePlayer();
mStartingFrame = 0;
}
}, nextStartTime);
}
public void actionPerformed(ActionEvent event) {
switch (event.getCommand().getId()) {
case MediaPhone.id.button_finished_playback:
closePlayer();
MediaPhoneMidlet.getInstance().showNarrativeListForm();
break;
case MediaPhone.id.button_replay_narrative:
closePlayer();
mStartingFrame = 0;
startPlayback();
break;
}
}
private void closePlayer() {
try {
if (mPlayer != null) {
mPlayer.stop();
mPlayer.close();
mPlayer = null;
}
} catch (Exception e) {
}
try {
mInputStream.close();
} catch (Exception e) {
}
try {
mFileConnection.close();
} catch (Exception e) {
}
}
private void playAudio(String fileName) {
try {
closePlayer();
mFileConnection = (FileConnection) Connector.open(fileName, Connector.READ);
mInputStream = mFileConnection.openInputStream();
mPlayer = Manager.createPlayer(mInputStream, "audio/amr");
if (mPlayer != null) {
mPlayer.prefetch();
mPlayer.start();
}
} catch (Exception e) {
if (MediaPhone.DEBUG) {
mAudioLabel.setText("Error: " + e.getMessage());
e.printStackTrace();
}
}
}
}