package examples.applets;

import java.awt.*;
import java.net.*;
import java.applet.*;
import java.util.Vector;

import java.util.Properties;
import java.sql.*;
import java.awt.event.*;

import weblogic.common.*;
import weblogic.db.jdbc.*;
import weblogic.common.internal.*;

/**
 * This applet demonstrates how to use a WebLogic jDriver JDBC
 * driver and WebLogic JDBC to retrieve and display
 * database data.
 *
 * <p>
 * To use this example, you'll need a phone book database named CUSTOMER
 * with fields CUSTID, NAME, ADDRESS, CITY, STATE, ZIP, AREA, PHONE
 * The HTML page for calling this applet is <tt>phonebook1.html</tt>.
 *
 * @author     Copyright (c) 1996-2000 BEA Systems, Inc. All Rights Reserved.
 */
public class PhoneBook1 extends Applet implements ItemListener {

  Connection         conn;
  QueryDataSet       ds;
  int                spacing     = 2;
  boolean            hadproblem  = false;
  PhoneBookControls  controls    = new PhoneBookControls(this);
  PhoneBookFields    fields      = new PhoneBookFields(this);
  GridBagConstraints c           = new GridBagConstraints();
  GridBagLayout      gridbag     = new GridBagLayout();
  List               list        = new List(10, false);
  int                currentRecN = 0;

  /**
   * Init method for the applet sets the layout (a gridbag) and adds
   * fields and controls. The real work of the method is enclosed
   * within a <tt>try</tt> block, where one
   * <tt>java.util.Properties</tt> object is created and used to set
   * properties for connecting the WebLogic Server and the database, and
   * another Properties object is created and used to set other
   * properties used by the multiter connection. Then a dbKona
   * QueryDataSet is created with the results of a SQL query, and its
   * records are displayed. The JDBC connection is closed in the
   * <tt>finally</tt> block.
   * <p>
   * To run this example, adjust these applet parameters in the
   * file <tt>phonebook1.html</tt>: set "dbserver"
   * to the name of your database, and set
   * "weblogicurl" to the name and port of your WebLogic Server.
   */
  public void init() {
    
    setLayout(gridbag);

    c.fill      = GridBagConstraints.BOTH;
    c.weighty   = 1.0;
    c.gridwidth = GridBagConstraints.REMAINDER;
    c.weightx   = 1.0;

    list.addItemListener((ItemListener)this);
    gridbag.setConstraints(list, c);
    list.setMultipleMode(false);
    add(list);
    c.fill = GridBagConstraints.HORIZONTAL;
    gridbag.setConstraints(fields, c);
    add(fields);
    gridbag.setConstraints(controls, c);
    add(controls);

    String failHow = null;
    try {
      failHow = "getParameter";
      String poolname = getParameter("poolname");
      String wurlS = getParameter("weblogic_url");
      if (poolname == null || wurlS == null)
        throw new Exception("'poolname' parameter from html page is missing");
      
      /* Note: You can use the WebLogicPreLoader class to ensure that all
       * the necessary WebLogic JDBC classes are downloaded by another thread
       * when your applet is initialized. This is useful when an applet makes
       * interactive calls to the database, so that the operation is smooth since 
       * all required classes are readily available. 
       * 
       * Since this applet downloads all of the information at initialization, 
       * it not benefit from using the WebLogicPreLoader, but it is included here 
       * (commented out) to demonstrate how you might use it in your applets.
       */
      
      // WebLogicPreLoader wlpl = new WebLogicPreLoader(wurlS);
      // new Thread(wlpl).start();
      
      failHow = "put t3props";
      Properties t3props = new Properties();
      t3props.put("weblogic.t3.connectionPoolID", poolname);
      t3props.put("weblogic.t3.serverURL",        wurlS);

      failHow = "getConnection";
      Class.forName("weblogic.jdbc.t3.Driver").newInstance();
      conn = DriverManager.getConnection("jdbc:weblogic:t3", t3props);

      failHow = "Query Fetch";
      ds = new QueryDataSet(conn,
                            "select CUSTID, NAME, ADDRESS, "
                            + "CITY, STATE, ZIP, AREA, PHONE from CUSTOMER");
      ds.fetchRecords();

      // Retrieve the entire dataset
      failHow = "list.addItem";
      int maxwidth[]  = ds.maxColumnWidths(false);
      for (int i = 0; i < ds.size(); i++) {
        list.addItem(ds.getRecord(i).asFormattedString(" ", maxwidth));
      }
      failHow = "ShowFirst";
      ShowFirst();
    }

    catch (Exception e) {
      this.hadproblem = true;
      this.resize(600, 25);
      e.printStackTrace();
      if (fields != null)
        fields.SetStatus("init failed " + failHow + ", " + e);
    }

    finally {
      //  No more talking to the server, the applet just shows local data in "list":
      try {conn.close();}    catch (Exception e) {;}
    }
  }

  /**
   * The JDBC connection is closed in a <tt>try</tt>
   * block in the applet <tt>finalize()</tt> method.
   */
  public void finalize() {
    try {conn.close();}    catch (Exception e) {;}
  }

  /**
   * Controls are enabled in the applet
   * <tt>start()</tt> method.
   */
  public void start() {
    controls.setEnabled(true);
  }

  /**
   * Controls are disabled in the
   * applet <tt>stop()</tt> method.
   */
  public void stop() {
    controls.setEnabled(false);
  }

  /**
   * This method sets the current record to the
   * first record and selects it to show.
   */
  public void ShowFirst() {
    if (hadproblem)  return;
    currentRecN = 0;
    this.list.deselect(this.list.getSelectedIndex());
    this.list.select(this.currentRecN);
    ShowRecordNo(this.currentRecN);
  }

  /**
   * This method sets the current record to the
   * previous record and selects it to show.
   */
  public void ShowPrev() {
    if (hadproblem)  return;
    this.currentRecN = (this.currentRecN > 0) ? this.currentRecN - 1 : 0;
    this.list.deselect(this.list.getSelectedIndex());
    this.list.select(this.currentRecN);
    ShowRecordNo(this.currentRecN);
  }

  /**
   * This method sets the current record to the
   * next record and selects it to show.
   */
  public void ShowNext() {
    if (hadproblem)  return;
    this.currentRecN = ((ds.size() -1) > this.currentRecN) ? this.currentRecN + 1 : ds.size() - 1;
    this.list.deselect(this.list.getSelectedIndex());
    this.list.select(currentRecN);
    ShowRecordNo(this.currentRecN);
  }

  /**
   * This method sets the current record to the
   * last record and selects it to show.
   */
  public void ShowLast() {
    if (hadproblem)  return;
    this.currentRecN = ds.size()-1;
    this.list.deselect(this.list.getSelectedIndex());
    this.list.select(this.currentRecN);
    ShowRecordNo(this.currentRecN);
  }

  /**
   * Shows a record.
   */
  public void ShowRecordNo(int index) {
    if (hadproblem)  return;
    try {
      // this.list.deselect(index);
      fields.ShowRecord(ds.getRecord(index));
    }
    catch (Exception e) {
      this.hadproblem = true;
    }
    this.currentRecN = index;
  }

  /**
   * Handles select events by showing a record.
   */
  public void itemStateChanged(ItemEvent ev) {
    if (ev.getID() == Event.LIST_SELECT) {
      ShowRecordNo(list.getSelectedIndex());
    }
  }

  /**
   * The main creates a new
   * applet, initializes and starts it,
   * and then adds the applet to a new frame.
   */
  public static void main(String args[]) {
    Frame f = new Frame("PhoneBook");
    PhoneBook1	PhoneBook = new PhoneBook1();

    PhoneBook.init();
    PhoneBook.start();

    f.add("Center", PhoneBook);
    f.setSize(500, 600);
    f.show();
  }
}


class PhoneBookControls extends Panel implements ActionListener{
  PhoneBook1 parent;
  Button First;
  Button Prev;
  Button Next;
  Button Last;

  public PhoneBookControls(PhoneBook1 pb) {
    parent = pb;
    add(First = new Button("First"));
    First.addActionListener(this);
    add(Prev = new Button("<<"));
    Prev.addActionListener(this);
    add(Next = new Button(">>"));
    Next.addActionListener(this);
    add(Last = new Button("Last"));
    Last.addActionListener(this);
  }

  public void actionPerformed(ActionEvent ev) {
   
   if ((ev.getSource() instanceof Button)) {
      
       try {
           if (ev.getSource() == First) {
               parent.ShowFirst();
           }
           else if (ev.getSource() == Prev) {
               parent.ShowPrev();
           }
           else if (ev.getSource() == Next) {
               parent.ShowNext();
           }
           else if (ev.getSource() == Last) {
               parent.ShowLast();
           }
       }
       catch (Exception e) {
           if (parent.fields != null)
               parent.fields.SetStatus("action got " + e);
       }
    }
  }
}

class PhoneBookFields extends Panel {
  PhoneBook1 parent;
  TextField id;
  TextField name;
  TextField address;
  TextField city;
  TextField state;
  TextField zip;
  TextField area;
  TextField phone;
  TextField status;
  GridBagLayout      gridbag = new GridBagLayout();
  GridBagConstraints c       = new GridBagConstraints();

  private void addLabel(String text, GridBagConstraints constraints) {
    constraints.gridwidth = 1;
    constraints.anchor    = GridBagConstraints.EAST;
    Label lbl             = new Label(text,Label.RIGHT);
    gridbag.setConstraints(lbl, constraints);
    add(lbl);
  }

  private TextField addTextField(int size, GridBagConstraints constraints) {
    constraints.gridwidth = GridBagConstraints.REMAINDER;
    constraints.anchor    = GridBagConstraints.WEST;
    TextField field       = new TextField(size);
    gridbag.setConstraints(field, constraints);
    add(field);
    return field;
  }

  /**
   * Sets up the fields and labels for the
   * GUI.
   */
  public PhoneBookFields(PhoneBook1 pb) {
    parent = pb;
    setLayout(gridbag);

    c.insets = new Insets(10,10,10,10);
    c.weighty = 1.0;
    c.weightx = 1.0;

    addLabel("ID", c);
    id = addTextField(10, c);
    addLabel("Name", c);
    name = addTextField(40, c);
    addLabel("Address", c);
    address = addTextField(40, c);
    addLabel("City", c);
    city = addTextField(30, c);
    addLabel("State", c);
    state = addTextField(20, c);
    addLabel("Zip", c);
    zip = addTextField(10, c);
    addLabel("Area", c);
    area = addTextField(3, c);
    addLabel("Phone", c);
    phone = addTextField(9, c);
    addLabel("Status", c);
    status = addTextField(50, c);
  }

  /**
   * Clears the fields.
   */
  public void ClearFields(String statStr) {
    id.setText("");
    name.setText("");
    address.setText("");
    city.setText("");
    state.setText("");
    zip.setText("");
    area.setText("");
    phone.setText("");
    status.setText(statStr);
  }

  public void SetStatus(String statStr)
  {
    status.setText(statStr);
  }

  /**
   * Shows a record.
   */
  public void ShowRecord(Record r) {
    try {
      id.setText(r.getValue("CUSTID").asString());
      name.setText(r.getValue("NAME").asString());
      address.setText(r.getValue("ADDRESS").asString());
      city.setText(r.getValue("CITY").asString());
      state.setText(r.getValue("STATE").asString());
      zip.setText(r.getValue("ZIP").asString());
      area.setText(r.getValue("AREA").asString());
      phone.setText(r.getValue("PHONE").asString());
      status.setText("record successfully shown");
    }
    catch (Exception e) {
      ClearFields("ShowRecord got " + e);
    }
  }


}

