package org.cmdline.sudoku;

import net.n3.nanoxml.*;
import java.io.*;
import java.util.*;
import java.awt.Color;

public class PuzzleOpener implements Constants, Runnable {

	Vector cells;
	Stack solution;
	String path = null;
	static int row,col;
	static int value;
	static boolean colorFirst = false;
	static String color = null;
	SudokuCell current = null;
	SolvingTableModel model = null;	
	SolvingSudokuBoard board = null;
	
	public PuzzleOpener(SolvingSudokuBoard board,Vector cells,Stack solution,SolvingTableModel model,File puzzle) {
		this.board = board;
		this.cells = cells;
		this.solution = solution;
		this.model = model;
		path = puzzle.getPath();
	}
	
	public void run() {
		try {
			IXMLReader reader = null;
			IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
			if (System.getProperty("os.name").startsWith("Windows")) {
				BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
				reader = new StdXMLReader(bis);
			}
			else reader = StdXMLReader.fileReader(path);
			parser.setReader(reader);
			parser.setBuilder(new Builder());
			parser.parse();
		}
		catch (Throwable tossed) { tossed.printStackTrace(); }
	}
	
	class Builder implements IXMLBuilder {
		int[] puzzle = new int[81];
		
		public void startBuilding(String systemID,          
								  int lineNr)
		{
//			System.out.println("Document started");
		}
	
		public void                                         
				newProcessingInstruction(String target,
										 Reader reader)
			throws IOException
		{
//			System.out.println("New PI with target " + target);
		}
	
		public void startElement(String name,              
								 String nsPrefix,
								 String nsSystemID,
								 String systemID,
								 int lineNr)
		{
//			System.out.println("Element started: " + name);
			// Reset defaults
			if (name.equals("cell")) {
				colorFirst = false;
				color = null;
			}
		}
	
		public void endElement(String name,                
							   String nsPrefix,
							   String nsSystemID)
		{
//			System.out.println("Element ended: " + name);
			if (name.equals("cell")) {
				int index = row*COLS+col;
				current = (SudokuCell)cells.elementAt(index);
				if (colorFirst) current.setColorFirst(true);
				current.setColor(color);
				current.setValue(value);
				solution.push(current);				
			}
			else if (name.equals("puzzle")) {
				System.out.println("PuzzleOpener: is color first " + colorFirst);
				model.fireTableDataChanged();
				if (colorFirst) board.setCurrColor(getColor(color));
				else board.setCurrColor(getColor(color),false);
				if (color.equals(Color.black))
					board.setup.setSelected(true);
				else 
					board.solve.setSelected(true);
			}
		}
	
		private Color getColor(String color) {
			if (color.equals("black")) return Color.black;
			else if (color.equals("gray")) return Color.gray;
			else if (color.equals("blue")) return Color.blue;
			else if (color.equals("cyan")) return Color.cyan;
			else if (color.equals("green")) return Color.green;
			else if (color.equals("lightGray")) return Color.gray;
			else if (color.equals("magenta")) return Color.magenta;
			else if (color.equals("orange")) return Color.orange;
			else if (color.equals("pink")) return Color.pink;
			else if (color.equals("red")) return Color.red;
			else if (color.equals("yellow")) return Color.yellow;
			throw new IllegalArgumentException("Unknown color " + color);
		}		
	
		public void addAttribute(String key,               
								 String nsPrefix,
								 String nsSystemID,
								 String value,
								 String type)
		{
//			System.out.println(" " + key + ": "
//							   + type + " = " + value);
			if (key.equals("value")) PuzzleOpener.value = new Integer(value).intValue();
			else if (key.equals("color")) PuzzleOpener.color = value;
			else if (key.equals("row")) PuzzleOpener.row = new Integer(value).intValue();
			else if (key.equals("col")) PuzzleOpener.col = new Integer(value).intValue();
			else if (key.equals("first")) PuzzleOpener.colorFirst = new Boolean(value).booleanValue();	
		}
	
		public void elementAttributesProcessed(             
				String name,
				String nsPrefix,
				String nsSystemID)
		{
			// nothing to do
		}
	
		public void addPCData(Reader reader,               
							  String systemID,
							  int lineNr)
			throws IOException
		{
//			System.out.println("#PCDATA");
		}
	
		public Object getResult()                          
		{
			return null;
		}
	}

}