package com.wiley.compbooks.brose.chapter10.office;

import java.util.*;
import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.PortableServer.*;

class DigitalSecretaryImpl
    extends DigitalSecretaryPOA
    implements java.io.Serializable
{
    /** the secretary's user */
    private String name;

    /** how the secretary can reach its user, an e-mail address */
    private String contact_data;
    
    /** the meeting diaries array, indexed by year and month */
    private Diary diary;

    /** the transient part of this serializable object
	needs to be initialized both after creating and
	every time the object is reread from a stream
    */

    private transient ORB orb;

    private transient NamingContextExt naming;
    private transient MeetingFactory meetingFactory;

    private transient String [] locations;
    private transient String [] buildingNames;
    private transient String [] secretaryNames;
    private transient Hashtable locationTable;
    private transient DigitalSecretary _this;

    public DigitalSecretaryImpl(String name, String contact_data, ORB orb)
    {
	this.name = name;
	this.contact_data = contact_data;
	this.orb = orb;
	diary = new Diary(orb);
    }
    
    /** 
	needs to be initialized both after creating and
	every time the object is reread from a stream
    */
    
    public void init(POA myPOA, NamingContextExt naming, ORB orb)
	throws NotFound, CannotProceed
    {
	this.naming = naming;
	try
	{
	    _this = DigitalSecretaryHelper.narrow( myPOA.servant_to_reference( this ));
	    meetingFactory = 
		MeetingFactoryHelper.narrow( naming.resolve( naming.to_name( "MeetingService" )));
	    
	    NamingContextExt roomContext = 
		NamingContextExtHelper.narrow(naming.resolve( naming.to_name( "RoomService" )));	    
	    secretaryNames = findBindings( naming, ".secretary" );	   
	    buildingNames = findBindings( roomContext, null );

	    locationTable = new Hashtable();
	    for( int i = 0; i < buildingNames.length; i++ )
	    {
		Building roomFactory = BuildingHelper.narrow( 
					      roomContext.resolve( 
					          roomContext.to_name( buildingNames[i] )));
		Room [] rooms = roomFactory.list();
		for( int j = 0; j < rooms.length; j++ )
		{
		    String locname = ( buildingNames[i] + ":" + rooms[j].name());
		    locationTable.put( locname, rooms[j] );
		}
	    }
	    Enumeration locs = locationTable.keys();
	    locations = new String[locationTable.size()];
	    for( int i = 0; locs.hasMoreElements(); i++ )
	    {
		locations[i] = (String)locs.nextElement();
	    }
	    diary.init(orb);
	}
	catch( Exception in )
	{
	    in.printStackTrace();
	}
    }


    public String name()
    {
	return name;
    }

    private void sendEMail(String to, String message)
    {
	System.out.println("Got notification: " + message );
    }

    public void notifyUser(String msg)
    {
	sendEMail(contact_data, msg);
    }

    public void invite(Meeting a_meeting) 
	throws AlreadyEngaged
    {
	 notifyUser("You have been invited to join a meeting " + a_meeting.purpose() );
    }

    public String [] secretaryNames()
    {
	return secretaryNames;
    }

    public String [] buildingNames()
    {
	return buildingNames;
    }

    public String[] getLocations()
    {
	return locations;
    }

    public MeetingFactory getMeetingService()
    {
	return meetingFactory;
    }

    Diary getDiary()
    {
	return diary;
    }

    Meeting scheduleMeeting( String[] meetingData, Date currentDate )
    {
	Date when = new Date( currentDate.the_year, 
			      currentDate.the_month, 
			      currentDate.the_day, 
			      Short.parseShort( meetingData[2] ));
	Meeting m = null;
	try
	{

	    m = meetingFactory.create(meetingData[0],
				      (Room)locationTable.get( meetingData[1]),
				      when, 
				      _this,
				      new DigitalSecretary[] {
					  DigitalSecretaryHelper.narrow( 
									naming.resolve(
										       naming.to_name( meetingData[3] + ".secretary" )))}
				      );
	    if( m != null )	
		diary.enter(when, m );
	}
	catch( Exception e )
	{
	    e.printStackTrace();
	}
	return m;
    }




    public String[] findBindings( NamingContextExt n, String suffix)
    {
	StringBuffer sb = new StringBuffer();
	Vector list = new Vector();

	list( n, list, suffix );
	String[] others = new String[ list.size() ];
	list.copyInto( others );
	return others;
    }

    /**
     * Find all bindings in context n that have suffix
     * a null suffix matches all bindings
     */

    private void list( NamingContextExt n, Vector v, String suffix )
    {
	try 
	{
	    BindingListHolder blsoh = 
		new BindingListHolder(new Binding[0]);
	    BindingIteratorHolder bioh = 
		new BindingIteratorHolder();

	    n.list( 0, blsoh, bioh );

	    BindingHolder bh = new BindingHolder();

	    if( bioh.value == null )
		return; 

	    while( bioh.value.next_one( bh )) 
	    {
		String stringName = n.to_string( bh.value.binding_name);
		if( suffix == null )
		{
		    v.addElement( stringName );
		}	
		else if(stringName.endsWith( suffix ))
		{
		    v.addElement( stringName.substring(0,stringName.indexOf(suffix)) );
		}

		if( bh.value.binding_type.value() == BindingType._ncontext ) {
		    
		    NameComponent [] name = n.to_name(stringName);
		    NamingContextExt sub_context = 
			NamingContextExtHelper.narrow(n.resolve(name));
		    list(sub_context,v, suffix);
		}
		else
		    System.out.println();
	    }
	} 
	catch (Exception e) 
	{
	    e.printStackTrace();
	}
    }


}

