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

import java.io.*;

import org.omg.CORBA.*;
import com.wiley.compbooks.brose.chapter7.printing.PrinterPackage.*;

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

public class PrintClient {

    public static void main(String args[]) {
       
	if( args.length < 1 || args.length > 3 ) {
	    System.out.println(
	    "usage: PrintClient printfile [constraint [preference]]");
	    System.exit( 1 );
	}

	try {
	    //initialize the ORB and BOA
	    ORB orb = ORB.init( args, null );
	    org.omg.CORBA.Object obj = null;

	    // get reference to trader lookup interface
	    Lookup lookup = 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 not resolve Trading Service!");
                    System.exit(1);
                }
            }

		lookup = LookupHelper.narrow( obj );
	    if (lookup == null) {
	    	System.err.println("Null Trader Reference");
		System.exit(1);
	    }

	    // determine the constraint
	    String constr;
	    if( args.length > 1 ) {
		constr = args[1];
	    } else {
		constr = "";
	    }

	    // determine the prefs
	    String prefs;

	    if (args.length > 2 )
		prefs = args[2];
	    else
		// if no preference, compare the offers for shortest queue
		prefs = "min queue_len";

	    // set some basic policies
	    org.omg.CosTrading.Policy[] query_pols = 
                new org.omg.CosTrading.Policy[2];

	    //declare variables needed in the query() 
	    int num_offers = 3;
	    String serv_type_name ="Printer";

	    SpecifiedProps desired_props;
	    OfferSeqHolder return_offers = new OfferSeqHolder();
	    OfferIteratorHolder iter = new OfferIteratorHolder();
	    PolicyNameSeqHolder limits = new PolicyNameSeqHolder();
	
  	    // we want at most 3 offers back
	    Any card_policy_any = orb.create_any();
	    card_policy_any.insert_ulong( num_offers );
	    query_pols[0] = new org.omg.CosTrading.Policy("return_card", 
                                                          card_policy_any);

	    // we want to use dynamic props to find printer queue length
	    Any dynamic_policy_any = orb.create_any();
	    dynamic_policy_any.insert_boolean(true);
	    query_pols[1] = new org.omg.CosTrading.Policy("use_dynamic_properties", 
                                                          dynamic_policy_any);

	    // we want back only the name property
	    String[] desired_prop_names = new String[1];
	    desired_prop_names[0] = "name";
	    desired_props = new SpecifiedProps();
	    desired_props.prop_names(desired_prop_names);

	    // make a query
	    try {
		lookup.query( serv_type_name,
				constr,
				prefs,
				query_pols,
				desired_props,
				num_offers,
				return_offers,
				iter,
				limits);
	    }
	    // catch some important exceptions
	    catch (PolicyTypeMismatch pm) {
		System.err.println("Query failed - User Exception: " + pm );
		System.err.println("Erroneous policy: name " + pm.the_policy.name 
				   + " value: " + pm.the_policy.name);
		System.exit(1);
	    }
	    catch (IllegalPreference p) {
		System.err.println("Query failed - User Exception: " + p );
		System.err.println("Erroneous preference: name " + p.pref );
		System.exit(1);
	    }	    
            catch (UserException ue) {
		System.err.println("Query failed - User Exception: " + ue );
		System.exit(1);
	    }
	    catch (SystemException se) {
		System.err.println("Query failed: " + se);
		System.exit(1);
	    }

	    // send job to printer
	    int i = 0;
	    boolean printed = false;
	    String pname = "";

	    System.out.println("Got " +  return_offers.value.length + " offers." );

	    Any return_any = orb.create_any();

	    // we'll try all the returned printers until one works
	    while (i < return_offers.value.length && !printed) {
		try {
		    return_any = 
			return_offers.value[i].properties[0].value;
		    pname = return_any.extract_string();
		    Printer printer = 
			PrinterHelper.narrow(return_offers.value[i].reference);
	            if (printer == null) {
                        System.out.println("Printer " + pname + " not found");
                        i++;
		        continue;
	            }
		    printer.print_file( args[0] );
		    printed = true;
		    System.out.println("File " + args[0] +  
			" sent to printer " + pname);
		}
		catch (PrinterOffLine pol) {
		    System.out.println("Printer " + pname + " offline!");
		}
		catch (SystemException se) {
		    System.out.println("Printer " + pname + 
					" raised: " + se);
                    se.printStackTrace();
		}
		i++;
	    }
	    
	}
	catch (SystemException se) {
	    System.out.println(se);
	}
    }
}


								               
