
/**
 * Title:        GUIMappedArray<p>
 * Description:  This is the GUI that allows a user to associate a specific
 * string with each value of a factor in an 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 javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class GUIMappedArray extends JFrame
  implements ActionListener
{
  /**
   * The constructor builds the menu structure
   */
  public GUIMappedArray() {
    setTitle("Orthogonal Array Mapper");
    setSize(500,500);
    menuBar = new JMenuBar();
    setJMenuBar(menuBar);
    functionMenu = new JMenu("Functions");
    displayItem = new JMenuItem("Display array");
    readItem = new JMenuItem("Construct problem array from orthogonal array");
    buildItem = new JMenuItem("Map problem values onto orthogonal array");
    loadItem = new JMenuItem("Load problem array");
    saveItem = new JMenuItem("Save");
    saveTextItem = new JMenuItem("Save as Text File");
    printItem = new JMenuItem("Print");
    editItem = new JMenuItem("Edit");
    exitItem = new JMenuItem("Exit");
    displayItem.addActionListener(this);
    readItem.addActionListener(this);
    buildItem.addActionListener(this);
    loadItem.addActionListener(this);
    printItem.addActionListener(this);
    editItem.addActionListener(this);
    exitItem.addActionListener(this);
    saveItem.addActionListener(this);
    button1.addActionListener(this);
    saveTextItem.addActionListener(this);
    functionMenu.add(readItem);
    functionMenu.add(buildItem);
    functionMenu.add(loadItem);
    functionMenu.add(displayItem);
    functionMenu.add(saveItem);
    functionMenu.add(saveTextItem);
    functionMenu.add(printItem);
    functionMenu.add(editItem);
    functionMenu.add(exitItem);
    menuBar.add(functionMenu);

  }

  /**
   * This method queries the user and maps all values to the array
   */
  public void startWithFile(){
    String fileName;
    String s;

    FileDialog dialog = new FileDialog(this,"Load File",FileDialog.LOAD);
    dialog.setVisible(true);
    if((fileName = dialog.getFile())!=null){
        String dirName = dialog.getDirectory();
        mappedArray = new MappedArray(dirName+fileName);
        for(int i=0;i < mappedArray.getNumberOfFactors();i++){
          int reply = responseBox.prompt("Do you want to use Factor "+i);
          if(reply == ResponseBox.YES){
            String name = inputBox.getString("Enter name for factor "+(i+1));
            mappedArray.putFactorNameAt(i,name);
            String item = (String)((mappedArray.getLevels()).elementAt(i));
            int itemValue = Integer.parseInt(item);
            for(int j=0;j < itemValue; j++){
              //System.out.println("itemValue "+itemValue+" "+j+" "+i+"\n");
              s = inputBox.getString("Enter Problem Value for the "+j+ " value");
              mappedArray.putLevelValueAt(j,i,s);
              for(int k=0;k<mappedArray.getNumberOfRows();k++){
                //System.out.println("values -- "+k+" "+i+" \n");
                if((mappedArray.getElementAt(k,i)).equals(new Integer(j).toString()))
                  mappedArray.putElementAt(k,i,s);
              }
            }
          }
          else{
            mappedArray.putFactorNameAt(i,"nis");
            String item = (String)((mappedArray.getLevels()).elementAt(i));
            int itemValue = Integer.parseInt(item);
            for(int j=0;j < itemValue; j++){
              mappedArray.putLevelValueAt(j,i," ");
              for(int k=0;k<mappedArray.getNumberOfRows();k++){
                if((mappedArray.getElementAt(k,i)).equals(new Integer(j).toString()))
                  mappedArray.putElementAt(k,i," ");
              }
            }
          }
        }
     }
     else{
        System.out.println("FileDialog cancelled");
     }
  }

    /**
   * This method queries the user and maps all values to the array
   */
  public void startWithTable(){
    String fileName;
    String s;
    this.getContentPane().remove(sp);
    this.getContentPane().remove(button1);
    //tableSetUp();
    System.out.println("numFactors "+numTableFactors );
    tmpLevels = new Vector(numTableFactors);
    tmpArray = new MappedArray(numTableFactors,numTableRows);
    for(int i=0;i < tmpArray.getNumberOfFactors();i++){
      tmpArray.putFactorNameAt(i,columnNames[i]);
      System.out.println(columnNames[i]+"\n");
      int count = 0;
      for(int j=0;j < numTableRows; j++){
        if(!((String)model.getValueAt(j,i)).equals(" ")){
          System.out.println("level "+j+" "+i+"\n");
          count++;
        }
        tmpArray.putLevelValueAt(j,i, (String)model.getValueAt(j,i));
      }
      System.out.println("i is "+i+" count "+count+" "+tmpLevels.toString()+"\n");
      tmpLevels.add(i, new Integer(count));
    }
    chooseArray();

    Vector mappedLevels = mappedArray.getLevels();
    boolean[] used = new boolean[mappedArray.getNumberOfFactors()];
    for(int i=0;i<mappedArray.getNumberOfFactors();i++){
      used[i]=false;
    }

    int pointerIntoMappedArray = 0;
    for(int i=0;i < tmpArray.getNumberOfFactors();i++){
      System.out.println("i = "+i+"\n");
      Integer tmpLevel = (Integer)tmpLevels.elementAt(i);
      String mappedLevel = (String)mappedLevels.elementAt(pointerIntoMappedArray);
      while(pointerIntoMappedArray < mappedArray.getNumberOfFactors() && ((tmpLevel.intValue() > Integer.parseInt(mappedLevel)) || used[pointerIntoMappedArray])){
        pointerIntoMappedArray++;
        if(pointerIntoMappedArray <  mappedArray.getNumberOfFactors()){
          mappedLevel = (String)mappedLevels.elementAt(pointerIntoMappedArray);
        }
        System.out.println("in while"+pointerIntoMappedArray+"\n");
      }//while
      System.out.println("out of while "+pointerIntoMappedArray+" "+mappedArray.getNumberOfFactors()+ " "+tmpLevel.intValue()+" "+Integer.parseInt(mappedLevel));
      if((tmpLevel.intValue() <= Integer.parseInt(mappedLevel)) && !used[pointerIntoMappedArray]){
        used[i]=true;
        mappedArray.putFactorNameAt(pointerIntoMappedArray, tmpArray.getFactorNameAt(i));

        for(int j=0;j < numTableRows; j++){
          s = tmpArray.getLevelValueAt(j,i);
          if(s.equals(" ") ){
            s = inputBox.getString("Enter value you would like to substitute for "+j+" in factor "+tmpArray.getFactorNameAt(i));
          }//if

          mappedArray.putLevelValueAt(j,pointerIntoMappedArray,s );
        //insert filling in the array
          for(int k=0;k < mappedArray.getNumberOfRows(); k++){
                System.out.println("values -- "+k+" "+j+" \n");
                if((mappedArray.getElementAt(k,pointerIntoMappedArray)).equals(new Integer(j).toString())){
                  mappedArray.putElementAt(k,pointerIntoMappedArray,s);
                }//if
          }//fork
        }//forj
        if(numTableRows < Integer.parseInt(mappedLevel)){
          s = inputBox.getString("Enter value you would like to substitute for values greater than "+ (numTableRows - 1)+ " in factor "+tmpArray.getFactorNameAt(i));
          for(int n= numTableRows; n < Integer.parseInt(mappedLevel);n++){
            for(int k=0;k < mappedArray.getNumberOfRows(); k++){
              if((mappedArray.getElementAt(k,pointerIntoMappedArray)).equals(new Integer(n).toString())){
                mappedArray.putElementAt(k,pointerIntoMappedArray,s);
              }//if
            }//fork
          }//forn
        }//if
        pointerIntoMappedArray++;
      }//if
      else{
          MessageBox box = new MessageBox(this);
          box.show("No match, try another array");
          pointerIntoMappedArray = mappedArray.getNumberOfFactors();
          i = tmpArray.getNumberOfFactors();
      }//else
    }//for
    for(int i=0;i < mappedArray.getNumberOfFactors();i++){
      if(!used[i]){
         mappedArray.putFactorNameAt(i,"nis");
            String item = (String)((mappedArray.getLevels()).elementAt(i));
            int itemValue = Integer.parseInt(item);
            for(int j=0;j < itemValue; j++){
              mappedArray.putLevelValueAt(j,i," ");
              for(int k=0;k<mappedArray.getNumberOfRows();k++){
                if((mappedArray.getElementAt(k,i)).equals(new Integer(j).toString()))
                  mappedArray.putElementAt(k,i," ");
              }//fork
            }//forj
      }//if
    }//fori
    display();
  }//method


  public void chooseArray(){
    String fileName;
    String s;

    FileDialog dialog = new FileDialog(this,"Load File",FileDialog.LOAD);
    dialog.setVisible(true);
    if((fileName = dialog.getFile())!=null){
        String dirName = dialog.getDirectory();
        mappedArray = new MappedArray(dirName+fileName);

    }
     else{
        System.out.println("FileDialog cancelled");
     }
  }



   /**
   * This method fires off the individual menu items
   * @param evt
   */
  public void actionPerformed(ActionEvent evt){
    String arg = evt.getActionCommand();
    Object source = evt.getSource();
    if(source == button1)
      this.startWithTable();
    else if(arg.equals("Construct problem array from orthogonal array"))
      this.startWithFile();
    else if(arg.equals("Map problem values onto orthogonal array"))
      this.tableSetUp();
    else if(arg.equals("Load problem array"))
      this.load();
    else if(arg.equals("Display array"))
      this.display();
    else if(arg.equals("Save"))
      this.save();
    else if(arg.equals("Save as Text File"))
      this.saveText();
    else if(arg.equals("Print"))
      this.printArray(this);
    else if(arg.equals("Edit"))
      this.edit();
    else if(arg.equals("Exit"))
      setVisible(false);
  }

   /**
   * This method gets a filename to use and invokes the save method of the array
   */
  public void save(){
    String fileName;
    if(mappedArray != null){
      FileDialog dialog = new FileDialog(this,"Save File",FileDialog.SAVE);
      dialog.setVisible(true);
      if((fileName = dialog.getFile())!=null){
        String dirName = dialog.getDirectory();
        mappedArray.save(dirName+fileName);
      }
      else{
        System.out.println("FileDialog cancelled");
      }
    }
    else{
      MessageBox message = new MessageBox(this,true);
      message.show("Nothing to save");
    }
  }

   /**
   * This method gets a filename to use and invokes the save method of the array
   */
  public void saveText(){
    String fileName;
    if(mappedArray != null){
      FileDialog dialog = new FileDialog(this,"Save File",FileDialog.SAVE);
      dialog.setVisible(true);
      if((fileName = dialog.getFile())!=null){
        String dirName = dialog.getDirectory();
        mappedArray.saveText(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 " + mappedArray.getElementAt(row-1,column-1));
    mappedArray.putElementAt(row-1,column-1,inputBox.getString("Enter new value"));
  }

  /**
   * This method displays the basic array
   */
  public void display(){

    if(mappedArray != null){

      contentPane = getContentPane();
      contentPane.remove(ta);
      String total ="";
      for(int j=0;j<mappedArray.getNumberOfFactors();j++){
        if(!mappedArray.getFactorNameAt(j).equals("nis")){
          total = total + mappedArray.getFactorNameAt(j)+"\t";
        }
      }
      total=total + "\n";
      for(int i=0;i<mappedArray.getNumberOfRows();i++){
        for(int j=0;j<mappedArray.getNumberOfFactors();j++){
          if(!mappedArray.getElementAt(i,j).equals(" ")){
             total = total + mappedArray.getElementAt(i,j)+"\t ";
          }
        }
        total = total + "\n";
      }
      ta.setText(total);
      sp = new JScrollPane(ta,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
      contentPane.add(sp);
      //contentPane.add(ta);
      setVisible(true);
    }
    else{
      MessageBox message = new MessageBox(this,true);
      message.show("Nothing to display");
    }
  }

  /**
   * 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();
        mappedArray = new MappedArray(dirName+fileName,0);
      }
      else{
        System.out.println("FileDialog cancelled");
      }
  }

   private void printArray(Component c){
    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 displays the basic array
   */
  public void print(){

    if(mappedArray != null){

      contentPane = getContentPane();
      contentPane.remove(ta);
      String total ="";
      for(int j=0;j<mappedArray.getNumberOfFactors();j++){
        total = total + mappedArray.getFactorNameAt(j)+"\t";
      }
      total=total + "\n";
      for(int i=0;i<mappedArray.getNumberOfRows();i++){
        for(int j=0;j<mappedArray.getNumberOfFactors();j++){
             total = total + mappedArray.getElementAt(i,j)+"\t ";
        }
        total = total + "\n";
      }
      ta.setText(total);
      contentPane.add(ta);
      //setVisible(true);
      Graphics g = getGraphics();
      contentPane.print(g);
    }
    else{
      MessageBox message = new MessageBox(this,true);
      message.show("Nothing to print");
    }
  }


   private void tableSetUp(){
    numTableFactors = inputBox.getInteger("Number of Factors");

    numTableRows = inputBox.getInteger("Maximum Number of Levels for any Factor");
    model = new DefaultTableModel(numTableRows,numTableFactors);
    table = new JTable(model);
    columnNames = new String[numTableFactors];
    for(int i=0;i < numTableFactors; i++){
      columnNames[i]=inputBox.getString("Enter Name for Factor: "+i);
    }
    model.setColumnIdentifiers(columnNames);
    this.getContentPane().setLayout(new BorderLayout());
    sp = new JScrollPane(table,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    this.getContentPane().add(sp,BorderLayout.NORTH);
    for(int i=0;i < model.getRowCount();i++){
      for(int j=0;j < model.getColumnCount();j++){
        model.setValueAt(" ",i,j);
      }
    }
    this.getContentPane().add(button1,BorderLayout.SOUTH);
    this.show();
  }

  public static void main(String[] args){
    GUIMappedArray guiMappedArray = new GUIMappedArray();
    guiMappedArray.show();
  }

  private Button button1 = new Button("I have finished filling in the table");
  private int mappedFactor;
  private Vector tmpLevels;
  private int numTableFactors;
  private int numTableRows;
  private String[] columnNames;
  private Container contentPane;
  private DefaultTableModel model;
  private JTable table;
  private MappedArray mappedArray;
  private MappedArray tmpArray;
  private JTextArea ta = new JTextArea();
  private JScrollPane sp;
  private int numFactors;
  private int maxRows;
  private Vector numLevels;
  private String [][] array;
  private JMenuBar menuBar;
  private JMenuItem displayItem;
  private JMenuItem readItem;
  private JMenuItem buildItem;
  private JMenuItem loadItem;
  private JMenuItem printItem;
  private JMenuItem editItem;
  private JMenuItem exitItem;
  private JMenuItem saveItem;
  private JMenuItem saveTextItem;
  private JMenu functionMenu;
  private InputBox inputBox = new InputBox(this,true);
  private ResponseBox responseBox = new ResponseBox(this);
}