
package Sorter;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Frame1 extends JFrame
{
  BorderLayout borderLayout1 = new BorderLayout();
  JTextArea outputTA = new JTextArea();
  JPanel jPanel2 = new JPanel();
  JRadioButton insertionRBtn = new JRadioButton();
  JRadioButton quickRBtn = new JRadioButton();
  GridLayout gridLayout1 = new GridLayout();
  JRadioButton bubbleRBtn = new JRadioButton();
  JRadioButton mergeRBtn = new JRadioButton();
  JRadioButton selectionRBtn = new JRadioButton();
  ButtonGroup buttonGroup = new ButtonGroup();
  JButton gBuildBtn = new JButton();
  JButton gSortBtn = new JButton();
  ButtonGroup compareButtonGroup = new ButtonGroup();
  ButtonGroup drawStyleButtonGroup = new ButtonGroup();


    JPanel jPanel3 = new JPanel();
  JLabel jLabel1 = new JLabel();
  GridLayout gridLayout2 = new GridLayout();
  JRadioButton compareWhiteRBtn = new JRadioButton();
  JRadioButton compareBlackRBtn = new JRadioButton();
  JRadioButton heapRBtn = new JRadioButton();
    JPanel jPanel4 = new JPanel();
    GridLayout gridLayout3 = new GridLayout();
    JPanel jPanel5 = new JPanel();
    JCheckBox reverseCBox = new JCheckBox();
    GridLayout gridLayout4 = new GridLayout();
    JCheckBox metricCBox = new JCheckBox();
    JCheckBox graphicCBox = new JCheckBox();
    JCheckBox graphicSortCBox = new JCheckBox();
    JPanel jPanel6 = new JPanel();
    JTextField compareDelayTF = new JTextField();
    JTextField sortDelayTF = new JTextField();
    GridLayout gridLayout5 = new GridLayout();
    JPanel jPanel7 = new JPanel();


  boolean fromApplet = false;

  public Frame1(boolean fromApplet)
  {
    this();
    this.fromApplet = fromApplet;
  }
  JPanel graphPanel = new JPanel()
  {
    public void paintComponent(Graphics g)
    {
      super.paintComponent(g);

      graphPanelCommand.paintComponent(g);
    }
  };

  int  loColorValue = 0;
  int  hiColorValue =  1+Color.white.getRGB()-Color.black.getRGB();
 SorterColor normalColor = new SorterColor((loColorValue+hiColorValue)/2, loColorValue, hiColorValue);
  Color compareColor = new SorterColor(hiColorValue-1, hiColorValue-1, hiColorValue-14-5);

  class GraphPanelCommand extends ACommand
  {
    Graphics g;
    int xIdx = 0, dx=0;
    double m, b;
    int minX, maxX, minY, maxY;

    void paintComponent(Graphics g)
    {
      this.g =g;
      xIdx = 0;
      minX = 10;
      maxX = graphPanel.getWidth()-10;
      minY = graphPanel.getHeight()-20;
      maxY = 5;
//      dx = (maxX-minX)/(gcDataArray.length);
//      dx = -(maxY-minY)/(gcDataArray.length);
      dx = 17;
      setMB();
      mapThis();
    }

    void setMB()
    {
          int minVal = 0;
          int maxVal = gcDataArray.length-1;
          m = ((double)(maxX-minX))/(maxVal - minVal);
          b = ((double)(minX*maxVal - maxX*minVal))/(maxVal-minVal);
    }

    public void execute(Object x)
    {
        g.setColor(((IColoredObject) x).getColor());
        g.fillOval((int)(m*((AInteger)x).getValue()+b), maxY+dx*xIdx++, 10,10);
        //((ColoredIntegerAdapter) x).paint(g, m, b, maxY+dx*xIdx++);
    }

    void mapThis()
    {
        ArrayMapper.Singleton().map(gcDataArray, this );
    }
  };

	class BarGraphPanelCommand extends GraphPanelCommand
	{
	    public void execute(Object x)
    	{
        	g.setColor(((IColoredObject) x).getColor());
        	g.fillRect(0, maxY+dx*xIdx++, (int)(m*((AInteger)x).getValue()+b),10);
    	}
	}

  GraphPanelCommand graphPanelCommand = new GraphPanelCommand();

  //Construct the frame
  public Frame1()
  {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try
    {
      jbInit();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    buttonGroup.add(insertionRBtn);
    buttonGroup.add(quickRBtn);
    buttonGroup.add(mergeRBtn);
    buttonGroup.add(selectionRBtn);
    buttonGroup.add(bubbleRBtn);
    buttonGroup.add(heapRBtn);
    buttonGroup.add(shakerRBtn);
    buttonGroup.add(sinkRBtn);
    compareButtonGroup.add(compareBlackRBtn);
    compareButtonGroup.add(compareWhiteRBtn);
    drawStyleButtonGroup.add(dotsRBtn);
    timer.start();
//      System.out.println("lo = "+loColorValue+"  hi ="+hiColorValue +"  normal =" + normalColor.getValue()+"  compare =" + compareColor.getRGB()+"  black =" + Color.black.getRGB());

  }

  //Component initialization
  private void jbInit() throws Exception
  {
    this.getContentPane().setLayout(borderLayout1);
    this.getContentPane().setBackground(SystemColor.textHighlightText);
        this.setSize(new Dimension(674, 688));
    this.setTitle("Template Pattern Sorting");
    insertionRBtn.setOpaque(false);
        insertionRBtn.setText("Insertion Sort");
        insertionRBtn.setForeground(Color.red);
        insertionRBtn.setFont(new java.awt.Font("Dialog", 1, 14));
    insertionRBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        insertionRBtn_actionPerformed(e);
      }
    });
    quickRBtn.setOpaque(false);
        quickRBtn.setSelected(true);
        quickRBtn.setText("Quick Sort");
        quickRBtn.setForeground(Color.red);
        quickRBtn.setFont(new java.awt.Font("Dialog", 1, 14));
    quickRBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        quickRBtn_actionPerformed(e);
      }
    });
    jPanel2.setLayout(gridLayout1);
    gridLayout1.setColumns(1);
    gridLayout1.setRows(14);
        bubbleRBtn.setOpaque(false);
    bubbleRBtn.setText("Bubble Sort");
        bubbleRBtn.setForeground(Color.red);
        bubbleRBtn.setFont(new java.awt.Font("Dialog", 1, 14));
    bubbleRBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        bubbleRBtn_actionPerformed(e);
      }
    });
    mergeRBtn.setOpaque(false);
        mergeRBtn.setText("Merge Sort");
        mergeRBtn.setForeground(Color.red);
        mergeRBtn.setFont(new java.awt.Font("Dialog", 1, 14));
    mergeRBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        mergeRBtn_actionPerformed(e);
      }
    });
    selectionRBtn.setToolTipText("");
        selectionRBtn.setOpaque(false);
    selectionRBtn.setText("Selection Sort");
        selectionRBtn.setForeground(Color.red);
        selectionRBtn.setFont(new java.awt.Font("Dialog", 1, 14));
    selectionRBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        selectionRBtn_actionPerformed(e);
      }
    });
    graphPanel.setBackground(Color.lightGray);
    graphPanel.setPreferredSize(new Dimension(400, 0));
    gBuildBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        gBuildBtn_actionPerformed(e);
      }
    });
    gBuildBtn.setFont(new java.awt.Font("Dialog", 1, 16));
        gBuildBtn.setText("Build");
    gSortBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        gSortBtn_actionPerformed(e);
      }
    });
    gSortBtn.setFont(new java.awt.Font("Dialog", 1, 16));
        gSortBtn.setText("Sort");
    jScrollPane1.setPreferredSize(new Dimension(100, 21));
    jLabel1.setForeground(Color.blue);
        jLabel1.setText("Compare Color:");
    jPanel3.setLayout(gridLayout2);
    gridLayout2.setColumns(1);
    gridLayout2.setRows(3);
    compareWhiteRBtn.setOpaque(false);
        compareWhiteRBtn.setSelected(true);
    compareWhiteRBtn.setText("White");
    compareWhiteRBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        compareWhiteRBtn_actionPerformed(e);
      }
    });
    compareBlackRBtn.setOpaque(false);
        compareBlackRBtn.setText("Black");
    compareBlackRBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        compareBlackRBtn_actionPerformed(e);
      }
    });
    heapRBtn.setOpaque(false);
        heapRBtn.setText("Heap Sort");
        heapRBtn.setForeground(Color.red);
        heapRBtn.setFont(new java.awt.Font("Dialog", 1, 14));
    heapRBtn.addActionListener(new java.awt.event.ActionListener()
    {

      public void actionPerformed(ActionEvent e)
      {
        heapRBtn_actionPerformed(e);
      }
    });
        jPanel4.setLayout(gridLayout3);
        gridLayout3.setColumns(1);
        gridLayout3.setRows(2);
        reverseCBox.setOpaque(false);
        reverseCBox.setBackground(new Color(255, 255, 150));
        reverseCBox.setText("Reverse Order");
        reverseCBox.setForeground(Color.red);
        reverseCBox.setFont(new java.awt.Font("Dialog", 1, 14));
        jPanel5.setLayout(gridLayout4);
        gridLayout4.setRows(4);
    gridLayout4.setColumns(1);
        metricCBox.setOpaque(false);
        metricCBox.setBackground(new Color(255, 255, 150));
        metricCBox.setText("Count Compares");
        metricCBox.setForeground(Color.red);
        metricCBox.setFont(new java.awt.Font("Dialog", 1, 14));
        metricCBox.addActionListener(new java.awt.event.ActionListener()
        {

            public void actionPerformed(ActionEvent e)
            {
                metricCBox_actionPerformed(e);
            }
        });
        graphicCBox.setOpaque(false);
        graphicCBox.setBackground(new Color(255, 255, 150));
        graphicCBox.setText("Graphical Ordering");
        graphicCBox.setForeground(Color.red);
        graphicCBox.setFont(new java.awt.Font("Dialog", 1, 14));
        graphicSortCBox.setOpaque(false);
        graphicSortCBox.setText("Graphic Split/Join");
        graphicSortCBox.setForeground(Color.red);
        graphicSortCBox.setFont(new java.awt.Font("Dialog", 1, 14));
        compareDelayTF.setToolTipText("Compare delay (ms)");
    compareDelayTF.setText("50");
        sortDelayTF.setToolTipText("Sort delay (ms)");
    sortDelayTF.setText("100");
        jPanel6.setLayout(gridLayout5);
        gridLayout5.setColumns(1);
        gridLayout5.setRows(3);
        jLabel2.setForeground(Color.black);
        jLabel2.setHorizontalAlignment(SwingConstants.RIGHT);
        jLabel2.setText("Compare Delay = ");
        jPanel9.setLayout(gridLayout6);
        jLabel4.setForeground(Color.black);
        jLabel4.setHorizontalAlignment(SwingConstants.RIGHT);
        jLabel4.setText("Sort Delay = ");
        jPanel10.setLayout(gridLayout8);
        statusLabel1.setHorizontalAlignment(SwingConstants.CENTER);
        statusLabel1.setPreferredSize(new Dimension(200, 20));
        statusLabel1.setForeground(Color.red);
        statusLabel2.setForeground(Color.red);
        statusLabel2.setPreferredSize(new Dimension(200, 20));
        statusLabel2.setHorizontalAlignment(SwingConstants.CENTER);
        jPanel8.setLayout(gridLayout7);
        jLabel3.setForeground(Color.black);
        jLabel3.setHorizontalAlignment(SwingConstants.RIGHT);
        jLabel3.setText("# of Elements = ");
        numElementsTF.setToolTipText("Number of elements to be sorted.");
        numElementsTF.setText("20");
        jPanel2.setBackground(new Color(255, 255, 150));
        jPanel4.setBackground(new Color(255, 255, 150));
        jPanel7.setBackground(new Color(255, 255, 150));
        jPanel7.setOpaque(false);
        jPanel5.setOpaque(false);
    jPanel5.setPreferredSize(new Dimension(159, 50));
        jPanel3.setOpaque(false);
        jPanel6.setOpaque(false);
        jPanel8.setOpaque(false);
        jPanel9.setOpaque(false);
        jPanel10.setOpaque(false);
        dotsRBtn.setOpaque(false);
        dotsRBtn.setSelected(true);
        dotsRBtn.setText("Dots");
        dotsRBtn.setFont(new java.awt.Font("Dialog", 1, 16));
        dotsRBtn.addActionListener(new java.awt.event.ActionListener()
        {

            public void actionPerformed(ActionEvent e)
            {
                dotsRBtn_actionPerformed(e);
            }
        });
        barsRBtn.setOpaque(false);
        barsRBtn.setText("Bars");
        barsRBtn.setFont(new java.awt.Font("Dialog", 1, 16));
        barsRBtn.addActionListener(new java.awt.event.ActionListener()
        {

            public void actionPerformed(ActionEvent e)
            {
                barsRBtn_actionPerformed(e);
            }
        });
        jPanel1.setLayout(gridLayout9);
        gridLayout9.setColumns(1);
        gridLayout9.setRows(2);
        jPanel1.setOpaque(false);
        shakerRBtn.setOpaque(false);
        shakerRBtn.setText("Shaker Sort");
        shakerRBtn.setForeground(Color.red);
        shakerRBtn.setFont(new java.awt.Font("Dialog", 1, 14));
        shakerRBtn.addActionListener(new java.awt.event.ActionListener()
        {

            public void actionPerformed(ActionEvent e)
            {
                shakerRBtn_actionPerformed(e);
            }
        });
        gridLayout7.setColumns(2);
    gridLayout6.setColumns(2);
    gridLayout8.setColumns(2);
    sinkRBtn.setOpaque(false);
    sinkRBtn.setText("Sink Sort");
    sinkRBtn.setForeground(Color.red);
    sinkRBtn.setFont(new java.awt.Font("Dialog", 1, 14));
    sinkRBtn.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        sinkRBtn_actionPerformed(e);
      }
    });
    this.getContentPane().add(jPanel2, BorderLayout.WEST);
        jPanel2.add(jPanel4, null);
        jPanel4.add(statusLabel2, null);
        jPanel4.add(statusLabel1, null);
        jPanel2.add(jPanel7, null);
        jPanel7.add(gBuildBtn, null);
    jPanel7.add(gSortBtn, null);
        jPanel2.add(jPanel5, null);
        jPanel5.add(graphicCBox, null);
        jPanel5.add(metricCBox, null);
        jPanel5.add(reverseCBox, null);
        jPanel5.add(graphicSortCBox, null);
        jPanel2.add(jPanel3, null);
        jPanel3.add(jLabel1, null);
        jPanel3.add(compareWhiteRBtn, null);
        jPanel3.add(compareBlackRBtn, null);
        jPanel2.add(jPanel6, null);
        jPanel6.add(jPanel8, null);
        jPanel6.add(jPanel9, null);
        jPanel9.add(jLabel2, null);
        jPanel9.add(compareDelayTF, null);
        jPanel8.add(jLabel3, null);
        jPanel8.add(numElementsTF, null);
        jPanel6.add(jPanel10, null);
        jPanel10.add(jLabel4, null);
        jPanel10.add(sortDelayTF, null);
        jPanel2.add(jPanel1, null);
        jPanel1.add(dotsRBtn, null);
        jPanel1.add(barsRBtn, null);
        jPanel2.add(selectionRBtn, null);
        jPanel2.add(insertionRBtn, null);
    jPanel2.add(mergeRBtn, null);
        jPanel2.add(shakerRBtn, null);
    jPanel2.add(bubbleRBtn, null);
    jPanel2.add(quickRBtn, null);
    jPanel2.add(heapRBtn, null);
    jPanel2.add(sinkRBtn, null);
    this.getContentPane().add(jScrollPane1, BorderLayout.CENTER);
    this.getContentPane().add(graphPanel, BorderLayout.EAST);
    jScrollPane1.getViewport().add(outputTA, null);
  }

  //Overridden so we can exit on System Close
  protected void processWindowEvent(WindowEvent e)
  {
    super.processWindowEvent(e);
    if(e.getID() == WindowEvent.WINDOW_CLOSING)
    {
      if(!fromApplet) System.exit(0);
    }
  }


  JScrollPane jScrollPane1 = new JScrollPane();

     int minSize = 11;
     int maxSize = 11;
     int minVal = 0;
     int maxVal = maxSize-1;


  void showData()
  {
    outputTA.setText("");
    ArrayMapper.Singleton().map(gcDataArray, new ACommand(){
      public void execute(Object x)
      {
          outputTA.append(""+((AInteger)x).getValue()+"\n");
      }
    });
    graphPanel.repaint();
  }

  Counter accessCounter = new Counter(1);

  int waitTime = 200;
  int sortWait = 300;
  int repaintTime = 100;


  AOrder aOrder = CInteger.makeOrder();
  GraphicOrder graphicOrder = new GraphicOrder(compareColor,waitTime, aOrder);
  CountOrder countOrder = new CountOrder(new Counter(1), aOrder);

   ASorter aCSorter = new QuickSorter(aOrder);

  void insertionRBtn_actionPerformed(ActionEvent e)
  {
    aCSorter = new InsertionSorter(aOrder);
  }

  void selectionRBtn_actionPerformed(ActionEvent e)
  {
    aCSorter = new SelectionSorter(aOrder);

  }

  void mergeRBtn_actionPerformed(ActionEvent e)
  {
    aCSorter = new MergeSorter(aOrder);

  }

  void bubbleRBtn_actionPerformed(ActionEvent e)
  {
    aCSorter = new BubbleSorter(aOrder);
  }

  void quickRBtn_actionPerformed(ActionEvent e)
  {
    aCSorter = new QuickSorter(aOrder);
  }

  void heapRBtn_actionPerformed(ActionEvent e)
  {
     (new Thread() {
        public void run()
        {
          countOrder.clearCount();
          aCSorter = new HeapSorter(buildAOrder(), gcDataArray, 0, gcDataArray.length-1);
          statusLabel1.setText("# of compares = "+countOrder.getCount());
        }
     }).start();
  }



  Timer timer  = new  Timer(repaintTime, new ActionListener(){
    public void actionPerformed(ActionEvent e)
    {
       //System.out.println("timer...");
       showData();
    }
  });

  Object gcDataArray[] = {new ColoredIntegerAdapter(new ColoredObject(normalColor),new CInteger(0))};
    private JPanel jPanel9 = new JPanel();
    private JPanel jPanel10 = new JPanel();
    private JLabel jLabel2 = new JLabel();
    private GridLayout gridLayout6 = new GridLayout();
    private JLabel jLabel4 = new JLabel();
    private GridLayout gridLayout8 = new GridLayout();
    private JLabel statusLabel1 = new JLabel();
    private JLabel statusLabel2 = new JLabel();
    private JPanel jPanel8 = new JPanel();
    private GridLayout gridLayout7 = new GridLayout();
    private JLabel jLabel3 = new JLabel();
    private JTextField numElementsTF = new JTextField();
    private JPanel jPanel1 = new JPanel();
    private JRadioButton dotsRBtn = new JRadioButton();
    private JRadioButton barsRBtn = new JRadioButton();
    private GridLayout gridLayout9 = new GridLayout();
    private JRadioButton shakerRBtn = new JRadioButton();
  JRadioButton sinkRBtn = new JRadioButton();

  void gBuildBtn_actionPerformed(ActionEvent e)
  {

//     gcDataArray =  new Object[minSize+(int)((maxSize-minSize)*Math.random())];
     gcDataArray =  new Object[Integer.parseInt(numElementsTF.getText())];

     for(int i=0;i<gcDataArray.length;i++)
     {
      gcDataArray[i] = new ColoredIntegerAdapter(new ColoredObject(normalColor), new CountInteger(accessCounter, new CInteger(i)));
     }
     for(int i=0;i<gcDataArray.length;i++)
     {
        int x = (int) ((gcDataArray.length)*Math.random());
        Object tmp = gcDataArray[i];
        gcDataArray[i] = gcDataArray[x];
        gcDataArray[x] = tmp;
     }
  }

  AOrder buildAOrder()
  {
        AOrder order = aOrder;
        if(metricCBox.isSelected())
        {
             countOrder.setOrder(order);
            order = countOrder;
        }
        if(reverseCBox.isSelected())
        {
            order = new ReverseOrder(order);
        }
        if(graphicCBox.isSelected())
        {
            graphicOrder.setOrder(order);
            graphicOrder.setWaitTime(Integer.parseInt(compareDelayTF.getText()));
            order =  graphicOrder;
        }
        return order;
  }

  ASorter buildSorter()
  {
        ASorter sorter =  aCSorter;
        if(graphicSortCBox.isSelected())
        {
            sorter = new GraphicSorter (sorter, statusLabel1, Integer.parseInt(sortDelayTF.getText()));
        }
        sorter.setOrder(buildAOrder());
        return sorter;
  }

  void gSortBtn_actionPerformed(ActionEvent e)
  {

    (new Thread() {
      public void run()
      {

        accessCounter.clear();
        countOrder.clearCount();
        statusLabel2.setText("");
        buildSorter().sort(gcDataArray,0,gcDataArray.length-1);
        statusLabel1.setText("# of compares = "+countOrder.getCount());
        statusLabel2.setText("# of accesses: "+accessCounter.getCount());
      }
    }).start();
  }

  void compareWhiteRBtn_actionPerformed(ActionEvent e)
  {
     compareColor = new SorterColor(hiColorValue-1, hiColorValue-1, hiColorValue-1);
     graphicOrder.setCompareColor(compareColor);
  }

  void compareBlackRBtn_actionPerformed(ActionEvent e)
  {
     compareColor = new SorterColor(loColorValue, loColorValue, loColorValue);
          graphicOrder.setCompareColor(compareColor);
  }

    void metricCBox_actionPerformed(ActionEvent e)
    {

    }

    void dotsRBtn_actionPerformed(ActionEvent e)
    {
		graphPanelCommand = new GraphPanelCommand();
    }

    void barsRBtn_actionPerformed(ActionEvent e)
    {
		graphPanelCommand = new BarGraphPanelCommand();
    }



    void shakerRBtn_actionPerformed(ActionEvent e)
    {
    	aCSorter = new ShakerSorter(aOrder);
    }

  void sinkRBtn_actionPerformed(ActionEvent e)
  {
    	aCSorter = new SinkSorter(aOrder);
  }







}
