package com.wiley.compbooks.brose.chapter15.management;

import java.util.Vector;
import java.util.Hashtable;
import java.awt.*;
import java.awt.event.*;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;

public class ManagerImpl
    extends ManagerPOA 
    implements ActionListener 
{
    /** GUI elements */
    private Button prepareButton;
    private Button shutdownButton;
    private Button getContextButton;
    private Button quitButton;

    private TextField ncTextField;
    private TextField cbTextField;

    private Panel mainPanel;

    /** manager objects */

    private java.awt.Container managementTool;
    private Manager manager;
    private ManagedServer managed;

    /** private bookkeeping */

    private Vector candidateObjects;
    private Vector selectedObjects;
    private Vector confirmedObjects;
    private Hashtable preparedObjects;

    private List candidateList;
    private List confirmedList;

    /** CORBA root objects */

    private org.omg.CORBA.Object obj;
    private NamingContextExt root;
    private NamingContextExt context;

    public ManagerImpl( java.awt.Container managementTool ) 
    {
        this.managementTool = managementTool;

        ORB orb = ORB.init( (String[])null, null);
        try
        {
            root = NamingContextExtHelper.narrow( orb.resolve_initial_references("NameService"));
        }
        catch( org.omg.CORBA.ORBPackage.InvalidName in ) 
        {
            System.err.println("Invalid Name");
        }

        selectedObjects = new Vector();
        confirmedObjects = new Vector();
        preparedObjects = new Hashtable();

        // create the GUI

        mainPanel = new Panel();

        Font HelveticaBold14 = new Font("Helvetica", Font.BOLD, 14);
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        mainPanel.setLayout(gridbag);
        c.fill = GridBagConstraints.BOTH;
        c.gridheight = 1;

        c.gridwidth = GridBagConstraints.REMAINDER;
        Label ncLabel = new Label("Naming Context", Label.CENTER );
        ncLabel.setFont( HelveticaBold14 );
        gridbag.setConstraints( ncLabel, c);
        mainPanel.add( ncLabel );

        c.gridwidth = GridBagConstraints.REMAINDER;
        ncTextField = new TextField();
        ncTextField.setFont( HelveticaBold14 );
        gridbag.setConstraints( ncTextField, c);
        mainPanel.add( ncTextField );

        c.gridwidth = GridBagConstraints.REMAINDER;
        getContextButton = new Button("List Naming Context");
        getContextButton.setActionCommand("getContext");
        getContextButton.addActionListener( this );
        getContextButton.setFont( HelveticaBold14 );
        gridbag.setConstraints( getContextButton, c);
        mainPanel.add( getContextButton );


        c.gridwidth = 1;
        Label ocLabel = new Label("Objects in Naming Context", Label.CENTER );
        ocLabel.setFont( HelveticaBold14 );
        gridbag.setConstraints( ocLabel, c);
        mainPanel.add( ocLabel );

        c.gridwidth = GridBagConstraints.REMAINDER;
        Label sdLabel = new Label("Objects Prepared for Shutdown", Label.CENTER );
        sdLabel.setFont( HelveticaBold14 );
        gridbag.setConstraints( sdLabel, c);
        mainPanel.add( sdLabel );


        c.gridwidth = 1;
        candidateList = new List( 5, false );
        candidateList.setFont( HelveticaBold14 );
        gridbag.setConstraints( candidateList, c);
        mainPanel.add( candidateList );

        c.gridwidth = GridBagConstraints.REMAINDER;
        confirmedList = new List( 5, false );
        confirmedList.setFont( HelveticaBold14 );
        gridbag.setConstraints( confirmedList, c);
        mainPanel.add( confirmedList );


        c.gridwidth = 1;
        prepareButton = new Button("Prepare Shutdown");
        prepareButton.setActionCommand("prepare");
        prepareButton.addActionListener( this );
        prepareButton.setFont( HelveticaBold14 );
        gridbag.setConstraints( prepareButton, c);
        mainPanel.add( prepareButton );

        c.gridwidth = GridBagConstraints.REMAINDER;
        shutdownButton = new Button("Shutdown");
        shutdownButton.setActionCommand("shutdown");
        shutdownButton.addActionListener( this );
        shutdownButton.setFont( HelveticaBold14 );
        gridbag.setConstraints( shutdownButton, c);
        mainPanel.add( shutdownButton );

        c.gridwidth = GridBagConstraints.REMAINDER;
        quitButton = new Button("Quit");
        quitButton.setActionCommand("quit");
        quitButton.addActionListener( this );
        quitButton.setFont( HelveticaBold14 );
        gridbag.setConstraints( quitButton, c);
        mainPanel.add( quitButton );

        managementTool.add( mainPanel );
        managementTool.validate();
    }

    /**
     *  confirmation operation, called back by managed servers 
     */

    public void shutdownConfirmation(  ManagedServer confirmedObject ) 
    {
        confirmedList.add( (String)preparedObjects.remove( confirmedObject.toString() ));
        selectedObjects.removeElement( (ManagedServer)confirmedObject );
        confirmedObjects.addElement( confirmedObject );
        managementTool.validate();
    }

    /**
     * Lists the contents of a naming context
     */

    public void getContext( String contextString ) 
    {
        if( contextString == null )
            return;

        try 
        {
            // get context
            context = 
                NamingContextExtHelper.narrow(root.resolve_str( contextString ) );
            
            candidateList.removeAll();
            candidateObjects = new Vector();

            // list bindings in context

            BindingListHolder blHolder = new BindingListHolder();
            BindingIteratorHolder biHolder = new BindingIteratorHolder();
            BindingHolder bHolder = new BindingHolder();
            ManagedServer m;
    
            context.list( 2, blHolder, biHolder );

            for( int i = 0; i < blHolder.value.length; i++ ) 
            {
                m = ManagedServerHelper.narrow(
                    context.resolve( blHolder.value[i].binding_name ) );
                if( m != null ) 
                {
                    candidateList.add( blHolder.value[i].binding_name[0].id );
                    candidateObjects.addElement( m );
                }
            }
            
            if( biHolder.value != null ) 
            {
                while( biHolder.value.next_one( bHolder ) ) 
                {
                    m = ManagedServerHelper.narrow(
                        context.resolve( bHolder.value.binding_name ) );
                    if( m != null ) 
                    {
                        candidateList.add( bHolder.value.binding_name[0].id );
                        candidateObjects.addElement( m );
                    }
                }
            }

            // be friendly with server resources
            if(  biHolder.value != null )
                biHolder.value.destroy();
        }
        catch( SystemException system_exception ) 
        { 
            System.err.println( system_exception.toString() ); 
        }
        catch( UserException naming_exception) 
        {
            ncTextField.setText( "context "+contextString+
                " not found, try again" );
        }
        managementTool.validate();
    }

    public void prepare() 
    {
        int selectedIndex = candidateList.getSelectedIndex();

        if( selectedIndex == -1 ) // no selection
            return;

        String name = candidateList.getItem( selectedIndex );

        System.out.println("Selection " + name );

        candidateList.remove( selectedIndex );
        
        managed = (ManagedServer)candidateObjects.elementAt( selectedIndex );

        preparedObjects.put( managed.toString(), name );

        candidateObjects.removeElementAt( selectedIndex );
        selectedObjects.addElement( managed );

        try 
        {
            managed.prepareShutdown( _this() );
        }
        catch(SystemException system_exception ) 
        { 
            // don't do anything, it's like to be stale entry
            // just remove name from the list which we do anyway
        }

        managementTool.validate();
    }



    public void shutdown() 
    {
        int selectedIndex = confirmedList.getSelectedIndex();

        if( selectedIndex == -1 ) // no selection
            return;

        try 
        {
            ((ManagedServer)confirmedObjects.elementAt( selectedIndex )).shutdown();
        }
        catch(SystemException system_exception ) 
        { 
            // don't do anything, object is already gone ...
        }

        confirmedList.remove( selectedIndex );
        confirmedObjects.removeElementAt( selectedIndex );

        managementTool.validate();
    }

    // catch and process events
    public void actionPerformed( ActionEvent ev ) 
    {
        if(ev.getActionCommand().equals("getContext"))
            getContext( ncTextField.getText() );

        if(ev.getActionCommand().equals("prepare"))
            prepare();

        if(ev.getActionCommand().equals("shutdown"))
            shutdown();

        if(ev.getActionCommand().equals("quit"))
            System.exit(0);
    }
}
