package example.corba;

import java.io.*;
import java.sql.*;
import org.omg.CosNaming.*;

/*
 * This class is the frontend to our mini CORBA application.
 *
 * It has no GUI, just a text frontend to keep it simple.
 *
 * $PostgreSQL: pgjdbc/example/corba/StockClient.java,v 1.8 2004/11/09 08:43:10 jurka Exp $
 */
public class StockClient
{
    org.omg.CosNaming.NamingContext nameService;

    stock.StockDispenser dispenser;
    stock.StockItem item;

    BufferedReader in;

    public StockClient(String[] args)
    {
        try
        {
            // We need this for our IO
            in = new BufferedReader(new InputStreamReader(System.in));

            // Initialize the orb
            org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);

            // Get a reference to the Naming Service
            org.omg.CORBA.Object nameServiceObj = orb.resolve_initial_references("NameService");
            if (nameServiceObj == null)
            {
                System.err.println("nameServiceObj == null");
                return ;
            }

            nameService = org.omg.CosNaming.NamingContextHelper.narrow(nameServiceObj);
            if (nameService == null)
            {
                System.err.println("nameService == null");
                return ;
            }

            // Resolve the dispenser
            NameComponent[] dispName = {
                                           new NameComponent("StockDispenser", "Stock")
                                       };
            dispenser = stock.StockDispenserHelper.narrow(nameService.resolve(dispName));
            if (dispenser == null)
            {
                System.err.println("dispenser == null");
                return ;
            }

            // Now run the front end.
            run();
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
            e.printStackTrace();
            System.exit(1);
        }
    }

    public static void main(String[] args)
    {
        new StockClient(args);
    }

    public void run()
    {
        // First reserve a StockItem
        try
        {
            item = dispenser.reserveItem();
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
            e.printStackTrace();
            System.exit(1);
        }

        mainMenu();

        // finally free the StockItem
        try
        {
            dispenser.releaseItem(item);
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
            e.printStackTrace();
            System.exit(1);
        }
    }

    private void mainMenu()
    {
        boolean run = true;
        while (run)
        {
            System.out.println("\nCORBA Stock System\n");
            System.out.println("  1 Display stock item");
            System.out.println("  2 Remove item from stock");
            System.out.println("  3 Put item into stock");
            System.out.println("  4 Order item");
            System.out.println("  5 Display all items");
            System.out.println("  0 Exit");
            int i = getMenu("Main", 5);
            switch (i)
            {
            case 0:
                run = false;
                break;

            case 1:
                displayItem();
                break;

            case 2:
                bookOut();
                break;

            case 3:
                bookIn();
                break;

            case 4:
                order(0);
                break;

            case 5:
                displayAll();
                break;
            }
        }
    }

    private void displayItem()
    {
        try
        {
            int id = getMenu("\nStockID to display", item.getLastID());
            if (id > 0)
            {
                item.fetchItem(id);
                System.out.println("========================================");

                String status = "";
                if (!item.isItemValid())
                    status = " ** Superceded **";

                int av = item.getAvailable();

                System.out.println("      Stock ID: " + id + status +
                                   "\nItems Available: " + av +
                                   "\nItems on order: " + item.getOrdered() +
                                   "\n   Description: " + item.getDescription());
                System.out.println("========================================");

                if (av > 0)
                    if (yn("Take this item out of stock?"))
                    {
                        int rem = 1;
                        if (av > 1)
                            rem = getMenu("How many?", av);
                        if (rem > 0)
                            item.removeStock(rem);
                    }

            }
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
            e.printStackTrace();
        }
    }

    private void bookOut()
    {
        try
        {
            int id = getMenu("\nStockID to take out", item.getLastID());
            if (id > 0)
            {
                item.fetchItem(id);
                int av = item.getAvailable();
                if (av > 0)
                    if (yn("Take this item out of stock?"))
                    {
                        int rem = 1;
                        if (av > 1)
                            rem = getMenu("How many?", av);
                        if (rem > 0)
                            item.removeStock(rem);
                    }
                    else
                    {
                        System.out.println("This item is not in stock.");
                        int order = item.getOrdered();
                        if (order > 0)
                            System.out.println("There are " + item.getOrdered() + " items on order.");
                        else
                        {
                            if (item.isItemValid())
                            {
                                System.out.println("You will need to order some more " + item.getDescription());
                                order(id);
                            }
                            else
                                System.out.println("This item is now obsolete");
                        }
                    }
            }
            else
                System.out.println(item.getDescription() + "\nThis item is out of stock");
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
            e.printStackTrace();
        }
    }

    // book an item into stock
    private void bookIn()
    {
        try
        {
            int id = getMenu("\nStockID to book in", item.getLastID());
            item.fetchItem(id);
            System.out.println(item.getDescription());

            if (item.getOrdered() > 0)
            {
                int am = getMenu("How many do you want to book in", item.getOrdered());
                if (am > 0)
                    item.addNewStock(am);
            }
            else
                System.out.println("You don't have any of this item on ordered");

        }
        catch (Exception e)
        {
            System.out.println(e.toString());
            e.printStackTrace();
        }
    }

    // Order an item
    private void order(int id)
    {
        try
        {
            if (id == 0)
                id = getMenu("\nStockID to order", item.getLastID());
            item.fetchItem(id);
            System.out.println(item.getDescription());
            int am = getMenu("How many do you want to order", 999);
            if (am > 0)
                item.orderStock(am);
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
            e.printStackTrace();
        }
    }

    private void displayAll()
    {
        try
        {
            boolean cont = true;
            int nr = item.getLastID();
            String header = "\nId\tAvail\tOrdered\tDescription";
            System.out.println(header);
            for (int i = 1;i <= nr && cont;i++)
            {
                item.fetchItem(i);
                System.out.println("" + i + "\t" + item.getAvailable() + "\t" + item.getOrdered() + "\t" + item.getDescription());
                if ((i % 20) == 0)
                {
                    if ((cont = yn("Continue?")))
                        System.out.println(header);
                }
            }
        }
        catch (Exception e)
        {
            System.out.println(e.toString());
            e.printStackTrace();
        }
    }

    private int getMenu(String title, int max)
    {
        int v = -1;
        while (v < 0 || v > max)
        {
            System.out.print(title);
            System.out.print(" [0-" + max + "]: ");
            System.out.flush();
            try
            {
                v = Integer.parseInt(in.readLine());
            }
            catch (Exception nfe)
            {
                v = -1;
            }
        }
        return v;
    }

    private boolean yn(String title)
    {
        try
        {
            while (true)
            {
                System.out.print(title);
                System.out.flush();
                String s = in.readLine();
                if (s.startsWith("y") || s.startsWith("Y"))
                    return true;
                if (s.startsWith("n") || s.startsWith("N"))
                    return false;
            }
        }
        catch (Exception nfe)
        {
            System.out.println(nfe.toString());
            nfe.printStackTrace();
            System.exit(1);
        }
        return false;
    }
}
