//(c) Copyright 2007, Scott Vorthmann. All rights reserved.
package org.vorthmann.zome.app.impl;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.StringTokenizer;
import org.vorthmann.ui.DefaultController;
import org.vorthmann.ui.SwingWorker;
import com.vzome.core.editor.LessonModel;
import com.vzome.core.editor.Snapshot;
import com.vzome.core.viewing.ThumbnailRenderer;
import com.vzome.core.viewing.Camera;
import com.vzome.desktop.controller.CameraController;
public class LessonController extends DefaultController
{
private final LessonModel model;
private final CameraController vpm;
private boolean listening = true;
public LessonController( LessonModel model, CameraController vpm )
{
this .model = model;
this .vpm = vpm;
// pages .add( new PageController( "How to save notes", DEFAULT_CONTENT, vpm .getView() ) );
model .addPropertyChangeListener( new PropertyChangeListener()
{
@Override
public void propertyChange( PropertyChangeEvent change )
{
properties() .firePropertyChange( change ); // forward to the view
}
} );
}
@Override
public void doAction( String action, ActionEvent e ) throws Exception
{
if ( ! listening )
// guard against events that originate here
return;
if ( "duplicatePage" .equals( action ) )
{
// this is the duplicate button in article mode
model .duplicatePage( this.vpm .getView() );
setProperty( "edited", "true" );
}
else if ( "deletePage" .equals( action ) )
{
model .deletePage();
setProperty( "edited", "true" );
}
else if ( action .startsWith( "elementSelected-" ) )
{
// action defined by ListPanel
String pageNumStr = action .substring( "elementSelected-" .length() );
model .goToPage( Integer .parseInt( pageNumStr ) );
}
else if ( action .startsWith( "elementChanged-" ) )
{
// no-op, the thumbnail image was added
}
else if ( action .startsWith( "elementMoved-" ) )
{
// action defined by ListPanel
String moveStr = action .substring( "elementMoved-" .length() );
StringTokenizer tokens = new StringTokenizer( moveStr, ">" );
String from = tokens .nextToken();
int fromNum = Integer .parseInt( from );
String to = tokens .nextToken();
int toNum = Integer .parseInt( to );
model .movePage( fromNum, toNum );
}
else if ( "firstPage" .equals( action ) )
{
model .goToFirstPage();
}
else if ( "previousPage" .equals( action ) )
{
model .goToPreviousPage();
}
else if ( "nextPage" .equals( action ) )
{
model .goToNextPage();
}
else if ( "lastPage" .equals( action ) )
{
model .goToLastPage();
}
else if ( "setView" .equals( action ) )
{
model .setView( vpm .getView() );
setProperty( "edited", "true" );
}
else if ( action .startsWith( "usePageView-" ) )
{
String pageStr = action .substring( "usePageView-".length() );
int num = Integer .parseInt( pageStr );
Camera newView = model .getPageView( num );
if ( ! newView .equals( this.vpm .getView() ) )
vpm .restoreView( newView );
}
else if ( action .startsWith( "copyPageView-" ) )
{
String pageStr = action .substring( "copyPageView-".length() );
int num = Integer .parseInt( pageStr );
Camera newView = model .getPageView( num );
vpm .copyView( newView );
}
else if ( "restoreSnapshot" .equals( action ) )
{
model .refresh();
}
else if ( action .startsWith( "insertUpdateEvent" ) )
{
StringTokenizer tokens = new StringTokenizer( action );
tokens .nextToken(); // skip action
String which = tokens .nextToken();
String original = "title" .equals( which )? model .getTitle() : model .getContent();
int offset = Integer .parseInt( tokens .nextToken() );
String text = tokens .nextToken( "" ) .substring( 1 ); // get the rest, strip off the leading space
StringBuffer buff = new StringBuffer();
buff .append( original .substring( 0, offset ) );
buff .append( text );
buff .append( original .substring( offset ) );
if ( "title" .equals( which ) )
model .setTitle(buff .toString());
else
model .setContent(buff .toString());
}
else if ( action .startsWith( "removeUpdateEvent" ) )
{
StringTokenizer tokens = new StringTokenizer( action );
tokens .nextToken(); // skip action
String which = tokens .nextToken();
String original = "title" .equals( which )? model .getTitle() : model .getContent();
int offset = Integer .parseInt( tokens .nextToken() );
int length = Integer .parseInt( tokens .nextToken() );
StringBuffer buff = new StringBuffer();
buff .append( original .substring( 0, offset ) );
buff .append( original .substring( offset + length ) );
if ( "title" .equals( which ) )
model .setTitle(buff .toString());
else
model .setContent(buff .toString());
}
else
super.doAction( action, e );
}
@Override
public boolean[] enableContextualCommands( String[] menu, MouseEvent e )
{
Integer item = (Integer) e .getSource();
boolean[] result = new boolean[ menu.length ];
boolean samePage = model .onPage( item .intValue() );
for ( int i = 0; i < result.length; i++ ) {
if ( menu[ i ] .startsWith( "usePageView-" ) )
result[ i ] = ! samePage;
else if ( "setView" .equals( menu[ i ] ) )
result[ i ] = samePage;
else if ( menu[ i ] .startsWith( "copyPageView-" ) )
result[ i ] = true;
else
result[ i ] = true;
}
return result;
}
@Override
public String getProperty( String propName )
{
if ( "has.pages" .equals( propName ) )
return Boolean .toString( ! model .isEmpty() );
if ( "onFirstPage" .equals( propName ) )
return Boolean .toString( model .onFirstPage() );
if ( "onLastPage" .equals( propName ) )
return Boolean .toString( model .onLastPage() );
if ( "num.pages" .equals( propName ) )
return Integer .toString( model. size() );
if ( "page.num" .equals( propName ) )
return Integer .toString( model .getPageNum() );
if ( "title" .equals( propName ) )
return model .getTitle();
if ( "content" .equals( propName ) )
return model .getContent();
return super.getProperty( propName );
}
public DocumentController getEditorController()
{
return (DocumentController) this .mNextController;
}
public void renderThumbnails( final Snapshot.Recorder recorder, final ThumbnailRenderer renderer )
{
SwingWorker worker = new SwingWorker()
{
@Override
public Object construct()
{
synchronized ( renderer )
{
for (int i = 0; i < model .size(); i++)
{
model .updateThumbnail( i, recorder, renderer );
}
}
return null;
};
@Override
public void finished() {}
};
worker .start(); //Start the background thread
}
}