import java.util.Hashtable;
import java.io.Serializable;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.applet.Applet;
import java.lang.reflect.Method;
import java.beans.Beans;
import sunw.beanbox.AppletSupport;
import sunw.beanbox.PropertyHookup;

public class tvDemoApplet extends Applet implements Serializable {

    // Public 0-argument constructor

    public tvDemoApplet() {
        this.setLayout(null);
        try {
            initContents();
        } catch (Exception ex) {
            System.err.println(ex);
            throw new Error("trouble initializing contents: "+ex);
        }
    }

    // Preferred size
    public Dimension getPreferredSize() {
        return getMinimumSize();
    }

    // Preferred size
    public Dimension getMinimumSize() {
        return new Dimension(382, 513);
    }

    // Initialize nested beans
    private void initContents()
            throws java.lang.ClassNotFoundException,
            java.io.IOException
    {
        myLoader = this.getClass().getClassLoader();
        propInstances = new Hashtable();


        // Create nested beans
        botaoOnOff1 = (tv.BotaoOnOff) Beans.instantiate(myLoader,"tv.BotaoOnOff");

        ourButton1 = (sunw.demo.buttons.OurButton) Beans.instantiate(myLoader,"sunw.demo.buttons.OurButton");

        ourButton2 = (sunw.demo.buttons.OurButton) Beans.instantiate(myLoader,"sunw.demo.buttons.OurButton");

        keyPad1 = (tv.KeyPad) Beans.instantiate(myLoader,"tv.KeyPad");

        TVEstado1 = (tv.TVEstado) Beans.instantiate(myLoader,"tv.TVEstado");

        limites1 = (tv.Limites) Beans.instantiate(myLoader,"tv.Limites");

        TVDisplay1 = (tv.TVDisplay) Beans.instantiate(myLoader,"tv.TVDisplay");

        botaoOnOff2 = (tv.BotaoOnOff) Beans.instantiate(myLoader,"tv.BotaoOnOff");

        // position all nested beans - we don't have it initially
        acquire(botaoOnOff1, new Rectangle(18, 218, 73, 21));
        acquire(ourButton1, new Rectangle(10, 255, 44, 24));
        acquire(ourButton2, new Rectangle(64, 254, 44, 24));
        acquire(keyPad1, new Rectangle(9, 289, 100, 84));
        acquire(TVEstado1, null);
        acquire(limites1, null);
        acquire(TVDisplay1, new Rectangle(193, 225, 120, 131));
        acquire(botaoOnOff2, new Rectangle(233, 189, 73, 21));

        // Add their connections
        addConnections();
    }

    private void addConnections() {
        try {
            hookup0 = new tmp.sunw.beanbox.___Hookup_175532878e();
            hookup0.setTarget(TVEstado1);
            botaoOnOff1.addActionListener(hookup0);
            //
            hookup1 = new tmp.sunw.beanbox.___Hookup_175532996d();
            hookup1.setTarget(TVEstado1);
            ourButton1.addActionListener(hookup1);
            //
            hookup2 = new tmp.sunw.beanbox.___Hookup_175532a005();
            hookup2.setTarget(TVEstado1);
            ourButton2.addActionListener(hookup2);
            //
            hookup3 = addPropertyTarget(
                keyPad1, 
                "valor",
                TVEstado1,
                "setCanal", new String[] {"int"});
            //
            hookup4 = new tmp.sunw.beanbox.___Hookup_175532ad8d();
            hookup4.setTarget(limites1);
            TVEstado1.addVetoableChangeListener(hookup4);
            hookup5 = addPropertyTarget(
                TVEstado1, 
                "on",
                botaoOnOff1,
                "setOn", new String[] {"boolean"});
            hookup6 = addPropertyTarget(
                TVEstado1, 
                "on",
                botaoOnOff2,
                "setOn", new String[] {"boolean"});
            hookup7 = addPropertyTarget(
                TVEstado1, 
                "on",
                TVDisplay1,
                "setOn", new String[] {"boolean"});
            //
            hookup8 = addPropertyTarget(
                limites1, 
                "valor",
                TVDisplay1,
                "setCanal", new String[] {"int"});
            //
            //
            hookup9 = new tmp.sunw.beanbox.___Hookup_1755328ce7();
            hookup9.setTarget(TVEstado1);
            botaoOnOff2.addActionListener(hookup9);
            //
        } catch (Exception ex) {
            System.err.println("Problems adding a target: "+ex);
            ex.printStackTrace();
        }
    }

    private void addReconnections() {
        try {
            //
            //
            //
            //
            //
            //
            //
            //
            //   No property adaptors.  A typical example is:
            //     hookup0 = addPropertyTarget(
            //       ourButton1,
            //       "foreground",
            //       "background",
            //       "setBackground", new String[] {"java.awt.Font"});
            //   No method adaptors.  A typical example is:
            //     hookup0 = new MyActionAdaptor();
            //     ourButton1.addActionListener(hookup0);
        } catch (Exception ex) {
            System.err.println("Problems adding a target: "+ex);
            ex.printStackTrace();
        }
    }

    // Serialization code - readObject
    private void readObject(java.io.ObjectInputStream ois)
        throws java.lang.ClassNotFoundException,
        java.io.IOException
    {
        // Initialize object from stream
        Object[] data = (Object[]) ois.readObject();

        myLoader = this.getClass().getClassLoader();
        propInstances = new Hashtable();

        String id = (String) data[0];
        if (! id.equals("tvDemoApplet")) {
            throw new Error("Wrong data!");
        }

        // Get references to nested beans
        botaoOnOff1 = (tv.BotaoOnOff) data[1];
        ourButton1 = (sunw.demo.buttons.OurButton) data[2];
        ourButton2 = (sunw.demo.buttons.OurButton) data[3];
        keyPad1 = (tv.KeyPad) data[4];
        TVEstado1 = (tv.TVEstado) data[5];
        limites1 = (tv.Limites) data[6];
        TVDisplay1 = (tv.TVDisplay) data[7];
        botaoOnOff2 = (tv.BotaoOnOff) data[8];
        
        // Don't position nested beans
        acquire(botaoOnOff1, null);
        acquire(ourButton1, null);
        acquire(ourButton2, null);
        acquire(keyPad1, null);
        acquire(TVEstado1, null);
        acquire(limites1, null);
        acquire(TVDisplay1, null);
        acquire(botaoOnOff2, null);

        // Reconnect their connections
        addReconnections();
    }

    // Serialization code - writeObject
    private void writeObject(java.io.ObjectOutputStream oos)
        throws java.io.IOException
    {
        Object data[] = new Object[9];
        data[0] = "tvDemoApplet";
        data[1] = botaoOnOff1;
        data[2] = ourButton1;
        data[3] = ourButton2;
        data[4] = keyPad1;
        data[5] = TVEstado1;
        data[6] = limites1;
        data[7] = TVDisplay1;
        data[8] = botaoOnOff2;

        // Write the object out
        oos.writeObject(data);
    }


    // The fields used to hold the beans
    private tv.BotaoOnOff botaoOnOff1;
    private sunw.demo.buttons.OurButton ourButton1;
    private sunw.demo.buttons.OurButton ourButton2;
    private tv.KeyPad keyPad1;
    private tv.TVEstado TVEstado1;
    private tv.Limites limites1;
    private tv.TVDisplay TVDisplay1;
    private tv.BotaoOnOff botaoOnOff2;

    // The hookups
    private tmp.sunw.beanbox.___Hookup_175532878e hookup0;
    private tmp.sunw.beanbox.___Hookup_175532996d hookup1;
    private tmp.sunw.beanbox.___Hookup_175532a005 hookup2;
    private PropertyHookup hookup3;
    private tmp.sunw.beanbox.___Hookup_175532ad8d hookup4;
    private PropertyHookup hookup5;
    private PropertyHookup hookup6;
    private PropertyHookup hookup7;
    private PropertyHookup hookup8;
    private tmp.sunw.beanbox.___Hookup_1755328ce7 hookup9;

    // the loader so we can locate the resource file
    private ClassLoader myLoader;

    // =========================================== 
    // Support code
    // =========================================== 
    // It really belongs in support.jar but it is here for your reading pleasure

    // Acquire a bean
    private void acquire(Object bean, Rectangle boundsData) {
        if (!(bean instanceof Component)) {
            return;
        }
        if (bean instanceof Applet) {
            AppletSupport.assignStub((Applet) bean,
                myLoader,
            bean.getClass());
        }

        add((Component) bean);
        if (boundsData != null) {
            ((Component) bean).setBounds(boundsData);
        }
        ((Component)bean).invalidate();	// not needed?

        if (bean instanceof Applet) {
            // Start the Applet
            ((Applet)bean).start();
        }
    }

    // Add a property bound via an adaptor
    Hashtable propInstances = new Hashtable();

    private PropertyHookup addPropertyTarget(Object source,
        String propertyName,
        Object targetObject,
        String setterName, String[] setterTypeNames) throws Exception
    {
        Object args[] = new Object[1]; // arguments
        Class types[] = new Class[1]; // types
        Class pClass = java.beans.PropertyChangeListener.class;

        PropertyHookup hook = (PropertyHookup) propInstances.get(source);
        if (hook == null) {
            // This is the first property hookup on this source object
            // Push a PropertyHookup adaptor onto the source
            hook = new PropertyHookup(source);
            propInstances.put(source, hook);

            // find the adder
            types[0] = pClass;
            Method adder = source.getClass().getMethod("addPropertyChangeListener", types);
            // invoke the adder
            args[0] = hook;
            adder.invoke(source, args);
        }

        // get setter
        Method setter = targetObject.getClass().getMethod(setterName,
            getClassFromTypes(setterTypeNames));

        hook.attach(propertyName, targetObject, setter);
        return hook;
    }

    private Class[] getClassFromTypes(String types[]) throws Exception {
        Class[] back = new Class[types.length];
        for (int i=0; i<back.length; i++) {
            Class c = unwrapPrimitiveStringToClass(types[i]);

            if (c == null)
                back[i] = myLoader.loadClass(types[i]);
            else
                back[i] = c;
        }
        return back;
    }
    private Class unwrapPrimitiveStringToClass(String s) {
        if (s.equals(Byte.TYPE.getName()))        return byte.class;
        if (s.equals(Short.TYPE.getName()))       return short.class;
        if (s.equals(Integer.TYPE.getName()))     return int.class;
        if (s.equals(Long.TYPE.getName()))        return long.class;
        if (s.equals(Double.TYPE.getName()))      return double.class;
        if (s.equals(Float.TYPE.getName()))       return float.class;
        if (s.equals(Character.TYPE.getName()))   return char.class;
        if (s.equals(Boolean.TYPE.getName()))     return boolean.class;
        if (s.equals(Void.TYPE.getName()))        return void.class;
        return null;
    }
    // =========================================== 
    // End of Support code
    // =========================================== 
}
