/*
* kolko i krzyzyk - GUI
*
* @see	ox.java desk.java
* @version    2.1, 04.10.2002
* @autor	Zbigniew Lisiecki, zlisiecki@evot.org
*		GNU Public Licence
*
* todo:
* 	init.setLayout needed for New Game, but it inhibits ox.paint
*/
import javax.swing.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;

public class ox extends JApplet {
	public static	gpanel gp;
	static boolean	editing = false;
	static boolean	linenums = true;
	static boolean	showttab = true;
	static File		filename = null;
	public static JMenu[]	menus = {
		new JMenu ("File"),
		new JMenu ("Edit"),
		new JMenu ("Options")
	};
	JMenuItem[]	items0 = {
		new JMenuItem ("New Game"),
		new JMenuItem ("Load"),
		new JMenuItem ("Save"),
		new JMenuItem ("Save as"),
		new JMenuItem ("Help"),
		new JMenuItem ("Exit")
	};
	JCheckBoxMenuItem[]	items1 = {
		new JCheckBoxMenuItem ("empty"),
		new JCheckBoxMenuItem ("white"),
		new JCheckBoxMenuItem ("black")
	};
	public static JMenuItem[]	items2 = {
		new JMenuItem ("Take back"),
		new JMenuItem ("Move forward"),
		new JMenuItem ("Play with oneself"),
		new JMenuItem ("Play"),
		new JMenuItem ("Play white"),
		new JMenuItem ("Play black")
	};
	JMenuItem[]	items3 = {
		new JMenuItem ("Parameters"),
		new JMenuItem ("Evaluate"),
		new JMenuItem ("Accounted for")
	};
	JCheckBoxMenuItem[]	items4 = {
		new JCheckBoxMenuItem ("Line numbers"),
		new JCheckBoxMenuItem ("TTab on"),
		new JCheckBoxMenuItem ("show TTab %"),
		new JCheckBoxMenuItem ("presorting on"),
		new JCheckBoxMenuItem ("show presorted %"),
		new JCheckBoxMenuItem ("show depth"),
		new JCheckBoxMenuItem ("show time"),
		new JCheckBoxMenuItem ("hqueue debug"),
		new JCheckBoxMenuItem ("compute debug"),
		new JCheckBoxMenuItem ("newmoves debug"),
		new JCheckBoxMenuItem ("m3 debug"),
		new JCheckBoxMenuItem ("m4 debug")
	};
	JButton butt[] = {
		new JButton ("<"),
		new JButton (">")
	};
    static JTextField   tf[] = {
		new JTextField (4),
		new JTextField (20)
	};
	public ActionListener al = new ActionListener () {
		public void actionPerformed (ActionEvent e) {
			Object src = e.getSource();
			String ac = e.getActionCommand();
            if (src instanceof JMenuItem) {
				if (ac == "New Game")	{ gp.newgame(); }
				if (ac == "Load")		{ load(); }
				if (ac == "Save")		{ save(); }
				if (ac == "Save as")	{ saveas(); }
				if (ac == "Help")		{ help(); }
				if (ac == "Exit")		{ System.exit(0); }
				if (ac == "Play" ||
					ac == "Play white" ||
					ac == "Play black")	{
					editing = false;
					items1[0].setState (false);
					items1[1].setState (false);
					items1[2].setState (false);
					gp.wipelila ();
					gp.repaint ();
					RepaintManager.currentManager(gp).paintDirtyRegions();
					gp.piece = gp.dsk.swabpiece (gp.piece);
					gp.answere ();
				}
				if (ac == "Take back")		{ takeback (); }
				if (ac == "Move forward")	{ moveforward(); }
				if (ac == "Play with oneself") {
					editing = false;
					while (gp.answere () == 0) {
						gp.wipelila ();
						gp.repaint ();
						RepaintManager.currentManager(gp).paintDirtyRegions();
					}
				}
				if (ac == "Parameters") {
					param dlg = new param(null);
					dlg.show();
				}
				if (ac == "Evaluate") {
        			int r = gp.dsk.evaluate();
        			tf[0].setText (String.valueOf(r));
				}
				if (ac == "Accounted for") {
					byte moves[][] = gp.dsk.newmoves (1, 0);
					for (int w = 0; w < moves.length; w++) {
						gp.putapiece (moves[w][0],moves[w][1],desk.lila);
					}
				}
			}
            if (src instanceof JButton) {
				if (ac == "<")	{ takeback (); }
				if (ac == ">")	{ moveforward(); }
			}
            if (src instanceof JCheckBoxMenuItem) {
                if (ac == "empty") {
					gp.piece = desk.empty;
					editing = true;
					items1[1].setState (false);
					items1[2].setState (false);
				}
                if (ac == "white") {
					gp.piece = desk.white;
					editing = true;
					items1[0].setState (false);
					items1[2].setState (false);
					menus[1].remove(6);
					menus[1].insert(items2[5], 6);
				}
                if (ac == "black") {
					gp.piece = desk.black;
					editing = true;
					items1[0].setState (false);
					items1[1].setState (false);
					menus[1].remove(6);
					menus[1].insert(items2[4], 6);
				}
                if (ac == "Line numbers") {
					if (ox.linenums)	ox.linenums = false;
					else				ox.linenums = true;
					gp.repaint();
				}
                if (ac == "TTab on") {
					if (gp.dsk.ttabon) {
						gp.dsk.ttabon = false;
						showttab = false;
						items4[2].setState (false);
					}
					else {
						gp.dsk.ttabon = true;
					}
				}
                if (ac == "show TTab %") {
					if (showttab)	showttab = false;
					else {
						showttab = true;
						gp.dsk.ttabon = true;
						items4[1].setState (true);
						gp.dsk.showpresorted = false;
						items4[4].setState (false);
						gp.dsk.gpshowdepth = false;
						items4[5].setState (false);
						gp.showtime = false;
						items4[6].setState (false);
					}
				}
                if (ac == "presorting on") {
					if (desk.presort) {
						desk.presort = false;
						gp.dsk.showpresorted = false;
						items4[4].setState (false);
					}
					else
						desk.presort = true;
				}
                if (ac == "show presorted %") {
					if (gp.dsk.showpresorted)
						gp.dsk.showpresorted = false;
					else {
						gp.dsk.showpresorted = true;
						showttab = false;
						items4[2].setState (false);
						gp.dsk.gpshowdepth = false;
						items4[5].setState (false);
						gp.showtime = false;
						items4[6].setState (false);
					}
				}
                if (ac == "show depth") {
					if (gp.dsk.gpshowdepth)
						gp.dsk.gpshowdepth = false;
					else {
						gp.dsk.gpshowdepth = true;
						showttab = false;
						items4[2].setState (false);
						gp.dsk.showpresorted = false;
						items4[4].setState (false);
						gp.showtime = false;
						items4[6].setState (false);
					}
				}
                if (ac == "show time") {
					if (gp.showtime)
						gp.showtime = false;
					else {
						gp.showtime = true;
						showttab = false;
						items4[2].setState (false);
						gp.dsk.showpresorted = false;
						items4[4].setState (false);
						gp.dsk.gpshowdepth = false;
						items4[5].setState (false);
					}
				}
                if (ac == "hqueue debug") {
					if (gp.dsk.hq.hdebug)
						gp.dsk.hq.hdebug = false;
					else
						gp.dsk.hq.hdebug = true;
				}
                if (ac == "compute debug") {
					if (gp.dsk.computedebug)
						gp.dsk.computedebug = false;
					else
						gp.dsk.computedebug = true;
				}
                if (ac == "newmoves debug") {
					if (gp.dsk.newmovesdebug)
						gp.dsk.newmovesdebug = false;
					else
						gp.dsk.newmovesdebug = true;
				}
                if (ac == "m3 debug") {
					if (gp.dsk.must3debug)
						gp.dsk.must3debug = false;
					else
						gp.dsk.must3debug = true;
				}
                if (ac == "m4 debug") {
					if (gp.dsk.must4debug)
						gp.dsk.must4debug = false;
					else
						gp.dsk.must4debug = true;
				}
			//if (src instanceof JTextField) {
            //    int pid = Integer.parseInt(ac);
            //    System.out.println (pid);
            //}
			}
		}
	};
	void takeback () {
		if (gp.movnr > 0) {
			gp.movnr--;
			byte x = gp.moves[gp.movnr][0];
			byte y = gp.moves[gp.movnr][1];
			gp.piece = gp.dsk.board[x][y];
			gp.putapiece (x, y, desk.empty);
		}
	}
	void moveforward () {
		byte x = gp.moves[gp.movnr][0];
		byte y = gp.moves[gp.movnr][1];
		if (x >= 0 && x < gp.xsize &&
			y >= 0 && y < gp.ysize) {
			gp.putapiece (x, y, gp.piece);
			gp.piece = gp.dsk.swabpiece(gp.piece);
			gp.movnr++;
		}
	}
	public void load () {
	JFileChooser chooser = new JFileChooser();
	//chooser.setCurrentDirectory (File ("/home/zbyszek/src/ox"));
	int c = chooser.showOpenDialog (null);
	if (c == JFileChooser.APPROVE_OPTION) {
		filename = chooser.getSelectedFile();
		int i = 0;
		String	s;
		try {
			BufferedReader r = new BufferedReader (
				new InputStreamReader (
				new FileInputStream (filename)));
			gp.piece = desk.white;
			while ((s = r.readLine()) != null) {
				if (s.charAt(0) != '#') {
					StringTokenizer st =
					new StringTokenizer (s, " 	,");
					for (int j = 0; j < 2; j++)
						if (st.hasMoreTokens()) {
							gp.moves[i][0] =
							Byte.parseByte(st.nextToken());
							gp.moves[i][1] =
							Byte.parseByte(st.nextToken());
							gp.putapiece (
								gp.moves[i][0],
								gp.moves[i][1], gp.piece);
							gp.piece = desk.swabpiece(gp.piece);
							i++;
						}
					}
					gpanel.movnr = i;
				}
			} catch (IOException ioe) {
				System.out.println ("cannot read from " + filename);
			}
		}
	}
	public void saveas () {
	// comment out for internet version
		JFileChooser chooser = new JFileChooser();
		//chooser.setCurrentDirectory (File ("/home/zbyszek/src/ox"));
		int r = chooser.showOpenDialog (null);
		if (r == JFileChooser.APPROVE_OPTION) {
			filename = chooser.getSelectedFile();
			save ();
		}
	}
	public static void save () {
	// comment out for internet version
		try {
			PrintWriter o = new PrintWriter (
				new BufferedWriter (
				new FileWriter (filename)));
			o.println("# kolko i krzyzyk");
			o.println("# maxdepth: "+ gp.dsk.maxdepth);
			o.print  ("# position: ");
			for (int j = 0; j < gp.ysize; j++)
			for (int i = 0; i < gp.xsize; i++) {
				if (gp.dsk.board[i][j] == desk.white)
					o.print ("O(" + i + "," + j + ") ");
				if (gp.dsk.board[i][j] == desk.black)
					o.print ("X(" + i + "," + j + ") ");
			}
			o.println();
			o.print  ("# moves: ");
			for (int i = 0; i < gp.movnr; i++) {
				// white
				o.print (	gp.moves[i][0] + "," +
							gp.moves[i][1]);
				if (++i < gp.movnr)		// black
					o.println (	"	" + 
						gp.moves[i][0] + "," +
						gp.moves[i][1]);
				else
					o.println();
			}
			o.close();
		} catch (IOException ioe) {
			System.out.println ("cannot write to " + filename);
		}
	}
	public static void help () {
		JFrame f = new JFrame ("ox help");
		JTextPane	tp = new JTextPane();
		JScrollPane	sp = new JScrollPane(tp);
		String filename = new String ("ox.readme");
		int i = 0;
		String	s;
		try {
			BufferedReader r = new BufferedReader (
				new InputStreamReader (
				new FileInputStream (filename)));
			while ((s = r.readLine()) != null) {
				tp.setText (tp.getText() + s + "\n");
			}
		} catch (IOException ioe) {
			JOptionPane.showMessageDialog (null,
				"cannot read "+filename, "Error",
				 JOptionPane.ERROR_MESSAGE);
			return;
		}
		f.getContentPane().add (sp);
		f.setSize (500, 400);
		f.setVisible (true);
 	}
	public static void setupClosing (JFrame frame) {
        frame.addWindowListener (new WindowAdapter() {
            public void windowClosing (WindowEvent e) {
                System.exit(0);
            }
        });
    }
	public void init() {
		for (int i = 0; i < items0.length; i++) {
			items0[i].addActionListener (al);
			menus[0].add (items0[i]);
		}
		for (int i = 0; i < items1.length; i++) {
			items1[i].addActionListener (al);
			menus[1].add (items1[i]);
		}
		for (int i = 0; i < items2.length; i++) {
			items2[i].addActionListener (al);
		}
		for (int i = 0; i < items2.length - 2; i++) {
			menus[1].add (items2[i]);
		}
		for (int i = 0; i < items3.length; i++) {
			items3[i].addActionListener (al);
			menus[2].add (items3[i]);
		}
		for (int i = 0; i < items4.length; i++) {
			items4[i].addActionListener (al);
			menus[2].add (items4[i]);
		}
		for (int i = 0; i < tf.length; i++) {
        	tf[i].setText (String.valueOf(0));
			tf[i].addActionListener (al);
			tf[i].setEditable (false);
			tf[i].setMaximumSize (new Dimension(80, 24)); 
		}
		JMenuBar mb = new JMenuBar();
		for (int i = 0; i < menus.length; i++) {
			mb.add (menus[i]);
		}
		mb.add(butt[0]);
		mb.add(butt[1]);

		butt[0].addActionListener (al);
		butt[1].addActionListener (al);
		mb.add(tf[0]);
		mb.add(tf[1]);
		setJMenuBar (mb);

	// this won't work
		Dimension d = butt[0].getSize();
		butt[0].setSize (d.width, (int)(0.6*d.height));
		butt[1].setSize (d.width, (int)(0.6*d.height));

		linenums = true;
		items4[0].setState (true);
		gp.dsk.ttabon = true;
		items4[1].setState (true);
		desk.presort = true;
		items4[3].setState (true);
		gpanel.showtime = true;
		items4[6].setState (true);
		Container cp = getContentPane ();
		cp.setLayout (new BorderLayout());
		gp = new gpanel();
		cp.add ("Center", gp);
		gp.newgame();
	}
	public static void main (String args[]) {
		if (args.length > 1)
            if (args[0].equals("-pid")) {
                //pid = Integer.parseInt(args[1]);
            }
		ox game = new ox ();
        JFrame frame = new JFrame ("ox");
        setupClosing (frame);
        frame.getContentPane().add (game);
		game.init();
        int width  = gp.step * gp.xsize + 11;
        int height = gp.step * gp.ysize + 62;
        frame.setSize (width, height);
        frame.setLocation (30,30);
        frame.setTitle ("kółko i krzyżyk");
        frame.setVisible (true);
	}
}

class param extends JDialog {
	JLabel lab[] = {
		new JLabel (" max width      "),
		new JLabel (" max depth      "),
		new JLabel (" mmax depth    "),
		new JLabel (" shown depth   "),
		new JLabel (" debug depth   "),
		new JLabel (" max ram (MB)  "),
		new JLabel (" hash size        "),
		new JLabel (" alpha             "),
		new JLabel (" beta               "),
		new JLabel (" add3              ") 
	};
	JTextField tf[] = {
		new JTextField (7),
		new JTextField (7),
		new JTextField (7),
		new JTextField (7),
		new JTextField (7),
		new JTextField (7),
		new JTextField (7),
		new JTextField (7),
		new JTextField (7),
		new JTextField (7),
		new JTextField (7) 
	};
	JTextField status = new JTextField (18);
	public void out () {
		tf[0].setText (String.valueOf(desk.maxwidth));
		tf[1].setText (String.valueOf(desk.maxdepth));
		tf[2].setText (String.valueOf(desk.mmaxdepth));
		tf[3].setText (String.valueOf(desk.showndepth));
		tf[4].setText (String.valueOf(desk.debugdepth));
		tf[5].setText (String.valueOf(hqueue.maxram/(1024 * 1024)));
		tf[6].setText (String.valueOf(hqueue.hsize));
		tf[7].setText (String.valueOf(gpanel.ialpha));
		tf[8].setText (String.valueOf(gpanel.ibeta));
		tf[9].setText (String.valueOf(desk.add3));
	}
	public param (JFrame parent) {
		super (parent, "Set parameters", true);
		Container cp = getContentPane();
		cp.setLayout (new FlowLayout());
		ActionListener al = new ActionListener () {
			public void actionPerformed (ActionEvent e) {
				Object src = e.getSource();
				String ac = e.getActionCommand();
				if (ac == "Abort") {
					setVisible (false);
					return;
				}
				if (ac == "Reset") {
					desk.maxwidth = 128;
					desk.maxdepth = 3;
					desk.mmaxdepth = 7;
					desk.showndepth = 2;
					desk.debugdepth = 2;
					hqueue.maxram = 128 * 1024 * 1024;
					hqueue.hsize = 256;
					gpanel.ialpha = -200;
					gpanel.ibeta = 200;
					desk.add3 = 24;
					out();
					//setVisible (false);
					//return;
				}
				try { desk.maxwidth = Integer.valueOf(
					tf[0].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					desk.maxwidth = 128;
				}
				try { desk.maxdepth = Integer.valueOf(
					tf[1].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					desk.maxdepth = 3;
				}
				try { desk.mmaxdepth = Integer.valueOf(
					tf[2].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					desk.mmaxdepth = 7;
				}
				try { desk.showndepth = Integer.valueOf(
					tf[3].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					desk.showndepth = 2;
				}
				try { desk.debugdepth = Integer.valueOf(
					tf[4].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					desk.showndepth = 3;
				}
				try { hqueue.maxram = 1024 * 1024 * Integer.valueOf(
					tf[5].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					hqueue.maxram = 128 * 1024 * 1024;
				}
				try { hqueue.hsize = Integer.valueOf(
					tf[6].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					hqueue.hsize = 256;
				}
				try { gpanel.ialpha = Integer.valueOf(
					tf[7].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					gpanel.ialpha = -200;
				}
				try { gpanel.ibeta = Integer.valueOf(
					tf[8].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					gpanel.ibeta = 200;
				}
				try { desk.add3 = Integer.valueOf(
					tf[9].getText()).intValue();
				} catch (java.lang.NumberFormatException ex) {
					desk.add3 = 24;
				}
				if (desk.maxwidth <= 3) {
					status.setText (String.valueOf (
						"maxwidth must be > 3"));
					ac = "Error";
				}
				if (ac == "Enter") {
					setVisible (false);
				}
			}
		};
		out();
		for (int i = 0; i < lab.length; i++) {
			cp.add (lab[i]);
			cp.add (tf[i]);
			tf[i].addActionListener (al);
		}
		JButton ok = new JButton ("Enter");
		JButton ab = new JButton ("Abort");
		JButton re = new JButton ("Reset");
		ok.addActionListener (al);
		ab.addActionListener (al);
		re.addActionListener (al);
		cp.add (ok);
		cp.add (ab);
		cp.add (re);
		status.setText (String.valueOf ("status line"));
		status.setEditable (false);
		cp.add (status);
		setSize (250, 330);
	}
}

class gpanel extends JPanel implements MouseListener {
	public final int	step = 30;			// grid diameter
	public static int	xsize = 16,
						ysize = 16;   		// initial size
	public static desk	kern,				// playing kernel
						dsk;				// desk shown on the screen
	public static byte	piece;
	public static byte	moves[][] = null;	// for history only
	public static final int	maxmoves = 512;	// history size
	public static int	movnr;
	public static int	ialpha = -200,		// initial window values
						ibeta = 200;
	public static byte	newboard = 0;
	public static boolean	showtime = false;
	Color lyellow = new Color(255,229,196);
	Color dyellow = new Color(166,149,113);
	//Color lila	  = new Color(255,179,246);
	//Color lila	  = new Color(232,189,216);
	Color lila	  = new Color(221,197,213);
	Color lgray	  = new Color(209,206,209);

	public gpanel() {
		addMouseListener (this);
	}
	public void paintComponent (Graphics g) {
		super.paintComponent (g);
		setBackground (Color.lightGray);
		g.setColor(Color.lightGray);
		Dimension d = getSize();
		byte xnew = (byte)(d.width  / step);
		byte ynew = (byte)(d.height / step);
		//System.out.println("drawboard: x,ynew "+xnew+","+ynew);
		if (dsk != null && (xnew != xsize || ynew != ysize)) {
			resize (xnew, ynew);
			newboard = 1;
		}
		g.fillRect (0, 0, xsize, ysize);
		g.setColor(Color.black);
		for (int i = 1; i <= xsize; i++)		// vertical
			g.drawLine (i*step, 0, i*step, d.height);
		for (int i = 1; i <= ysize; i++)		// horizontal
			g.drawLine (0, i*step, d.width, i*step);
		int psize = step * 3/4;		// piece diameter
		int	col, row;
		if (dsk != null)
		for (int i = 0; i < xsize; i++)
		for (int j = 0; j < ysize; j++) {
			switch (dsk.board[i][j]) {
			case desk.empty:
				g.setColor(Color.lightGray);
				break;
			case desk.white:
				g.setColor(Color.white);
				break;
			case desk.black:
				g.setColor(Color.black);
				break;
			case desk.lyellow:
				g.setColor(lyellow);
				break;
			case desk.dyellow:
				g.setColor(dyellow);
				break;
			case desk.lila:
				g.setColor(lila);
				break;
			default:
				System.out.println ("paintComponent: wrong piece " +
					dsk.board[i][j]);
			}
			col = i * step + step * 1/8;
			row = j * step + step * 1/8;
			g.fillOval (col, row, psize, psize);
		}
		if (ox.linenums) {
			g.setColor(Color.black);
			for (int i = 1; i < xsize; i++)
				g.drawString (Integer.toString((int)i),
					i*step+step/4,3*step/5);
			for (int j = 1; j < ysize; j++)
				g.drawString (Integer.toString((int)j),
					step/4,j*step+step*4/5);
		}
	}
	public void newgame () {
		ox.editing = false;
		dsk  = new desk((int)xsize, (int)ysize);
		moves = new byte[maxmoves][2];
		movnr = 0;
		piece = desk.white;		// computer starts with white
		byte x = (byte)(xsize/2 - 1);
		byte y = (byte)(ysize/2 - 1);
		dsk.board[x][y] = piece;
		moves[movnr][0] = x;
		moves[movnr][1] = y;
		movnr++;
		repaint();
		piece = desk.black;
	}

	/*
	* resize the window: alloc a new board
	* all game computations will be lost
	* pieces will be moved to new positions
	* history will be recalculated into new coordinates
	*/
	void resize (byte xnew, byte ynew) {

		/* check if makeing smaller would cut something out */
		if (xnew < xsize || ynew < ysize) {
			for (byte i = 0; i < xsize; i++)
			for (byte j = 0; j < ysize; j++)
				if ((dsk.board[i][j] == desk.white ||
					 dsk.board[i][j] == desk.black) &&
					(i >= xnew || j >= ynew))
					/*
					* won't make the board smaller
					*/
					return;
		}

		byte bnew[][] = new byte[xnew][ynew];
		byte bnewd[][] = new byte[xnew][ynew];

		/*
		* compute the weighted middle of the game pieces position
		* and shift them to (x,y)new/2
		*/

		int midx = 0;
		int midy = 0;
		int n = 0;
		for (byte i = 0; i < xsize; i++)
		for (byte j = 0; j < ysize; j++)
			if (dsk.board[i][j] == desk.white ||
				dsk.board[i][j] == desk.black) {
				midx += i;
				midy += j;
				n++;
			}
		if (n == 0) { return; }
		midx /= n;
		midy /= n;
		byte dx = (byte)(xnew/2 - midx);
		byte dy = (byte)(ynew/2 - midy);
		for (byte i = 0; i < xsize; i++)
		for (byte j = 0; j < ysize; j++)
			if (dsk.board[i][j] == desk.white ||
				dsk.board[i][j] == desk.black) {
				bnew[i+dx][j+dy] = dsk.board[i][j];
				bnewd[i+dx][j+dy] = dsk.board[i][j];
			}
		xsize = xnew;
		ysize = ynew;
		dsk.xsize = xnew;
		dsk.ysize = ynew;
		dsk.board = bnew;
		//dsk.board = bnewd;

		/*
		* recalculate the history
		*/
		if (moves != null) {
			byte newmoves[][] = new byte[maxmoves][2];
			for (byte i = 0; i < movnr; i++) {
				newmoves[i][0] = (byte)(moves[i][0] + dx);
				newmoves[i][1] = (byte)(moves[i][1] + dy);
			}
			moves = newmoves;
		}
		repaint();
		RepaintManager.currentManager(this).paintDirtyRegions();
		return;
	}
	public void wipelila () {
		for (byte i = 0; i < xsize; i++)
		for (byte j = 0; j < ysize; j++)
			if (dsk.board[i][j] != desk.white &&
				dsk.board[i][j] != desk.black)
				dsk.board[i][j] = desk.empty;
	}
	public int answere () {
		long t1 = System.currentTimeMillis();

		byte	lastx = -1, lasty = -1;		// last move
		byte	last1x = -1, last1y = -1;	// 2.-last move
		dsk.piece = piece;
		if (movnr > 1) {					// computers last move
			last1x = moves[movnr-2][0];
			last1y = moves[movnr-2][1];
		}
		if (movnr > 0) {					// computer last move
			lastx = moves[movnr-1][0];		// players last move
			lasty = moves[movnr-1][1];
		}
		int r;
		kern = new desk (dsk);
		r = kern.compute (0,ialpha,ibeta,lastx,lasty,last1x,last1y);

		ox.tf[0].setText (String.valueOf(r));
		if (ox.showttab) {
			float f;
			if (desk.stored == 0)	f = 0;
			else f = (float)desk.recalled/(float)desk.stored;
			ox.tf[1].setText ("TT%=" + String.valueOf(f));
			//ox.tf[1].setText (String.valueOf(desk.recalled)+"-"+String.valueOf(desk.stored));
		}
		if (showtime) {
			long t2 = System.currentTimeMillis();
			ox.tf[1].setText (String.valueOf(t2-t1) + " millisec.");
		}
		if (r == desk.matval) {
			dsk.board[kern.answx][kern.answy] = piece;
			repaint();
			JOptionPane.showMessageDialog (null,
				"you have lost", "game over", JOptionPane.ERROR_MESSAGE);
			return (-1);
		}
		else if (r == -desk.matval) {
			JOptionPane.showMessageDialog (null,
				"you have won", "game over", JOptionPane.ERROR_MESSAGE);
			return (-1);
		}
		dsk.board[kern.answx][kern.answy] = piece;
		moves[movnr][0] = kern.answx;
		moves[movnr][1] = kern.answy;
		movnr++;
		repaint();
		RepaintManager.currentManager(this).paintDirtyRegions();
		piece = dsk.swabpiece (piece);
		ox.menus[1].remove(6);
		if (piece == desk.white)
			ox.menus[1].insert(ox.items2[4], 6);
		if (piece == desk.black)
			ox.menus[1].insert(ox.items2[5], 6);
		return (0);
	}
	public void mouseReleased (MouseEvent e) {
		byte	row, col;
		//e.consume();
		col = (byte)(e.getX() / step);
		row = (byte)(e.getY() / step);
		if (ox.editing) {
			if (dsk.board[col][row] == piece)
				putapiece (col, row, desk.empty);
			else {
				putapiece (col, row, piece);
				moves[movnr][0] = col;
				moves[movnr][1] = row;
				movnr++;
			}
			return;
		}
		wipelila ();
		dsk.board[col][row] = piece;
		repaint();
		RepaintManager.currentManager(this).paintDirtyRegions();
		moves[movnr][0] = (byte)col;
		moves[movnr][1] = (byte)row;
		movnr++;
		piece = dsk.swabpiece (piece);
		answere ();
	}
	public void mousePressed (MouseEvent e) { }
	public void mouseExited  (MouseEvent e) { }
	public void mouseEntered (MouseEvent e) { }
	public void mouseClicked (MouseEvent e) { }

	public void putapiece (byte x, byte y, byte p) {
		if (dsk != null) {
			dsk.board[x][y] = p;
			repaint();
			RepaintManager.currentManager(this).paintDirtyRegions();
		}
	}
}
