// Copyright 1996, Marimba Inc. All Rights Reserved.


// @(#)PlayerUtil.java, 1.15, 12/19/96





package marimba.gui;





import java.io.*;


import java.net.*;


import java.util.Hashtable;





import marimba.text.TextView;


import marimba.util.*;





/**


 * A utillity class for manipulating the widgets in a player.


 * It contains many helper routines for accessing widgets and


 * setting their parameters.


 */





public class PlayerUtil implements TimerClient {


    /**


     * The PlayerPanel on which this util operates.


     * @see #getPlayerPanel


     */


    public PlayerPanel  player;





    Hashtable widgetHash;


    Presentation presentation;


    Widget widgetParent;





    /**


     * Constructor.


     */


    public PlayerUtil(PlayerPanel player) {


	this.player = player;


    }





    /**


     * Get the PlayerPanel.


     * @see #player


     */


    public PlayerPanel getPlayerPanel() {


	return player;


    }





    /**


     * Set a presentation from a file


     */


    public synchronized void setPresentation(String file) {


	File f = new File(file);


	if (!f.canRead()) {


	    System.err.println("error: can't read: " + file);


	    return;


	}





	try {


	    setPresentation(new URL("file:" + f.getAbsolutePath().replace(File.separatorChar, '/')));


	} catch (MalformedURLException e) {


	    e.printStackTrace();


	}


    }





    /**


     * Set a presentation from a url


     */


    public synchronized void setPresentation(URL url) {


	Presentation presentation = Presentation.getPresentation(url);


	player.setPresentation(presentation);


	widgetHash = null;


	widgetParent = null;


    }





    /**


     * Get the current presentation.


     */


    public Presentation getPresentation() {


	return player.presentation;


    }





    /**


     * Find a widget in this container. The name can be hierarchical


     * and is alreay broken into the root component and the rest.


     */


    Widget findWidget(Widget parent, String nm, int i, String name) {


	Widget w = parent.findWidget(nm);


	while ((w != null) && (i >= 0)) {


	    int j = name.indexOf('.', i+1);


	    w = w.findWidget((j < 0) ? name.substring(i+1) : name.substring(i+1, j));


	    i = j;


	}


	return w;


    }





    /**


     * Do a depth first search for a widget. The name can be hierarchical


     * and is alreay broken into the root component and the rest.


     */


    Widget searchWidget(Widget parent, String nm, int i, String name) {


	Widget w = findWidget(parent, nm, i, name);


	if (w != null) {


	    widgetParent = parent;


	    return w;


	}





	for (int j = 0 ; j < parent.nwidgets ; j++) {


	    if ((w = searchWidget(parent.widgets[j], nm, i, name)) != null) {


		return w;


	    }


	}


	return null;


    }





    /**


     * Accessing widgets, prints an error message to system.err if


     * the widget is not being found.


     */


    public synchronized Widget getWidget(String name) {


	return getWidget(name, true);


    }





    /**


     * Accessing widgets, print or do not print an error message.


     */


    public synchronized Widget getWidget(String name, boolean print) {


	// Flush the cache when the presentation changes


	if (presentation != player.presentation) {


	    widgetHash = null;


	    widgetParent = null;


	    presentation = player.presentation;


	}





	// Don't bother if there is no presentation


	if (presentation == null) {


	    return null;


	}





	// Create a hash if needed


	if (widgetHash == null) {


	    widgetHash = new Hashtable();


	}





	// Look in the hash


	Widget w = (Widget)widgetHash.get(name);


	if (w != null) {


	    return w;


	}





	// Get the root of the name


	int i = name.indexOf('.');


	String nm = (i < 0) ? name : name.substring(0, i);





	// Check the same container as last time first (optimization)


	if ((widgetParent != null) && ((w = findWidget(widgetParent, nm, i, name)) != null)) {


	    //System.err.println("found in parent: " + name);


	    widgetHash.put(name, w);


	    return w;


	}





	// Check in the presentation.


	if ((w = searchWidget(player.presentation, nm, i, name)) != null) {


	    //System.err.println("found after search: " + name);


	    widgetHash.put(name, w);


	    return w;


	}





	// Not found


	if (print) {


	    System.err.println("warning: widget not found: '" + name + "'");


	}


	return null;


    }





    /**


     * Get the value of a widget.


     */


    public Object getValue(String name) {


	Widget w = getWidget(name);


	return (w != null) ? w.getValue() : null;


    }





    /**


     * Get the value of a widget.


     */


    public void setValue(String name, Object value) {


	Widget w = getWidget(name);


	if (w != null) {


	    w.setValue(value);


	}


    }





    /**


     * Get the text of a widget.


     */


    public String getText(String name) {


	Widget w = getWidget(name);


	return (w != null) ? w.getText() : null;


    }





    /**


     * Get the text of a widget.


     */


    public void setText(String name, String value) {


	Widget w = getWidget(name);


	if (w != null) {


	    w.setText(value);


	    Timer.master.remove(this, w);


	}


    }





    /**


     * Append to a named TextWidget or TextAreaWidget.


     */


    public void appendText(String name, String value) {


	Widget w = getWidget(name);


	if (w instanceof TextWidget) {


	    TextWidget tw = (TextWidget)w;


	    tw.append(value);


	    tw.focus(tw.getLength());


	} else {


	    w.setText(w.getText() + value);


	}


    }





    /**


     * Tick, means clear a text widget.


     */


    public long tick(long tm, Object arg) {


	if (arg instanceof Widget) {


	    ((Widget)arg).setText("");


	}


	return -1;


    }





    /**


     * Clear a named TextWidget or TextAreaWidget, after a given time.


     */


    public void clearText(String name, long tm) {


	Widget w = getWidget(name);


	if (w != null) {


	    Timer.master.add(this, System.currentTimeMillis() + tm, w);


	}


    }





    /**


     * Get the value of a named ChoiceWidget.


     */


    public String getChoice(String name) {


	ChoiceWidget w = (ChoiceWidget)getWidget(name);


	return (w != null) ? w.getStringValue() : null;


    }





    /**


     * Set the value of a named ChoiceWidget.


     */


    public void setChoice(String name, String value) {


	ChoiceWidget w = (ChoiceWidget)getWidget(name);


	if (w != null) {


	    w.setValue(value);


	}


    }





    /**


     * Get the value of a named CheckBoxWidget.


     */


    public boolean getBoolean(String name) {


	CheckBoxWidget w = (CheckBoxWidget)getWidget(name);


	return (w != null) ? w.getBooleanValue() : false;


    }





    /**


     * Set the value of a named CheckBoxWidget.


     */


    public void setBoolean(String name, boolean value) {


	CheckBoxWidget w = (CheckBoxWidget)getWidget(name);


	if (w != null) {


	    w.setValue(value);


	}


    }





    /**


     * Goto a named page.


     */


    public void gotoPage(String name) {


	PageWidget w = (PageWidget)getWidget(name);


	if (w != null) {


	    ((FolderWidget)w.parent).gotoPage(w);


	}


    }





    /**


     * Get the current page of a named FolderWidget.


     */


    public String currentPage(String name) {


	FolderWidget w = (FolderWidget)getWidget(name);


	return (w != null) ? w.currentPage().getName() : null;


    }





    /**


     * Show a named widget.


     */


    public void show(String name) {


	show(name, true);


    }





    /**


     * Show/Hide a named widget.


     */


    public void show(String name, boolean flag) {


	Widget w = getWidget(name);


	if (w != null) {


	    w.show(flag);


	}


    }





    /**


     * Clear a named ListWidget.


     */


    public void clearList(String name) {


	ListWidget w = (ListWidget)getWidget(name);


	if (w != null) {


	    w.clear();


	}


    }





    /**


     * Add a ListItemWidget to a named ListWidget.


     */


    public void addList(String name, ListItemWidget item) {


	ListWidget w = (ListWidget)getWidget(name);


	if (w != null) {


	    w.addItem(item);


	}


    }





    /**


     * Add a sorted ListItemWidget to a named ListWidget.


     */


    public void addSortedList(String name, ListItemWidget item) {


	ListWidget w = (ListWidget)getWidget(name);


	if (w != null) {


	    w.addSorted(item);


	}


    }





    /**


     * Set the Frames per second for a named AnimatedWidget.


     */


    public void setFPS(String name, int fps) {


	AnimatedWidget w = (AnimatedWidget)getWidget(name);


	if (w != null) {


	    w.setFPS(fps);


	}


    }


}


