
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.applet.*;

import cnp.ew.util.*;
import cnp.ew.layout.*;
import cnp.ew.misc.*;
import cnp.ew.lightweight.*;
import cnp.ew.button.*;
import cnp.ew.text.*;
import cnp.ew.list.*;
import cnp.ew.image.*;

import marimba.gui.*;
import marimba.channel.*;
import marimba.desktop.*;

/**
 * CpChannelLauncher: provides a simple Applet-Viewer like application
 * that can launch our applets.  To add applets, do the following:
 *   - add the title to either the static array applicationTitles or widgetTitles
 *   - add the class name as a string (without .class) to the classNames static array
 * Note that order is important; the title arrays and the className array have to match up.
 *
 * @version        $Version$
 * @author         $Author: Ken Cooper$
 *
 * Copyright 1996, Cooper & Peters, Inc.
 */
public class CpChannelLauncher extends ApplicationFrame implements AppletStub, java.applet.AppletContext {
    Label label;
    Applet currentApplet;
    int currentAppletIndex;

    static String[] applicationTitles = {
        "Word Processor",
        "Spreadsheet",
        "Charting",
        "Graphics Editor",
        "Java Editor"
    };


    static String[] widgetTitles = {
        "Bordered Panels",
        "Buttons",
        "Gauges",
        "Spin Buttons",
        "Formatted Entryfields",
        "Calendar",
        "Customizable Entryfields",
        "Notebooks",
        "Sliders",
        "Dialogs",
        "Lists",
        "Attachments",
        "Split Bars"
    };

    static String[] classNames = {
        "CpWordProcessorDemo",
        "CpSpreadsheetDemo",
        "CpChartDemo",
        "CpDiagramDemo",
        "CpJavaEditor",


        "CpBorderedPanelDemo",
        "CpButtonDemo",
        "CpGaugeDemo",
        "CpSpinButtonDemo",
        "CpPictureFieldDemo",
        "CpCalendarDemo",
        "CpEntryFieldDemo",
        "CpNotebookDemo",
        "CpSliderDemo",
        "CpDialogDemo",
        "CpListDemo",
        "CpAttachmentsDemo",
        "CpSplitbarDemo"
    };

    CheckboxMenuItem [] menuItems;

    public void start()
    {
        setTitle("Cooper & Peters Demo Applet Viewer");
        CpImageGetter.getDefault().isApplet = true;
        CpToolkit.setDefaultComponent(this);

        menuItems = new CheckboxMenuItem[applicationTitles.length + widgetTitles.length];

        MenuBar menuBar = new MenuBar();
        Menu menu = new Menu("Applications");
        for (int i=0; i < applicationTitles.length; i++) {
            menuItems[i] = new CheckboxMenuItem(applicationTitles[i]);
            menu.add(menuItems[i]);
        }
        menuBar.add(menu);

        menu = new Menu("Components");
        for (int i=0; i < widgetTitles.length; i++) {
            menuItems[i + applicationTitles.length] = new CheckboxMenuItem(widgetTitles[i]);
            menu.add(menuItems[i + applicationTitles.length]);
        }
        menuBar.add(menu);
        setMenuBar(menuBar);

        label = new Label();
        add(label);

        showNewApplet(0);
        show();
    }

    /**
     * Returns true if the applet is active.
     */
    public boolean isActive() {
        return true;
    }

    /**
     * Gets the document URL.
     */
    public URL getDocumentBase() {
        System.out.println("GET DOC: " + context.getBase());
        return context.getBase();
    }

    /**
     * Gets the base URL.
     */
    public URL getCodeBase() {
        System.out.println("GET CODE: " + context.getBase());
        return context.getCodeBase();
    }

    /**
     * Gets a parameter of the applet.
     */
    public String getParameter(String name) {
        System.out.println("GET PARAM: " + name);
        return context.getParameter(name);
    }

    /**
     * Gets a handler to the applet's context.
     */
    public java.applet.AppletContext getAppletContext() {
        return this;
    }

    /**
     * Called when the applet wants to be resized.
     */
    public void appletResize(int width, int height) {
    }

    /**
     * Gets an audio clip.
     */
    public AudioClip getAudioClip(URL url) {
        System.out.println("GET AUDIO: " + url);
        return AudioCache.get(url);
    }

    /**
     * Gets an image. This usually involves downloading it
     * over the net. However, the environment may decide to
     * cache images. This method takes an array of URLs,
     * each of which will be tried until the image is found.
     */
    public Image getImage(URL url) {
        System.out.println("GET IMG: " + url);
        return ImageCache.get(url);
    }

    /**
     * Gets an applet by name.
     * @return null if the applet does not exist.
     */
    public Applet getApplet(String name) {
        return null;
    }

    /**
     * Enumerates the applets in this context. Only applets
     * that are accessible will be returned. This list always
     * includes the applet itself.
     */
    public Enumeration getApplets() {
        return new Vector().elements();
    }

    /**
     * Shows a new document. This may be ignored by
     * the applet context.
     */
    public void showDocument(URL url) {
        Desktop.getDesktop().showURL(url);
    }

    /**
     * Show a new document in a target window or frame. This may be ignored by
     * the applet context.
     *
     * This method accepts the target strings:
     *   _self          show in current frame
     *   _parent        show in parent frame
     *   _top           show in top-most frame
     *   _blank         show in new unnamed top-level window
     *   <other>        show in new top-level window named <other>
     */
    public void showDocument(URL url, String target) {
        Desktop.getDesktop().showURL(url);
    }

    /**
     * Show a status string.
     */
    public void showStatus(String status) {
        System.out.println("STATUS: " + status);
    }

    public void layout()
    {
        Insets insets = insets();
        int innerWidth = size().width - insets.left - insets.right;
        int innerHeight = size().height - insets.top - insets.bottom;
        int labelHeight = label.preferredSize().height;
        label.reshape(insets.left, size().height - labelHeight - insets.bottom, innerWidth, labelHeight);

        if (currentApplet != null) {
            currentApplet.reshape(insets.left, insets.top, innerWidth, innerHeight - labelHeight);
        }
    }



        public boolean handleEvent (Event evt) {

                switch(evt.id) {
                case Event.WINDOW_DESTROY:
                if (currentApplet != null) {
                    currentApplet.stop();
                }
                context.stop();
                return true;

              case Event.ACTION_EVENT:
                if (evt.target instanceof CheckboxMenuItem) {
                showNewApplet(indexForMenuItem((CheckboxMenuItem)evt.target));
            }
                break;
                }
                return super.handleEvent(evt);
        }

    int indexForMenuItem(CheckboxMenuItem menuItem)
    {
        for (int i = 0; i < menuItems.length; i++) {
            if (menuItem == menuItems[i]) {
                return i;
            }
        }
        return -1;
    }

        void showNewApplet(int index)
        {
            if (currentApplet != null) {
                remove(currentApplet);
                currentApplet.hide();
                currentApplet.stop();
                menuItems[currentAppletIndex].setState(false);
            }

            try {
                currentApplet = (Applet)Class.forName(classNames[index]).newInstance();
            } catch (ClassNotFoundException e) {  System.out.println(e); return; }
            catch (InstantiationException e) { System.out.println(e); return; }
            catch (IllegalAccessException e) { System.out.println(e); return; }

        currentAppletIndex = index;
        menuItems[currentAppletIndex].setState(true);

        System.out.println("Set Stub");
        currentApplet.setStub(this);
        System.out.println("Set Stub Done");

        add(currentApplet);
        label.setText("Initializing...");

        resizeByOnePixel();

        currentApplet.init();
        currentApplet.start();

        label.setText("Running...");
    }


    /**
     * TBD: This is a complete hack, and needs to be looked into.  Size() is not answering the correct
     * dimension unless we explicitly resize the frame, and this causes each applet to fail. To get
     * around it, we size up and down by one pixel when they switch applets. Ick.
     */
    int sizeToggle = 0;

    void resizeByOnePixel()
    {
        int curHeight = size().height;
        if (curHeight == 0) {
            curHeight = 480;
        }
        resize(640, curHeight + sizeToggle);
        if (sizeToggle > 0) {
            sizeToggle = -1;
        } else {
            sizeToggle = 1;
        }
    }

}


