package com.wiley.compbooks.brose.chapter7.printing;

import java.io.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.*;

import org.omg.CosTrading.*;
import org.omg.CosTrading.Register.*;
import org.omg.CosTrading.RegisterPackage.*;
import org.omg.CosTradingRepos.*;
import org.omg.CosTradingRepos.ServiceTypeRepositoryPackage.*;
import org.omg.CosTradingDynamic.*;

import com.wiley.compbooks.brose.chapter7.printing.PrinterPackage.*;

public class PrinterServer 
{
    static final int NAME = 0;
    static final int BUILDING = 1;
    static final int FLOOR = 2;
    static final int RESOLUTION = 3;
    static final int QUEUE_LEN = 4;
    static final int COLOR = 5;
    static final int LANGUAGE = 6;

    public static void main (String[] args) {

        int num_printers;
        PrinterImpl [] printers;
        String printer_name;

        if( args.length < 4 || args.length % 4 != 2) {
            System.out.println("Usage: vbj com.wiley.compbooks.brose.chapter7.printing.PrintServer print_command queue_len_command name resolution building floor [ name res build floor ... ]");
            System.exit (1);

	}

        // allocate an array to store Printer Implementation Objects

        num_printers = (args.length - 2) / 4;
        printers = new PrinterImpl[num_printers];

        int i;

        try {
            //initilize the Object Request Broker and Portable Object Adapter

            ORB orb = ORB.init(args, null);
            POA poa = POAHelper.narrow( orb.resolve_initial_references("RootPOA"));

	    poa.the_POAManager().activate();

            // Trader object reference declarations
            Lookup              lookup;
            Register            register;
            ServiceTypeRepository       st_repos;

            // get the trader reference 
            // and initialise the ServiceTypeRepository and Register
            // interface references from the initial Lookup interface

            org.omg.CORBA.Object obj = null;
            try 
            {
                obj = orb.resolve_initial_references("TradingService");
            } 
            catch ( org.omg.CORBA.ORBPackage.InvalidName in )
            {
                try {
                    String ior = new BufferedReader(new FileReader("Trader.ior")).readLine();
                    obj = orb.string_to_object( ior );
                }
                catch( Exception e )
                {
                    System.err.println("Could no resolve Trading Service!");
                    System.exit(1);
                }
            }
	    

            lookup = LookupHelper.narrow(obj);
            if (lookup == null) {
                System.err.println("Lookup narrowed incorrectly");
                System.exit(1);
            }
            System.out.println("lookup narrowed");

            register = lookup.register_if();
            System.out.println("register obtained");

            obj = register.type_repos();
            st_repos = ServiceTypeRepositoryHelper.narrow(obj);
            if (st_repos == null) {
                System.err.println("ServiceTypeRepository narrowed incorrectly");
                System.exit(1);
            }
            System.out.println("st_repos narrowed");

            // check for Service Type existence
            // and create a new Service Type if it does not exist

            boolean type_exists = false;
            String repos_id = "IDL:com/wiley/compbooks/vogel/chapter7/Printing/Printer:1.0";
            String serv_type_name = "Printer";
            IncarnationNumber incarn_num;

            TypeStruct type_desc;
            try {
                type_desc = st_repos.describe_type(serv_type_name);
                System.out.println("called describe_type - returned typedesc");
                type_exists = true;
            }
            catch (UnknownServiceType ust) {
                System.out.println("called describe_type - raised UnknownServiceType");
                type_exists = false;
            }
            catch (IllegalServiceType ist) {
                System.err.println(ist);
                System.exit (1);
            }
            catch (SystemException se) {
                System.err.println(se);
                System.exit (1);
            }

            if (! type_exists) {
                System.out.println("service type does not exist");

                // we will create a new service type

                // create a prop stuct list with the property names
                // for a printer service type

                PropStruct[] st_props = new PropStruct[7];
                st_props[NAME] = new PropStruct( "name",
						 orb.create_string_tc(0),
						 PropertyMode.PROP_MANDATORY);

                st_props[BUILDING] = new PropStruct( "building",
						     orb.create_string_tc(0),
						     PropertyMode.PROP_MANDATORY);

                st_props[FLOOR] = new PropStruct("floor",
						 orb.get_primitive_tc(TCKind.tk_short),
						 PropertyMode.PROP_MANDATORY);

                st_props[RESOLUTION] = new PropStruct("resolution",
						      orb.get_primitive_tc(TCKind.tk_short),
						      PropertyMode.PROP_MANDATORY);

                st_props[QUEUE_LEN] = new PropStruct( "queue_len",
						      orb.get_primitive_tc(TCKind.tk_short),
						      PropertyMode.PROP_MANDATORY);

                st_props[COLOR] = new PropStruct("color",
						 orb.create_string_tc(0),
						 PropertyMode.PROP_MANDATORY);

                st_props[LANGUAGE] = new PropStruct( "language",
						     orb.create_string_tc(0),
						     PropertyMode.PROP_MANDATORY);

                
                // create an empty super type list

                String[] super_types = new String[0];

                // add the new Service Type
                // we use the Interface Type string as the service
                // type name
                System.out.println("about to add_type");
                incarn_num = st_repos.add_type( serv_type_name,
                                                repos_id,
                                                st_props,
                                                super_types);
                System.out.println("Created Service Type:" +
				   serv_type_name);
                System.out.println("Incarnation Number: high=" +
				   incarn_num.high);
                System.out.println("                     low=" +
				   incarn_num.low);
            } 
            // create Service Offer Property Seq to use for export
            Property[] so_props = new Property[7];

            // create a Dynamic Property for queue length evaluation
            DynamicProp queue_prop = 
		new DynamicProp(null,
				orb.get_primitive_tc(TCKind.tk_short),
				orb.create_any());

            // The first 5 properties will be different for each
            // printer, so we initialize them in the loop below

            so_props[NAME] = new Property( "name", orb.create_any());
            so_props[BUILDING] = new Property( "building", orb.create_any());
            so_props[FLOOR] = new Property( "floor", orb.create_any());
            so_props[RESOLUTION] = new Property( "resolution", orb.create_any());
            so_props[QUEUE_LEN] = new Property( "queue_len", orb.create_any());

            // the last two properties' values are assumed by this server
            // so we initialize them for all printers

            so_props[COLOR] = new Property( "color", orb.create_any());
            so_props[COLOR].value.insert_string("black");
            so_props[LANGUAGE] = new Property( "language", orb.create_any());
            so_props[LANGUAGE].value.insert_string("postscript");

            // create printer object(s) and export

            for (i = 0; i < num_printers; i++) {

                System.out.println("about to create printer");
                // create a Printer object and register it with the POA
                printers[i] = new PrinterImpl(
					      args[0],
					      args[1],
					      args[i*4 + 2],
					      orb.get_primitive_tc(TCKind.tk_short)
					      );
		//		printers[i]._orb( orb );

		org.omg.CORBA.Object printerObject = 
		    poa.servant_to_reference( printers[i] );


                System.out.println("Printer IOR: " +
				   orb.object_to_string(printerObject));

                System.out.println("Created printer: " + args[i*4 + 2]);
                // initialize the properties we get from the command line

                // name
                so_props[NAME].value.insert_string(args[i*4 + 2]);

                // resolution
                System.out.println("Resolution: " + args[i*4 + 3]);
                so_props[RESOLUTION].value.insert_short(Short.parseShort(args[i*4 + 3]));

                // building
                System.out.println("Building: " + args[i*4 + 4]);
                so_props[BUILDING].value.insert_string(args[i*4 + 4]);

                // floor
                System.out.println("Floor: " + args[i*4 + 5]);
                so_props[FLOOR].value.insert_short(Short.parseShort(args[i*4 + 5]));

                // update the dynamic prop struct and insert into
                // the queue_len property of the service offer
                queue_prop.eval_if = DynamicPropEvalHelper.narrow( printerObject );
                DynamicPropHelper.insert(so_props[QUEUE_LEN].value,
                                         queue_prop);


                // export the service offer
                System.out.println("about to export");
                register.export(printerObject,
                                serv_type_name,
                                so_props);

                System.out.println("Exported printer: " + args[i*4 + 2]);
            } // end for loop

            // take requests for our printers
            orb.run();
        }
        catch (PropertyTypeMismatch pm) {
            System.err.println(pm);
            System.err.println(pm.type);
            System.err.println(pm.prop.name);
            System.err.println(pm.prop.value);
        }
        catch (NumberFormatException ne) {
            System.err.println("Badly formatted numeric argument");
            System.err.println(ne);
            System.exit (1);
        }
        catch (UserException ue) {
            System.err.println("User exception caught");
	    ue.printStackTrace();
            System.exit (1);
        }
        catch (SystemException se) {
            System.err.println("System exception caught");
	    se.printStackTrace();
            System.err.println(se);
            System.exit (1);
        }
    }
}











