package org.cmdline.sudoku;

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

public class PuzzleList extends JFrame implements ActionListener, TreeSelectionListener, ListSelectionListener {
	Vector colnames = new Vector(Arrays.asList(new Object[] { "Solved","Title","Level" }));
	Vector rows = new Vector();
	ListTableModel model = new ListTableModel(rows);
    JList list = new JList();
	JScrollPane puzzleScroller = null;
	JTree puzzles = null;
	JTable puzzleList = null;
	JButton open = new JButton("Open");
	JButton delete = new JButton("Delete");
	String solved = null;
	static ImageIcon solvedCkMark = getIcon("images/checkmark.gif","checkmark");
	static ImageIcon puzzlesIcon = getIcon("images/puzzles.gif","puzzles");
	static ImageIcon[] puzzleIcon = new ImageIcon[] { getIcon("images/puzzle1.gif","puzzle1"), 
											   getIcon("images/puzzle2.gif","puzzle2"),
											   getIcon("images/puzzle3.gif","puzzle3") };

	public PuzzleList(String solved) {
		super("Puzzle List");
		this.solved = solved;	
		init();
	}
											
	public PuzzleList() {
		super("Puzzle List");
		init();
	}
	
	private void init() {
		addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent evt) {
            	setVisible(false);
            }
        });
        GridBagLayout gbl = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        Container content = getContentPane();
        content.setBackground(Color.white);
 		content.setLayout(gbl);
		PuzzleNode top = new PuzzleNode("Puzzles");
		top.setIcon(SolvingSudokuBoard.ico);
		
	    final ListSelectionModel lsm = list.getSelectionModel();
	    lsm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
   		lsm.addListSelectionListener(this);
 			
		puzzles = new JTree(top);
		puzzles.addTreeSelectionListener(this);
		puzzles.setCellRenderer(new PuzzleTreeCellRenderer());
        puzzles.setFont(puzzles.getFont().deriveFont(Font.BOLD,
                                               puzzles.getFont().getSize() * 1.4f));
		PuzzleNode sss = new PuzzleNode("Sunday Sudoku Solver");
		sss.setIcon(puzzlesIcon);
		sss.setFont(puzzles.getFont().deriveFont(Font.BOLD,puzzles.getFont().getSize() * .8f));
		top.add(sss);
		TreePath initPath = new TreePath(new Object[] { top,sss});
		puzzles.addSelectionPath(initPath);
		JScrollPane puzzlesPane = new JScrollPane(puzzles);
		puzzlesPane.setBackground(Color.white);
		puzzleList = new JTable(model);
    	puzzleList.setSelectionModel(lsm);
  		puzzleList.addMouseListener(new MouseAdapter() {
     		public void mouseClicked(MouseEvent e){
      			if (e.getClickCount() == 2) {
					String title = ((ListTableCell)puzzleList.getValueAt(lsm.getMinSelectionIndex(),1)).getText();
					Vector v = CannedGames.getGame(title);
					((SolvingSudokuBoard)SolvingSudokuBoard.applet).doPuzzle(v);
					setVisible(false);
					dispose();
         		}
      		}
     	});
		TableColumnModel tcm = puzzleList.getColumnModel();
		tcm.getColumn(0).setPreferredWidth(25);
		tcm.getColumn(0).setMinWidth(25);
		PuzzleCellRenderer renderer = new PuzzleCellRenderer();
		tcm.getColumn(0).setCellRenderer(renderer);
		tcm.getColumn(1).setPreferredWidth(200);
		tcm.getColumn(1).setMinWidth(200);
		tcm.getColumn(1).setCellRenderer(renderer);
		tcm.getColumn(2).setPreferredWidth(60);
		tcm.getColumn(2).setMinWidth(60);
		tcm.getColumn(2).setCellRenderer(renderer);
		puzzleList.setPreferredScrollableViewportSize(new Dimension(puzzleList.getPreferredSize().width,getContentPane().getPreferredSize().height));
		puzzleList.setModel(model);
		puzzleScroller = new JScrollPane(puzzleList);
		JSplitPane view = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,puzzlesPane,puzzleScroller);
		view.resetToPreferredSizes();
        c.gridwidth = 9;
        c.gridheight = 9;
        c.fill = c.BOTH;
        c.weightx = 1.0;
        c.weighty = 1.0;
		c.anchor = c.WEST;
        gbl.setConstraints(view,c);
		content.add(view);
		JPanel controls = new JPanel();
		controls.setBackground(Color.white);
		controls.add(open);
		open.setBackground(Color.white);
		open.addActionListener(this);
		controls.add(delete);
		delete.setBackground(Color.white);
		delete.addActionListener(this);
		c.gridwidth = 9; c.gridheight = 2;
		c.gridx = 1;
		c.gridy = 11;
		gbl.setConstraints(controls,c);
  		content.add(controls);
		pack();
		positionWindow();
	}

  	public void valueChanged(TreeSelectionEvent event) {
//    	System.out.println("Current Selection: " +
//    		puzzles.getLastSelectedPathComponent().toString());
    	String path = puzzles.getLastSelectedPathComponent().toString();
    	rows.clear();
    	if (path.equals("Sunday Sudoku Solver")) {
    		CannedGames.list(rows,solved);
  		}
//  		else System.out.println("path mismatch on " + path);
		model.fireTableDataChanged();
  	}
  	
 	public void actionPerformed(ActionEvent evt) {
		String cmd = evt.getActionCommand();
		System.out.println(cmd);
	}
  		
    public void valueChanged(final ListSelectionEvent e) {
		if (!e.getValueIsAdjusting()) return;
	    ListSelectionModel lsm = (ListSelectionModel)e.getSource();
		int id_index = list.getSelectedIndex();
    }
    
 	public Insets insets(int t, int l, int b, int r)
	{
		return new Insets(t,l,b,r);
	}
	
	// move it only 1/2 of way down to leave room for message window
	public void positionWindow()
	{
		Dimension sSize = this.getToolkit().getScreenSize();	// Position the window
  	 	int sHeight = sSize.height;
  	 	int sWidth = sSize.width;
  	 	Dimension aSize = this.getSize();
  	 	int aHeight = aSize.height;
  	 	int aWidth = aSize.width;
 	 	this.setLocation((sWidth-aWidth)/2,(sHeight-aHeight)/2);
	}
	
	public void processEvent(AWTEvent e) {
		super.processEvent(e);
		int id = e.getID();
		if (id == ComponentEvent.COMPONENT_SHOWN)
			SolvingSudokuBoard.allPaintAll(this);
	}
	
	private static ImageIcon getIcon(String icon,String title) {
		try {
			InputStream	is = SolvingSudokuBoard.class.getResourceAsStream(icon);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			BufferedOutputStream bos = new BufferedOutputStream(baos);
			BufferedInputStream bis = new BufferedInputStream(is);
			byte [] buf = new byte[1024];
			int cnt = bis.read(buf,0,buf.length);
			while (cnt > -1) {
				bos.write(buf,0,cnt);
				cnt = bis.read(buf,0,buf.length);
			}
			bis.close();
			bos.flush();
			bos.close();
			byte[] img = baos.toByteArray();
			return new ImageIcon(img,title);
		}
		catch(IOException ioex) { ioex.printStackTrace(); }
		return null;
	}
}

// This class manages the download table's data.
class ListTableModel extends AbstractTableModel
{
  // These are the names for the table's columns.
  private static final String[] columnNames = new String[] { "Solved","Title","Level" };
  private final Vector rows;
  
  public ListTableModel(Vector rows) {
  	this.rows = rows;
  }
  
  // Get table's column count.
  public int getColumnCount() {
    return 3;
  }

  // Get a column's name.
  public String getColumnName(int col) {
     return columnNames[col];
  }
  // Get table's row count.
  public int getRowCount() {
    return rows.size();
  }

  // Return editable
  public boolean isCellEditable(int row, int col) {
  	return false;
  }
  
  // Get value for a specific row and column combination.
  public Object getValueAt(int row, int col) {
  	Vector vrow = (Vector)rows.elementAt(row);
  	return vrow.elementAt(col);
//	return new Integer(((SudokuCell)board.getCells().elementAt(row*COLS+col)).getValue());
  }
/*
  // Set value for a specific row and column combination.
  public void setValueAt(Object value,int row,int col) {
  	if (value.equals("")) {
  		SudokuCell cell = (SudokuCell)board.getCells().elementAt(row*COLS+col);
		cell.setValue(0);  		
  	}
    if (isValidValue(value)) {	
  		int ivalue = new Integer((String)value).intValue(); 
  		SudokuCell cell = (SudokuCell)board.getCells().elementAt(row*COLS+col);
  		if (cell.isHintCell()) {
	 		cell.setValue(Math.abs(board.values[row*COLS+col]));
	 		board.addCell(cell);
	 		fireTableCellUpdated(row,col);
			return;
		}
  		int result = board.internal.set((byte)ivalue,cell.getIndex());
  		if (result != 0) {	// Q. Invalid duplicate value?
  			SudokuCell dup = (SudokuCell)board.getCells().elementAt(result);
  			dup.startError();
  		}
  		else {
  			cell.setValue(ivalue);
  			cell.setColor(board.getCurrColor());
  			board.addCell(cell);
  			if (board.complete()) fanfare();
 		}
  		fireTableCellUpdated(row,col);
  		click();
  	}
  	else Toolkit.getDefaultToolkit().beep();
  }
*/  
}

class ListTableCell {
	int col;
	String text;
	Icon ico;
	
	ListTableCell(int col,String text,Icon ico) {
		this.col = col;
		this.text = text;
		this.ico = ico;
	}
	
	public int getCol() { return col; }
	
	public String getText() { return text; }

	public Icon getIcon() { return ico; }
}