
/**
 * RoomBookingBridgeImpl.java
 *
 *
 * Created: Wed Aug 25 22:54:38 1999
 *
 * @author Jan Newmarch
 * @version 1.0
 */
package corba.RoomBookingImpl;

import org.omg.CORBA.*;
import org.omg.CosNaming.*;
import corba.RoomBooking.*;
import corba.common.*;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Vector;

public class RoomBookingBridgeImpl extends UnicastRemoteObject implements RemoteRoomBookingBridge {

    private MeetingFactory meeting_factory;
    private Room[] rooms;
    private Meeting[] meetings;
    private ORB orb;
    private NamingContext room_context;
   
    public RoomBookingBridgeImpl(String[] args)
	throws RemoteException, UserException {
	try {
            // initialise the ORB
            orb = ORB.init(args, null);
        }
        catch(SystemException system_exception ) { 
            throw new RemoteException("constructor RoomBookingBridge: ",
				      system_exception); 
        }
	init_from_ns();
	update();
    }
    
    public void init_from_ns()
	throws RemoteException, UserException {

        // initialise from Naming Service
        try {
            // get room context
	    String str_name = "/BuildingApplications/Rooms/";
	    org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
	    NamingContext ncRef = NamingContextHelper.narrow(objRef);
	    NameComponent nc = new NameComponent(str_name,  " ");
	    NameComponent path[] = {nc};
    
	    org.omg.CORBA.Object roomRef = ncRef.resolve(path);
            room_context = NamingContextHelper.narrow(roomRef);
            if( room_context == null ) {
                System.err.println( "Room context is null," );
                System.err.println( "exiting ..." );
                System.exit( 1 );
            }
	    
            // get MeetingFactory from Naming Service
	    str_name = "/BuildingApplications/MeetingFactories/MeetingFactory";
	    nc = new NameComponent(str_name, " ");
	    path[0] = nc;
            meeting_factory = MeetingFactoryHelper.narrow(ncRef.resolve(path));
            if( meeting_factory == null ) {
                System.err.println(
                    "No Meeting Factory registred at Naming Service" );
                System.err.println( "exiting ..." );
                System.exit( 1 );
            }
        }
        catch(SystemException system_exception ) { 
	    throw new RemoteException("Initialise ORB", system_exception);
        }
    }

    public void update()
	throws RemoteException, UserException {

        try {
            // list rooms
            // initialise binding list and binding iterator
            // Holder objects for out parameter
            BindingListHolder blHolder = new BindingListHolder();
            BindingIteratorHolder biHolder = new BindingIteratorHolder();
            BindingHolder bHolder = new BindingHolder();
            Vector roomVector = new Vector();
            Room aRoom;
    
            // we are 2 rooms via the room list
            // more rooms are available from the binding iterator
            room_context.list( 2, blHolder, biHolder );

            // get rooms from Room context of the Naming Service
            // and put them into the roomVector
            for(int i = 0; i < blHolder.value.length; i++ ) {
                aRoom = RoomHelper.narrow(
                    room_context.resolve( blHolder.value[i].binding_name ));
                roomVector.addElement( aRoom );
            }

            // get remaining rooms from the iterator
            if( biHolder.value != null ) {
                while( biHolder.value.next_one( bHolder ) ) {
                    aRoom = RoomHelper.narrow(
                        room_context.resolve( bHolder.value.binding_name ) );
                    if( aRoom != null ) {
                        roomVector.addElement( aRoom );
                    }
                }
            }

            // convert the roomVector into a room array
            rooms = new Room[ roomVector.size() ];
            roomVector.copyInto( rooms );

            // be fiendly with system resources
            if(  biHolder.value != null )
                biHolder.value.destroy();
        }
    
        catch(SystemException system_exception) {
	    throw new RemoteException("View", system_exception);
            // System.err.println("View: " + system_exception); 
        }
    }

    public void cancel(int selected_room, int selected_slot)
	throws RemoteException, NoMeetingInThisSlot {
        try {
            rooms[selected_room].Cancel(
                Slot.from_int(selected_slot) );
            System.out.println("Cancel called" ); 
        }
        catch(SystemException system_exception) { 
	    throw new RemoteException("Cancel", system_exception);
        }
    }

    public void book(String purpose, String participants,
			int selected_room, int selected_slot) 
	throws RemoteException, SlotAlreadyTaken {
        try {
            Meeting meeting =
                meeting_factory.CreateMeeting(purpose, participants);
            System.out.println( "meeting created" );
            String p = meeting.purpose();
            System.out.println("Purpose: "+p);
            rooms[selected_room].Book(
                Slot.from_int(selected_slot), meeting );
            System.out.println( "room is booked" ); 
        }
        catch(SystemException system_exception ) { 
	    throw new RemoteException("Booking system exception", system_exception);
        }
    }

    /**
     * return a list of the rooms as portable JavaRooms
     */
    public JavaRoom[] getRooms() {
	int len = rooms.length;
	JavaRoom[] jrooms = new JavaRoom[len];
	for (int n = 0; n < len; n++) {
	    jrooms[n] = new JavaRoomImpl(rooms[n]);
	}
	return jrooms;
    }

    public JavaMeeting[] getMeetings(int room_index) {
	Meeting[] meetings = rooms[room_index].View();
	int len = meetings.length;
	JavaMeeting[] jmeetings = new JavaMeeting[len];
	for (int n = 0; n < len; n++) {
	    if (meetings[n] == null) {
		jmeetings[n] = null;
	    } else {
		jmeetings[n] = new JavaMeetingImpl(meetings[n], orb);
	    }
	}
	return jmeetings;
    }
} // RoomBookingBridgeImpl
