//////////////////////////////////////////////////////////////////////////////
//
//  This file is part of the Atari graphical interface for GNU Chess,
//  and is Copyright 1992 by Warwick W. Allison.
//
//  You are free to copy and modify these sources, provided you acknowledge
//  the origin by retaining this notice, and adhere to the conditions
//  of the CHESS General Public License described in the main chess file
//  gnuchess.cc.
//
//////////////////////////////////////////////////////////////////////////////

#include <string.h>
#include <stdio.h>
#include "Buttons.h"
#include "Help.h"

GameButton **Button;
int MaxNumButtons=20;
int NumButtons;
int MyLevel=1;
const int TopButtonX=0;
const int TopButtonY=5;

static char* const IncTextTemplate="Up level (now %d)";
static char* const DecTextTemplate="Down level (now %d)";
static char IncText[25];
static char DecText[25];

Sprite *Indicator;
static int LevX,LevY;

DrawIndicator()
{
	Indicator->MoveTo(LevX+MyLevel*3,LevY);
	Indicator->Draw();
	Pages->Flop();
	Indicator->Draw();
	Pages->Flop();

	sprintf(IncText,IncTextTemplate,MyLevel);
	sprintf(DecText,DecTextTemplate,MyLevel);
	NoteHelpChanged(IncText);
	NoteHelpChanged(DecText);
}

class LevelButton : public GameButton
{
public:
	LevelButton(Sprite* S,int i,int x,int y,int w,int h,char *commandstr,char *HelpText,int Inc);
	virtual char* const Push();
	virtual void Release();

private:
	int inc;
};

LevelButton::LevelButton(Sprite* S,int i,int x,int y,int w,int h,char *commandstr,char *HelpText,int Inc) :
	GameButton(S,i,x,y,w,h,commandstr,HelpText),
	inc(Inc)
{ }

void InitButtons(Screen& Sc)
{
	ColourIncarnation* Pointer=new ColourIncarnation(4);
	Pointer->GetImage(Sc,304,166);
	Indicator=new Sprite(Pointer);

	Incarnation **P=new Incarnation*[2];
	P[0]=new WideColourIncarnation(15);
	P[1]=new ColourIncarnation(15);

	P[0]->GetImage(Sc,288,185);
	P[1]->GetImage(Sc,288,155);

	Sprite *S=new Sprite(P,2);

	Button=new GameButton*[MaxNumButtons];
	int b=0;
	int w=32;
	int h=15;
	int x=TopButtonX;
	int y=TopButtonY-h;

	// First column
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"quit","Quit GNUchess");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"new","New game");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"help","Information");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"edit","Edit board");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"book","Disable openings book");

	Button[b++]=new LevelButton(S,1,x,y+=h,w/2,h,"level",DecText,-1);
	Button[b++]=new LevelButton(S,1,x+w/2,y,w/2,h,"level",IncText,+1);
	LevX=x-3;
	LevY=y+15-4;

	// Second column
	y=TopButtonY-h;
	x+=w;
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"get","Load game");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"save","Save game");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"savecnf","Save configuration");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"list","List game to CHESS.LST");
	y+=h;// modem
	y+=h;// humans

	// Third column
	y=TopButtonY-h;
	x+=w;
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"both","Start CPU duel");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"remove","Back two moves");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"reverse","Reverse board");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"hint","Hint");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"switch","Advance (Swap sides)");
	Button[b++]=new GameButton(S,0,x,y+=h,w,h,"undo","Undo move");

	NumButtons=b;

	DrawIndicator();
}

static GameButton* Pushed;

void ReleaseButton()
{
	if (Pushed) {
		Pushed->Release();
		Pushed=0;
	}
}

GameButton::GameButton(Sprite* S,int i,int x,int y,int w,int h,char *commandstr,char *HelpText)
	: X(x), Y(y), W(w), H(h), cmdstr(commandstr), Pusher(S), I(i)
{
	AddHelp(x,y,w,h,HelpText);
}

void GameButton::Release()
{
	Pusher->Wipe();
	Pages->Flop();
	Pusher->Wipe();
	Pages->Flop();
}

char* const GameButton::Push()
{
	ReleaseButton();
	Pushed=this;
	Pusher->ShapeTo(I);
	Pusher->MoveTo(X,Y);
	Pusher->Draw();
	Pages->Flop();
	Pusher->Draw();
	Pages->Flop();
	return cmdstr;
}

char* const LevelButton::Push()
{
	MyLevel+=inc;
	if (MyLevel<1) {
		MyLevel=1;
		return " ";
	} else if (MyLevel>10) {
		MyLevel=10;
		return " ";
	}

	Indicator->Wipe();
	Pages->Flop();
	Indicator->Wipe();
	Pages->Flop();

	char* const result=GameButton::Push();

	DrawIndicator();
	return result;
}

void LevelButton::Release()
{
	Indicator->Wipe();
	Pages->Flop();
	Indicator->Wipe();
	Pages->Flop();

	GameButton::Release();

	DrawIndicator();
}

bool PressButton(int x, int y, char *cmd)
{
	for (int b=0; b<NumButtons; b++) {
		if (Button[b]->Contains(x,y)) {
			strcpy(cmd,Button[b]->Push());
			return TRUE;
		}
	}
	return FALSE;
}
