
/**
 * Title:        GUI Orthogonal Array<p>
 * Description:  Provides a GUI that constructs a file that holds a standard
 * orthogonal array<p>
 * Copyright:    Copyright (c) 2000<p>
 * Company:      mctest<p>
 * @author John D. McGregor
 * @version 1.0
 */

/*
The OATS Orthognal Array Test Design Tool
Copyright (C) 2000  McTest

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

package oats;

import java.util.*;
import java.io.*;
import javabook2.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class GUIOrthogonalArray extends JFrame
    implements ActionListener
{
  /**
   * Constructor sets up the menu structure
   */
  public GUIOrthogonalArray() {
    setTitle("Orthogonal Array Builder");
    setSize(500,500);
    menuBar = new JMenuBar();
    setJMenuBar(menuBar);
    functionMenu = new JMenu("Functions");
    displayItem = new JMenuItem("Display array");
    readItem = new JMenuItem("Construct array");
    loadItem = new JMenuItem("Load existing array");
    importItem = new JMenuItem("Import blank-delimited array");
    saveItem = new JMenuItem("Save");
    printItem = new JMenuItem("Print");
    exitItem = new JMenuItem("Exit");
    editItem = new JMenuItem("Edit");
    displayItem.addActionListener(this);
    readItem.addActionListener(this);
    exitItem.addActionListener(this);
    editItem.addActionListener(this);
    printItem.addActionListener(this);
    loadItem.addActionListener(this);
    importItem.addActionListener(this);
    saveItem.addActionListener(this);
    functionMenu.add(readItem);
    functionMenu.add(displayItem);
    functionMenu.add(loadItem);
    functionMenu.add(importItem);
    functionMenu.add(saveItem);
    functionMenu.add(editItem);
    functionMenu.add(printItem);
    functionMenu.add(exitItem);
    menuBar.add(functionMenu);
  }

  /**
   * This method fires off the individual menu items
   */
  public void actionPerformed(ActionEvent evt){
    String arg = evt.getActionCommand();
    Object source = evt.getSource();
    if(arg.equals("Construct array"))
      this.readArray();
    else if(arg.equals("Display array"))
      this.display();
    else if(arg.equals("Save"))
      this.save();
    else if(arg.equals("Print"))
      this.printArray(ta);
    else if(arg.equals("Load existing array"))
      this.load();
    else if(arg.equals("Import blank-delimited array"))
      this.importBlank();
    else if(arg.equals("Edit"))
      this.edit();
    else if(arg.equals("Exit"))
      setVisible(false);
  }

    /**
     * This method reads the initial parameters for the orthogonal array
     * It creates the orthogonal array instance that is to be filled
     */
  protected void readDimensions(){
    setVisible(true);
    numFactors = inputBox.getInteger("Enter the number of factors ");
    numLevels = new Vector(numFactors);
    maxRows = inputBox.getInteger("Enter the number of rows ");
    oa = new OrthogonalArray(numFactors, maxRows);
    for(int i=0;i<numFactors;i++){
      int tmp = inputBox.getInteger("Enter the number of levels for factor "+(i+1));
      numLevels.add(i,new Integer(tmp));
    }
    oa.putLevels(numLevels);
  }

  /**
   * This method gets a filename to use and invokes the save method of the array
   */
  public void save(){
    String fileName;
    if(oa != null){
      FileDialog dialog = new FileDialog(this,"Save File",FileDialog.SAVE);
      dialog.setVisible(true);
      if((fileName = dialog.getFile())!=null){
        String dirName = dialog.getDirectory();
        oa.save(dirName+fileName);
      }
      else{
        System.out.println("FileDialog cancelled");
      }
    }
    else{
      MessageBox message = new MessageBox(this,true);
      message.show("Nothing to save");
    }
  }

  /**
   * This method allows the user to edit a specific entry in the array
   */
  public void edit(){
    int row = inputBox.getInteger("Enter row number of element to be edited");
    int column = inputBox.getInteger("Enter column number of element to be edited");
    MessageBox message = new MessageBox(this);
    message.show("Current value is " + oa.getElementAt(row-1,column-1));
    oa.putElementAt(row-1,column-1,inputBox.getString("Enter new value"));
  }


   /**
   * This method displays the basic array
   */
  public void load(){
    String fileName;
    //String name = inputBox.getString("Enter file name for existing array");
    FileDialog dialog = new FileDialog(this,"Load File",FileDialog.LOAD);
      dialog.setVisible(true);
      if((fileName = dialog.getFile())!=null){
        String dirName = dialog.getDirectory();
        oa = new OrthogonalArray(dirName+fileName);
        display();
      }
      else{
        System.out.println("FileDialog cancelled");
      }
  }

  /**
   * This method displays the basic array that has been read
   * in from a file.
   */
  public void importBlank(){
    int i =0;
    int j = 0;
    String fileName;
    FileDialog dialog = new FileDialog(this,"Import File",FileDialog.LOAD);
      dialog.setVisible(true);
      if((fileName = dialog.getFile())!=null){
        StreamTokenizer stok = null;
        String dirName = dialog.getDirectory();
        try{
          stok = new StreamTokenizer(new FileReader(dirName+fileName));
        }catch(IOException e){e.printStackTrace();}
        stok.wordChars(0,' ');
        stok.whitespaceChars(' ',' ');
        try{
          stok.nextToken();
          maxRows = (int)stok.nval;
          stok.nextToken();
          numFactors = (int)stok.nval;
          //System.out.println("dimensions "+maxRows+" "+numFactors+"\n");
          oa = new OrthogonalArray( numFactors,maxRows);
          //i = 0;
          //j = 0;
          while (stok.nextToken()!=stok.TT_EOF){
            oa.putElementAt(i,j,new Integer((int)stok.nval).toString());
            j++;
            if(j==numFactors){
              j = 0;
              i++;
            }
          }
          //System.out.println("numFactors "+numFactors+"\n");
          Vector tempLevels=new Vector(numFactors);
          for(i=0;i<numFactors;i++){
            int max = new Integer(oa.getElementAt(0,i)).intValue();
            //System.out.println(" start value "+max+"\n");
            for(j=1;j<maxRows;j++){
              int tmp = new Integer(oa.getElementAt(j,i)).intValue();
              if(tmp > max){
                max = tmp;
              }
            }
           // System.out.println("put a level "+(max+1)+" value at "+i+"\n");
            tempLevels.add(i, new Integer(max+1));
           // System.out.println("value placed \n");
          }
          oa.putLevels(tempLevels);
          display();//buildTextArea();
        }catch(IOException e){
          if(i != maxRows){oa = null;}
        }
      }
      else{
        System.out.println("FileDialog cancelled");
      }
  }


  /**
   * This method displays the basic array
   */
  public void display(){
    if(oa != null){
      contentPane = getContentPane();
      contentPane.remove(sp);
      buildTextArea();
      sp = new JScrollPane(ta,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
      contentPane.add(sp);
      setVisible(true);
    }
    else{
      MessageBox message = new MessageBox(this,true);
      message.show("Nothing to display");
    }
  }

  /**
   * This method loads a textarea with a string to be displayed or printed
   */
  private void buildTextArea(){
    String total ="";
    //System.out.println("in build");
    ta = new JTextArea();
    for(int i=0;i<oa.getNumberOfRows();i++){
        for(int j=0;j<oa.getNumberOfFactors();j++){
             total = total + oa.getElementAt(i,j)+"\t ";
        }
        total = total + "\n";
      }
      ta.setText(total);
  }

   /**
   * This method prints the basic array
   */
   /*
  public void print(){
    if(oa != null){
      contentPane = getContentPane();
      contentPane.remove(ta);
      String total ="";
      for(int i=0;i<oa.getNumberOfRows();i++){
        for(int j=0;j<oa.getNumberOfFactors();j++){
             total = total + oa.getElementAt(i,j)+"\t ";
        }
        total = total + "\n";
      }
      ta.setText(total);
      contentPane.add(ta);
      Graphics g = getGraphics();
      ta.print(g);
    }
    else{
      MessageBox message = new MessageBox(this,true);
      message.show("Nothing to print");
    }
  }
*/
  /**
   * This method prints the basic array to the currently selected
   * Windows printer
   */
  private void printArray(Component c){
    if(c != null){
    buildTextArea();
    Toolkit tk = Toolkit.getDefaultToolkit();
    Properties props = new Properties();
    props.put("awt.print.numCopies", "2");
    if(tk != null){
      String name = c.getName() + "print job";
      PrintJob pj = tk.getPrintJob(this,name,props);
      if(pj != null){
        Graphics pg = pj.getGraphics();
        try{
          c.printAll(pg);
        }
        finally{
          pg.dispose();
        }
      }
      pj.end();
    }
    System.out.println(props);
    }
  }

  /**
   * This method prompts the user for each entry in the basic orthogonal array
   */
  protected void readArray(){
    readDimensions();
    for(int i=0;i<maxRows;i++){
      for(int j=0;j<numFactors;j++){
      int tmp2 = inputBox.getInteger("Enter the value for row "+(i+1)+" and column "+(j+1));
      oa.putElementAt(i,j,new Integer(tmp2).toString());
      }
    }
    display();
  }


  public static void main(String[] args){

    GUIOrthogonalArray guiOrthogonalArray = new GUIOrthogonalArray();
    guiOrthogonalArray.show();
  }

  private JTextArea ta = new JTextArea();
  protected JScrollPane sp= new JScrollPane(ta,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);;
  private OrthogonalArray oa;
  private Container contentPane;
  private int numFactors;
  private int maxRows;
  private Vector numLevels;
  private String [][] array;
  private JMenuBar menuBar;
  private JMenuItem displayItem;
  private JMenuItem readItem;
  private JMenuItem exitItem;
  private JMenuItem editItem;
  private JMenuItem printItem;
  private JMenuItem loadItem;
  private JMenuItem importItem;
  private JMenuItem saveItem;
  private JMenu functionMenu;
  private InputBox inputBox = new InputBox(this,true);
}