/*
 * PcSystemViewer.java
 *
 * Created on October 7, 2004, 11:21 AM
 */
import java.sql.*;
import java.util.*;
import java.io.*;

/** This is a non-extensible hack that implements a console mode 
 *  user interface to demonstrate the PCComponent class.
 *
 * @author  Timothy Paul Fox
 */
public class PcSystemViewer {
    private Vector systems;
    private ConsoleFormatter cf;
  
    private int waitForKey() {
        int key = 0;
        BufferedReader br = new BufferedReader(
                            new InputStreamReader(System.in), 1);
        try {
            if (br.ready()) {
                key = br.read();
            }
            else {
                try {
                    wait(125L); // 1/8 second
                }
                catch (Exception e){
                    notify(); // ???
                }
            }
        }
        catch (Exception e) { // an I/O exception
            return 0;
        }
        return key;
    } // end waitForKey
    
    /** Prints out a numbered list of items in the pcsystem table
     * @param con a Connection to the database that contains the PC System 
     * data tables.
     * @return true if the method was able to construct the numbered list.
     */
    public boolean getSystems(Connection con) {
        Statement stmt = null;
        ResultSet rslt = null;
        int bullet = 1;
        systems = new Vector();
        StringBuffer sysDescriptor;
        try {
            stmt = con.createStatement();
            rslt = stmt.executeQuery("SELECT * FROM pcsystem");
            while (rslt.next()) {
                sysDescriptor = new StringBuffer(rslt.getString("name"));
                System.out.println(
                    "" + bullet + ")\t" + sysDescriptor.toString());
                bullet++;
                sysDescriptor.append("\t");
                sysDescriptor.append(rslt.getString("prikey"));
                systems.add(sysDescriptor.toString());
            }
        }
        catch (Exception e) {
            System.out.println("\nProblem in getting System Names\n\n");
            return false;
        }
        finally {
            try {
                if (stmt != null) stmt.close();
            }
            catch (Exception e) { }
        }
        return true;
    } // end getSystems
    
    /** Shows a detailed list of parts and costs that comprise a
     * PC System.
     * @param systemIndex the index of the element in Vector
     * systems that identifies the PC System to be shown in detail.
     * @param con a Connection to the database that contains the
     * PC System data tables.
     */
    public void showSystem(int systemIndex, Connection con) {
        String pckey, expanded;
        int tabpos;
        PCComponent pcc;
        
        if (null == con || systemIndex > systems.size()) {
            System.out.println("\nProblem: Cannot show System list.\n");
            return;
        }
        // extract primary key from system descriptor
        pckey = (String) systems.elementAt(systemIndex);
        tabpos = pckey.indexOf('\t');
        pckey = pckey.substring(tabpos + 1);
        try {
            pcc = new PCComponent("pcsystem",  pckey, con);
            expanded = cf.expandTabbedString(pcc.toString());
            System.out.println(expanded);
            expanded = cf.expandTabbedString(
                "Total system cost = \u0002" + pcc.getCost());
            System.out.println("\n" + expanded);
        }
        catch (Exception e) { } // dummy
        System.out.print("Press Enter to continue ...");
        do {
        } while (0 == waitForKey());
    } // end showSystem
    
    /** Shows a list of PC Systems available for inspection.
     * @param con a Connection to the database that contains the
     * PC System data tables.
     */
    public void topMenu(Connection con) {
        int key = 0;
        do {
            System.out.println("\nPC System Catalog\n");
            if (false == getSystems(con))
                return;
            System.out.print(
            "\nTo view details of a PC system, press the number" +
            " then press Enter\n" +
            "\nto quit, press Q   --> ");
            // keyboard input loop
            do {
                key = waitForKey();
            } while (0 == key);
            switch (key) {
                case 'Q' : case 'q' :
                    key = 'Q';
                    break;
                case '1' :  case '2' :  case '3' :
                    showSystem(key - '1', con);
                    break;
                default :
                    // System.out.print('\u0007'); 
                    // bell? probably not ...
                    // What is the Java way of making noises?
            } // end switch
        } while (key != 'Q');
        System.out.println("\nGoodbye.\n");
    } // end topMenu
    
    /** instantiates a new SystemViewer
     */
    public PcSystemViewer() {
        cf = new ConsoleFormatter();
    }
    
    /** Startup code for the System Viewer. 
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        PcSystemViewer pcv = new PcSystemViewer();
        Connection con = null;
        String jdbcURL = "jdbc:mysql:///task2?user=root";
        String driverName = "com.mysql.jdbc.Driver";
        try { // load the driver
            Class.forName(driverName);
        }
        catch( Exception e ) {  // problem loading driver, 
                                // driver class doesn't exist?
            System.out.println(
            "\nERROR: Could not load the JDBC driver.\n\n" +
            "Before you try this program again, please make sure\n" +
            "the JDBC driver is present and that the system variables\n" + 
            "that describe the path to the driver have been defined.\n\n" +
            "(See your System Administrator.)\n\n");
            return;
        }
        try {
            con = DriverManager.getConnection(jdbcURL);
            pcv.topMenu(con);
        }
        catch( Exception e ) {  
            System.out.println(
            "\nERROR: Could not connect to the database.\n\n" +
            "Before you try this program again, please make sure\n" +
            "the database is running.\n\n");
            return;
        }
        try {
            if (null != con) con.close();
        }
        catch (Exception e) { }
    } // end main
    
}