import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.io.Serializable;
import javax.swing.ImageIcon;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.*;

public class Gallery extends JPanel implements Observer, Serializable
{
  private Model model;
  private ArrayList<Item> items;

  // Bob the Builder this shit
  public Gallery(Model model)
  {
    // Hook up this observer so that it will be notified when the model
    // changes.
    this.model = model;
    this.setLayout(new FlowLayout(10));
    this.setBackground(Color.cyan);
    this.items = new ArrayList();
    reList();
    reFill();
    
    try
    {
      Item.fullStarImg = ImageIO.read(new File("src/main/resources/fullStar.png"));
    } catch(IOException e) {}
    try
    {
      Item.emptyStarImg = ImageIO.read(new File("src/main/resources/emptyStar.png"));
    } catch(IOException e) {}
    Item.fullStarImg = Item.fullStarImg.getScaledInstance(32, 32,  java.awt.Image.SCALE_SMOOTH);
    Item.emptyStarImg = Item.emptyStarImg.getScaledInstance(32, 32,  java.awt.Image.SCALE_SMOOTH);
    Item.fullStarIcon = new ImageIcon(Item.fullStarImg);
    Item.emptyStarIcon = new ImageIcon(Item.emptyStarImg);

    model.addObserver(this);
  }

  /**
  * Update with data from the model.
  */
  public void update(Object observable)
  {
    reList();
    reFill();
    revalidate();
    repaint();
  }
  
  private void reList()
  {
    ArrayList<PicData> temp = model.getPics();
    for (int i = items.size(); i < temp.size(); i++)
    {
      Item temp2 = new Item(temp.get(i));
      items.add(temp2);
    }
  }
  
  private void reFill()
  {
    if (model.getGrid())
    {
      this.setLayout(new FlowLayout(10));
    }
    else
    {
      this.setLayout(new GridLayout(0, 1));
    }

    this.removeAll();
    
    for (Item i: items)
    {
      if (i.getData().getRating() >= model.getFilter()) this.add(i);
    }

    this.setBackground(Color.cyan);
  }
}

class Item extends JPanel implements Serializable
{
  private PicData data;
  private ImageIcon picture;
  private JLabel pic;
  private JLabel name;
  private JPanel rating;
  private JLabel dateSize;
  public static Image fullStarImg;
  public static Image emptyStarImg;
  public static ImageIcon fullStarIcon;
  public static ImageIcon emptyStarIcon;
  private JRadioButton star1;
  private JRadioButton star2;
  private JRadioButton star3;
  private JRadioButton star4;
  private JRadioButton star5;
  private ButtonGroup stars;
  
  private class clickListener extends MouseInputAdapter
  {
    public void mousePressed(MouseEvent e)
    {
      JFrame tempFrame = new JFrame(data.getName());
      ImageIcon tempIcon = new ImageIcon(data.getPic());
      JLabel tempLabel = new JLabel(tempIcon, JLabel.CENTER);
      tempLabel.setMinimumSize(new Dimension(800, 600));
      tempFrame.getContentPane().add(tempLabel);
      tempFrame.pack();
	    tempFrame.setVisible(true);
    }
  }
  private clickListener clicklistener;
  
  private class superListener implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      if (e.getSource() == star1)
      {
        if (!(star1.isSelected()) || data.getRating() == 1)
        {
          star1.setSelected(false);
          star2.setSelected(false);
          star3.setSelected(false);
          star4.setSelected(false);
          star5.setSelected(false);
          star1.setIcon(emptyStarIcon);
          star2.setIcon(emptyStarIcon);
          star3.setIcon(emptyStarIcon);
          star4.setIcon(emptyStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(0);
        }
        else
        {
          star1.setSelected(true);
          star2.setSelected(false);
          star3.setSelected(false);
          star4.setSelected(false);
          star5.setSelected(false);
          star1.setIcon(fullStarIcon);
          star2.setIcon(emptyStarIcon);
          star3.setIcon(emptyStarIcon);
          star4.setIcon(emptyStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(1);
        }
      }
      else if (e.getSource() == star2)
      {
        if (!(star2.isSelected()) || data.getRating() == 2)
        {
          star1.setSelected(false);
          star2.setSelected(false);
          star3.setSelected(false);
          star4.setSelected(false);
          star5.setSelected(false);
          star1.setIcon(emptyStarIcon);
          star2.setIcon(emptyStarIcon);
          star3.setIcon(emptyStarIcon);
          star4.setIcon(emptyStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(0);
        }
        else
        {
          star1.setSelected(true);
          star2.setSelected(true);
          star3.setSelected(false);
          star4.setSelected(false);
          star5.setSelected(false);
          star1.setIcon(fullStarIcon);
          star2.setIcon(fullStarIcon);
          star3.setIcon(emptyStarIcon);
          star4.setIcon(emptyStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(2);
        }
      }
      else if (e.getSource() == star3)
      {
        if (!(star3.isSelected()) || data.getRating() == 3)
        {
          star1.setSelected(false);
          star2.setSelected(false);
          star3.setSelected(false);
          star4.setSelected(false);
          star5.setSelected(false);
          star1.setIcon(emptyStarIcon);
          star2.setIcon(emptyStarIcon);
          star3.setIcon(emptyStarIcon);
          star4.setIcon(emptyStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(0);
        }
        else
        {
          star1.setSelected(true);
          star2.setSelected(true);
          star3.setSelected(true);
          star4.setSelected(false);
          star5.setSelected(false);
          star1.setIcon(fullStarIcon);
          star2.setIcon(fullStarIcon);
          star3.setIcon(fullStarIcon);
          star4.setIcon(emptyStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(3);
        }
      }
      else if (e.getSource() == star4)
      {
        if (!(star4.isSelected()) || data.getRating() == 4)
        {
          star1.setSelected(false);
          star2.setSelected(false);
          star3.setSelected(false);
          star4.setSelected(false);
          star5.setSelected(false);
          star1.setIcon(emptyStarIcon);
          star2.setIcon(emptyStarIcon);
          star3.setIcon(emptyStarIcon);
          star4.setIcon(emptyStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(0);
        }
        else
        {
          star1.setSelected(true);
          star2.setSelected(true);
          star3.setSelected(true);
          star4.setSelected(true);
          star5.setSelected(false);
          star1.setIcon(fullStarIcon);
          star2.setIcon(fullStarIcon);
          star3.setIcon(fullStarIcon);
          star4.setIcon(fullStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(4);
        }
      }
      else
      {
        if (!(star5.isSelected()) || data.getRating() == 5)
        {
          star1.setSelected(false);
          star2.setSelected(false);
          star3.setSelected(false);
          star4.setSelected(false);
          star5.setSelected(false);
          star1.setIcon(emptyStarIcon);
          star2.setIcon(emptyStarIcon);
          star3.setIcon(emptyStarIcon);
          star4.setIcon(emptyStarIcon);
          star5.setIcon(emptyStarIcon);
          data.setRating(0);
        }
        else
        {
          star1.setSelected(true);
          star2.setSelected(true);
          star3.setSelected(true);
          star4.setSelected(true);
          star5.setSelected(true);
          star1.setIcon(fullStarIcon);
          star2.setIcon(fullStarIcon);
          star3.setIcon(fullStarIcon);
          star4.setIcon(fullStarIcon);
          star5.setIcon(fullStarIcon);
          data.setRating(5);
        }
      }
    }
  }
  private superListener superlistener;

  public Item(PicData p)
  {
    this.data = p;
    this.clicklistener = new clickListener();
    this.superlistener = new superListener();
    this.star1 = new JRadioButton(emptyStarIcon, false);
    star1.addActionListener(superlistener);
    this.star2 = new JRadioButton(emptyStarIcon, false);
    star2.addActionListener(superlistener);
    this.star3 = new JRadioButton(emptyStarIcon, false);
    star3.addActionListener(superlistener);
    this.star4 = new JRadioButton(emptyStarIcon, false);
    star4.addActionListener(superlistener);
    this.star5 = new JRadioButton(emptyStarIcon, false);
    star5.addActionListener(superlistener);
    this.stars = new ButtonGroup();
    stars.add(star1);
    stars.add(star2);
    stars.add(star3);
    stars.add(star4);
    stars.add(star5);
    star1.setSelected(false);
    star2.setSelected(false);
    star3.setSelected(false);
    star4.setSelected(false);
    star5.setSelected(false);
    this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    this.setPreferredSize(new Dimension(200, 300));
    this.picture = new ImageIcon(data.getPic());
    this.pic = new JLabel(picture, JLabel.CENTER);
    this.pic.addMouseListener(clicklistener);
    this.pic.setAlignmentX(LEFT_ALIGNMENT);
    this.pic.setPreferredSize(new Dimension(200, 200));
    this.name = new JLabel(data.getName(), JLabel.LEFT);
    this.name.setAlignmentX(LEFT_ALIGNMENT);
    this.name.setPreferredSize(new Dimension(200, 25));
    this.rating = new JPanel();
    this.rating.setLayout(new BoxLayout(this.rating, BoxLayout.X_AXIS));
    this.rating.add(star1);
    this.rating.add(star2);
    this.rating.add(star3);
    this.rating.add(star4);
    this.rating.add(star5);
    this.rating.setPreferredSize(new Dimension(200, 32));
    this.rating.setAlignmentX(LEFT_ALIGNMENT);
    this.dateSize = new JLabel(Long.toString(data.getLastmod()) + Long.toString(data.getSize()), JLabel.LEFT);
    this.dateSize.setAlignmentX(LEFT_ALIGNMENT);
    this.dateSize.setPreferredSize(new Dimension(200, 25));
    this.add(pic);
    this.add(name);
    this.add(rating);
    this.add(dateSize);
  }

  public PicData getData()
  {
    return data;
  }
}
  
