import SliderTile;
import java.awt.*;
import java.util.Random;

final class SliderBox extends Canvas 
{
	Slider game;
	SliderTile tile[];
	int width, height, bevel;
	int tilecolor, boardcolor, shimcolor;
	int selected;
	Point anchor;
	Random rand;
	boolean justdown;


	SliderBox(Slider applet) {
		game = applet;
		tilecolor = game.m_tilecolor;
		boardcolor = game.m_boardcolor;
		shimcolor = game.m_shimcolor;
		setBackground(new Color(shimcolor));
		rand = new Random();
		reset();
	}

	void reset() {
		width = 4; height = 5; bevel = 1;
		tile = new SliderTile[10];
		tile[0] = new SliderTile(this,1,0,3,2);	//  222000000333
		tile[1] = new SliderTile(this,1,2,3,3);	//  222000000333
		tile[2] = new SliderTile(this,0,0,1,2);	//  222000000333
		tile[3] = new SliderTile(this,3,0,4,2);	//  222000000333
		tile[4] = new SliderTile(this,0,3,1,5);	//     111111
		tile[5] = new SliderTile(this,3,3,4,5);	//     111111
		tile[6] = new SliderTile(this,1,3,2,4);	//  444666777555
		tile[7] = new SliderTile(this,2,3,3,4);	//  444666777555
		tile[8] = new SliderTile(this,1,4,2,5);	//  444888999555
		tile[9] = new SliderTile(this,2,4,3,5);	//  444888999555
		selected = -1;
	}

	void rescale(int newwidth, int newheight) {
		int oldx = width/4;
		int oldy = height/5;
		int newx = newwidth/4;
		int newy = newheight/5;
		for (int i = 0; i < 10; i++) {
			tile[i].rescale(oldx,oldy,newx,newy);
		}
		width = newwidth;
		height = newheight;
		bevel = newx;
		if (bevel > newy) bevel = newy;
		bevel = bevel/16+1;
	}

	public void paint(Graphics g) {
		if(width!=size().width || height!=size().height) {
			rescale(size().width,size().height);
		}
		g.setColor(new Color(shimcolor));
		g.fillRect(0,0,width,height);
		g.setColor(new Color(boardcolor));
		g.fillRect(0,0,width/4*4,height/5*5);
		for (int i = 0; i < 10; i++) {
			tile[i].paint(g);
//			g.setColor(Color.black);
//			g.drawString(""+i,tile[i].left+5,tile[i].bottom-5);
		}
	}

	Image offScrImg;			// double buffering
	int i_width = 0, i_height = 0;
	public void update( Graphics g ) {
		if(i_width!=size().width || i_height!=size().height) {
			i_width = size().width;
			i_height = size().height;
			offScrImg = createImage(i_width, i_height);
		}
		Graphics og = offScrImg.getGraphics();
		paint( og );
		g.drawImage(offScrImg, 0, 0, null);
		og.dispose();
	}

	public boolean mouseDown(Event evt, int x, int y) {
		if (game.solving) return true;
		justdown = true;
		for (int i = 0; i < 10; i++) {
			if ( tile[i].contains(x,y) ) {
				selected = i;
				anchor = new Point(x,y);
				return true;
			}
		}
		selected = -1;
		return true;
	}

	public boolean mouseUp(Event evt, int x, int y) {
		selected = -1;
		if (justdown) {
			justdown = false;
		}
		return true;
	}

	public boolean mouseDrag(Event evt, int x, int y) {
		if (selected < 0) return true;
		int dx=0, dy=0;
		boolean moved = false;
		if (x < anchor.x)
			dx = tile[selected].moveleft(x-anchor.x, tile);
		else if (x > anchor.x)
			dx = tile[selected].moveright(x-anchor.x, width/4*4, tile);
		if (dx!=0) {
			anchor.x += dx;
			if (selected==0 && tile[0].bottom==height/5*5
				&& tile[0].left==width/4 && !game.solved)
				game.bigwinner = true; //!!!
				//(I don't think bigwinner is possible on a down move
			moved = true;
		}
		if (y < anchor.y)
			dy = tile[selected].moveup(y-anchor.y, tile);
		else if (y > anchor.y) {
			dy = tile[selected].movedown(y-anchor.y, height/5*5, tile);
			if (selected==0 && dy!=0 && tile[0].bottom==height/5*5
				&& !game.solved) game.winner = true; //!!
		}
		if (dy!=0) {
			moved = true;
			anchor.y += dy;
		}
		if (moved) {
			if (justdown) {
				game.addmove();
				justdown = false;
			}
			repaint();
		}
		return true;
	}

	void movetile(int t, int direction, int fraction, boolean last) {
		int distance;
		switch (direction) {
		case 0:
			distance = height/5/fraction;
			if (last) distance = height/5 - (fraction-1)*distance;
			tile[t].top -= distance;
			tile[t].bottom -= distance;
			break;
		case 1:
			distance = width/4/fraction;
			if (last) distance = width/4 - (fraction-1)*distance;
			tile[t].left += distance;
			tile[t].right += distance;
			break;
		case 2:
			distance = height/5/fraction;
			if (last) distance = height/5 - (fraction-1)*distance;
			tile[t].top += distance;
			tile[t].bottom += distance;
			break;
		case 3:
			distance = width/4/fraction;
			if (last) distance = width/4 - (fraction-1)*distance;
			tile[t].left -= distance;
			tile[t].right -= distance;
			break;
		}
	}

	int randomColor() {
		return rand.nextInt()&0xfffff;
	}

}


