/*

  Outputs window class

*/


import java.awt.*;


class OutputsWindow extends Frame {

  public Net net;
  LearnData[] cur_data;
  int width = 120;    // dimensions of window
  int height = 170;

  // for checking for correct output:
  int max_node, max_correct_node;
  float max_output;
  boolean[] correct;
  int number_correct = 0;

  OutputsWindow (Net nt) {

    super ("");
    net = nt;
    int sets, i, nodes;

    setTitle("All Outputs");
    setBackground(new Color(220, 220, 220));
    move (300, 200);

    // PleaseWait pleaseWait = new PleaseWait();
    // pleaseWait.show();
    // pleaseWait.resize (150, 50);

    correct = new boolean[net.training_sets+1];
    cur_data = new LearnData[net.training_sets+1];
    for (sets = 1; sets <= net.training_sets; sets ++) {
      correct[sets] = false;
      cur_data[sets] = new LearnData(net.input_nodes, net.output_nodes);
      net.runNet(net.learndata[sets].train_input);
      max_correct_node = 0;
      max_output = -1;
      for (i = 1; i <= net.output_nodes; i ++)   // find max output node
        if (net.learndata[sets].train_output[i] >= max_output) {
          max_output = net.learndata[sets].train_output[i];
          max_correct_node = i;
        }
      max_node = 0;
      max_output = -1;
      for (nodes = 1; nodes <= net.output_nodes; nodes ++) {
        cur_data[sets].train_output[nodes] =
            net.neuron[net.num_layers][nodes].getRndValue();
        if (cur_data[sets].train_output[nodes] >= max_output) {
          max_output = cur_data[sets].train_output[nodes];
          max_node = nodes;
          if (max_node == 0) {  // couldn't find any node close to correct val.
            System.out.println("No nodes were greater than -1 in input set" +
                sets + "!");
            max_node = 1;
          }
        }
      }
      // To display comparison between correct output and actual output
      /* System.out.println("Set #"+sets+" correct node: "+max_correct_node+
          " learned node: "+max_node);  */
      if (max_node == max_correct_node) {
        correct[sets] = true;
        number_correct ++;
      }
    }
    // pleaseWait.hide();
    // pleaseWait.dispose();

  }



  public void paint (Graphics g) {
    String str;
    Font status_font14, status_font18;
    FontMetrics f_met14, f_met18;
    int i, sets, nodes;
    int f_width, f_ascent14, f_ascent18;
    int start_line;
    int cur_line = 40;
    int traindata[] = new int[net.input_nodes+1];
    float correct;
  
    g.setColor (new Color (127, 0, 50));

    status_font14 = new Font("TimesRoman", Font.PLAIN, 14);
    f_met14 = g.getFontMetrics(status_font14);
    f_ascent14 = f_met14.getAscent();
    status_font18 = new Font("TimesRoman", Font.PLAIN, 18);
    f_met18 = g.getFontMetrics(status_font18);
    f_ascent18 = f_met18.getAscent();

    // Draw percentage correct

    g.setFont(status_font18);
    cur_line += 7 + f_ascent18;
    start_line = cur_line;
    correct = ((float) number_correct) / ((float) net.training_sets) * 10000;
    correct = Math.round(correct);
    correct = correct / 100;
    str = "Percentage correct: " + Float.toString(correct) + "%";
    f_width = f_met18.stringWidth(str);
    g.drawString(str, 20, cur_line);
    cur_line += 2;
    g.drawLine(20, cur_line, 20+f_width, cur_line);

    // Draw inputs

    g.setFont(status_font18);
    cur_line += 7 + f_ascent18;
    start_line = cur_line;
    str = "Inputs";
    f_width = f_met18.stringWidth(str);
    g.drawString(str, 10, cur_line);
    cur_line += 2;
    g.drawLine(10, cur_line, 10+f_width, cur_line);

    g.setFont(status_font14);
    int max_width_inp = f_width + 10;
    cur_line += 7;
    for (sets = 1; sets <= net.training_sets; sets ++) {
      str = "";
      for (nodes = 1; nodes <= net.input_nodes; nodes ++) {
        if (nodes > 1) str = str + ", ";
        str = str + net.learndata[sets].train_input[nodes];
      }
      f_width = f_met14.stringWidth(str);
      if (max_width_inp < (f_width + 20)) max_width_inp = f_width + 20;
      cur_line += f_ascent14 + 4;
      g.drawString(str, 20, cur_line);
    }

    // Draw network outputs

    g.setFont(status_font18);
    cur_line = start_line;
    str = "Outputs";
    f_width = f_met18.stringWidth(str);
    g.drawString(str, max_width_inp+10, cur_line);
    cur_line += 2;
    g.drawLine(max_width_inp+10, cur_line, max_width_inp+10+f_width, cur_line);

    g.setFont(status_font14);
    int max_width_outp = f_width + 10;
    cur_line += 7;
    for (sets = 1; sets <= net.training_sets; sets ++) {
      str = "";
      for (nodes = 1; nodes <= net.output_nodes; nodes ++) {
        if (nodes > 1) str = str + ", ";
        str = str + Float.toString(cur_data[sets].train_output[nodes]);
      }
      f_width = f_met14.stringWidth(str);
      if (max_width_outp < (f_width + 20)) max_width_outp = (f_width + 20);
      cur_line += f_ascent14 + 4;
      g.drawString(str, max_width_inp+10+10, cur_line);
    }

    // Draw correct outputs

    cur_line = start_line;
    cur_line += 2;

    g.setFont(status_font14);
    int max_width_edge = 0;
    cur_line += 7;
    for (sets = 1; sets <= net.training_sets; sets ++) {
      str = "(";
      for (nodes = 1; nodes <= net.output_nodes; nodes ++) {
        if (nodes > 1) str = str + ", ";
        str = str + Float.toString(net.learndata[sets].train_output[nodes]);
      }
      str = str + ")";
      f_width = f_met14.stringWidth(str);
      if (max_width_edge < f_width) max_width_edge = f_width;
      cur_line += f_ascent14 + 4;
      g.drawString(str, max_width_inp+max_width_outp+10, cur_line);
    }

    // Resize the window

    cur_line += 20;
    height = cur_line;
    width = 20+max_width_inp+10+max_width_outp+10+max_width_edge+14;
    resize(width, height);
  }

  int center (int font_width) {
    return (int) ((width - font_width) / 2);
  }

}



// Please Wait dialog box

class PleaseWait extends Dialog {

  PleaseWait () {
  
    super (new Frame(), "", true);
    setTitle ("Please wait...");

    setLayout (new FlowLayout());
    add(new Label ("Please wait..."));

    Font f = new Font ("Dialog", Font.PLAIN, 12);
    setFont (f);
  }

}


