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

public class Sidepane extends JPanel implements Observer
{
  private Model model;
  private Colours colours;
  private JPanel thiccness;
  private previewPanel preview;

  // Bob the Builder this shit
  public Sidepane(Model model, Handler handler)
  {
    // Hook up this observer so that it will be notified when the model
    // changes.
    this.model = model;
    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    this.setPreferredSize(new Dimension(280, 720));
    colours = new Colours(model);
    preview = new previewPanel(model);
    this.add(colours);
    this.add(preview);
    model.addObserver(this);
  }

  /**
  * Update with data from the model.
  */
  public void update(Object observable)
  {
    this.setBackground(model.sideColour);
    revalidate();
    repaint();
  }
}

class Colours extends JPanel
{
  private Model model;
  private ArrayList<colourButton> colours;
  private JButton chooserButton;
  private JFrame chooserFrame;
  private JPanel chooserPanel;
  private JButton changeButton;
  private JButton confirmButton;
  private JColorChooser colourChooser;

  public Colours(Model m)
  {
    this.model = m;
    this.setLayout(new GridLayout(0, 2));
    this.setPreferredSize(new Dimension(280, 480));
    this.colours = new ArrayList();
    colourButton.model = m;
    colours.add(new colourButton(Color.red));
    colours.add(new colourButton(Color.green));
    colours.add(new colourButton(Color.blue));
    colours.add(new colourButton(Color.yellow));
    colours.add(new colourButton(Color.magenta));
    colours.add(new colourButton(Color.orange));
    colours.add(new colourButton(Color.cyan));
    //colours.add(new colourButton(Color.gray));

    this.changeButton = new JButton("Custom");
    changeButton.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        chooserFrame.pack();
	chooserFrame.setVisible(true);
      }
    });
    this.chooserFrame = new JFrame("Chooser Window");
    this.colourChooser = new JColorChooser();
    this.confirmButton = new JButton("Select this colour?");
    confirmButton.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        changeButton.setBackground(colourChooser.getColor());
        model.changeColour(colourChooser.getColor());
      }
    });
    this.chooserPanel = new JPanel(new FlowLayout());
    chooserFrame.getContentPane().add(chooserPanel);
    chooserPanel.add(colourChooser);
    chooserPanel.add(confirmButton);
    this.add(changeButton);
    
    for(colourButton b: colours)
    {
      this.add(b);
      b.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent e)
        {
          colourButton.model.changeColour(b.getBackground());
        }
      });
    }
  }
}

class colourButton extends JButton
{
  public static Model model;

  public colourButton(Color c)
  {
    this.setBackground(c);
    this.setOpaque(true);
  }
  
  public String toString()
  {
    return this.getBackground().toString();
  }
}

class previewPanel extends JPanel
{
  private Model model;
  private JSlider slider;
  //private JLabel label;
  private previewLine preview;
  
  public previewPanel(Model m)
  {
    this.model = m;
    //this.label = new JLabel("Thiccness");
    this.slider = new JSlider(1, 50, model.getThiccness());
    this.slider.addChangeListener(new ChangeListener()
      {
        public void stateChanged(ChangeEvent e)
        {
          model.changeThiccness(slider.getValue());
        }
      });
    this.slider.setPreferredSize(new Dimension(280, 75));
    this.preview = new previewLine(m);
    this.setPreferredSize(new Dimension(280, 240));
    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    this.add(preview);
    //this.add(label);
    this.add(slider);
  }
}

class previewLine extends JPanel implements Observer
{
  private Model model;
  private previewPanel parent;
  
  public previewLine(Model m)
  {
    this.model = m;
    model.addObserver(this);
  }

  public void update(Object observable)
  {
    newBackground();
    revalidate();
    repaint();
  }

  public void newBackground()
  {
    Color temp = model.getColour();
    int r = temp.getRed();
    int g = temp.getGreen();
    int b = temp.getBlue();

    if (r == g && g == b)
    {
      if (r > 125) r = g = b = 0;
      else r = g = b = 255;
    }
    else
    {
      r = 255 - r;
      g = 255 - g;
      b = 255 - b;
    }

    this.setBackground(new Color(r, g, b));
  }
  
  public void paintComponent(Graphics g)
  {
    super.paintComponent(g);
    Graphics2D gtemp = (Graphics2D) g;
    gtemp.setColor(model.getColour());
    gtemp.setStroke(new BasicStroke(model.getThiccness(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    gtemp.drawLine((int)(this.getSize().width*.25), (this.getSize().height/2), (int)(this.getSize().width*.75), (this.getSize().height/2));
  }
}

