/*
   Copyright (C) 2004 by James Gregory
   Part of the GalaxyHack project
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.
 
   See the COPYING file for more details.
*/

#ifndef GUARD_ForceSelect
#define GUARD_ForceSelect

#include "Globals.h"
#include "GameState.h"
#include "DragWindow.h"
#include "Menu_Base.h"

#include <string>

#include <boost/filesystem/path.hpp>

using std::string;

namespace ForceSelect {
class ForceSelect_State: public GameState {
public:
	ForceSelect_State();
	~ForceSelect_State();
	void Main();
	
	void MouseD(Uint8 button, Uint16 x, Uint16 y);
	void Keyboard(SDL_keysym& keysym);
};

void ToStageTwo();

void DrawWorld();

void LoadSide(string& iName, bool newSide);
void SideToFile();

void CreateNewGroupWins(const string& iName, UnitType iType, bool newFlag);
void AddGroups(const string& iName, UnitType iType, int number, CapShipType csType, int parentCaSh);
void UnitToFile(int nGroup);
void AllUnitsToFile();
void CreateNewSideDirs();
void CreatePictureDirs(const string& baseDir);

void DeleteGroupCheck(int nGroup);
void DeleteGroup(int nGroup);

int WhichGSharesName(int nGroup);
bool UnitNameSharedQ(int& currentGroup, int changedGroup, int addOrDelete);

bool UnitGTOrEqual(UnitType typeOne, const string& nameOne, UnitType typeTwo, const string& nameTwo);
bool NameGTOrEqual(const string& nameOne, const string& nameTwo);

void ChangeUnitPic(const string& unitName, const string& newPic);
void ChangeUnitSmallWeapons(const string& unitName, const string& newType);
void ChangeUnitBigWeapons(const string& unitName, const string& newType);
void ChangeUnitEngine(const string& unitName, const string& newStat);
void ChangeUnitArmour(const string& unitName, const string& newStat);
void ChangeUnitShield(const string& unitName, const string& newStat);
void ChangeUnitEquipment(const string& unitName, const string& newStat);
void ChangeUnitAI(const string& unitName, const string& newStat);
void ChangeUnitCSType(const string& unitName, CapShipType newStat);

void ChangeGroupParentCaSh(int nGroup, int newParent);

//1 is add, 0 is delete
void GroupAddDelInform(int groupNumber, int howMany);

void TrySaveAndExit();

///

class LoadSideDW: public LargeBlankDW {
public:
	LoadSideDW();
	~LoadSideDW();
};

class LoadSideSM: public FileListMenu {
public:
	LoadSideSM(int iParentID);

	void ExpensiveUpdate();
	bool SwitchOnChoice(Uint16 x, Uint16 y);
};

class LoadSidePU: public PopupMenu {
public:
	LoadSidePU(int ix, int iy, const string& iSideName, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

private:
	string sideName;
};

class DeleteFleet: public Menu_Base {
public:
	DeleteFleet(const string& iSideName, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

private:
	string sideName;
};

class CopyFleet: public StringInputBox {
public:
	CopyFleet(const string& iSideName, int iParentID);
	bool Keyboard(SDL_keysym& keysym);
	
private:
	void DoCopy(boost::filesystem::path sourcePath, boost::filesystem::path destPath);

private:
	string sideName;
};

class NewSideName: public StringInputBox {
public:
	NewSideName();

	bool Keyboard(SDL_keysym& keysym);
};

class ChangeCommanderName: public StringInputBox {
public:
	ChangeCommanderName();

	bool Keyboard(SDL_keysym& keysym);
};

///

class BasePU: public PopupMenu {
public:
	BasePU(int ix, int iy);
	bool SwitchOnChoice(Uint16 x, Uint16 y);
};

///

class SideOptions: public DragWindow {
public:
	SideOptions(int ix, int iy, int flags);

	bool MouseD(Uint8 button, Uint16 x, Uint16 y);
	void DrawSelf();
};

class SideOptionsPU: public PopupMenu {
public:
	SideOptionsPU(int ix, int iy);
	bool SwitchOnChoice(Uint16 x, Uint16 y);
};


class AddGroupMenu: public FileListMenu {
public:
	AddGroupMenu(int iParentID);

	void ExpensiveUpdate();
	bool SwitchOnChoice(Uint16 x, Uint16 y);
};

class AddGroupPU: public PopupMenu {
public:
	AddGroupPU(int ix, int iy, const string& iUnitName, int iParentID);

	bool SwitchOnChoice(Uint16 x, Uint16 y);

private:
	string unitName;
};

class NewGroupChoicesOK: public Menu_Base {
public:
	NewGroupChoicesOK(int ix, int iy, const string& iName, UnitType iMyType, int iIDOne, int iIDTwo, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

	string name;
	UnitType myType;
	int sliderOneID;
	int sliderTwoID;
};

class CapShipTypeSlider: public Slider {
public:
	CapShipTypeSlider(int ix, int iy, int iParentID, int flags);

	void DrawSelf();
};

class NewGroupParentPU: public SidePU {
public:
	NewGroupParentPU(const string& iName, UnitType iType, int iNumber);

	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	string name;
	UnitType myType;
	int number;
};

class NewUnitName: public StringInputBox {
public:
	NewUnitName(UnitType iUnitType, int iParentID);

	bool Keyboard(SDL_keysym& keysym);

protected:
	UnitType unitType;
};

class EditGroup: public DragWindow {
public:
	EditGroup(int ix, int iy, int iMyGroup, int flags);

	bool MouseD(Uint8 button, Uint16 x, Uint16 y);
	void DrawSelf();

	void WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID);

protected:
	int myGroup;
};

class EditGroupPU: public PopupMenu {
public:
	EditGroupPU(int ix, int iy, int iMyGroup);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	int myGroup;
};

class SetAIScriptMenu: public FileListMenu {
public:
	SetAIScriptMenu(int iMyGroup, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

	void WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID);

protected:
	int myGroup;
};

class SetAIScriptPU: public Menu_Base {
public:
	SetAIScriptPU(const string& iNewScript, int iMyGroup, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

	void WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID);

protected:
	int myGroup;
	const string newScript;
};

class EditUnit: public DragWindow {
public:
	EditUnit(int ix, int iy, int iMyGroup);

	bool MouseD(Uint8 button, Uint16 x, Uint16 y);
	void DrawSelf();

	void WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID);

protected:
	int myGroup;
	UnitType myType;
};

class EditUnitPU: public PopupMenu {
public:
	EditUnitPU(int ix, int iy, int iMyGroup);

	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	int myGroup;
};

///

class SetUnitPicMenu: public FileListMenu {
public:
	SetUnitPicMenu(int iMyGroup, int iParentID);

	bool SwitchOnChoice(Uint16 x, Uint16 y);
	bool MouseM(Uint8 state, Uint16 x, Uint16 y);

	void WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID);

protected:
	int myGroup;
	int previewWinID;
};

class WeapEquipMenu_Base: public Menu_Base {
public:
	WeapEquipMenu_Base(int ix, int iy, int iMyGroup, int iParentID);
	virtual ~WeapEquipMenu_Base();

	void InitEquipMenu(WindowChoice first, WindowChoice last);
	bool SharedSwitchOnChoice(void (*ChangeUnitFunction)(const string&, const string&));
	bool MouseM(Uint8 state, Uint16 x, Uint16 y);

	void WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID);

protected:
	int myGroup;
};

class WeaponsDW: public DragWindow {
public:
	WeaponsDW(int ix, int iy, int iMyGroup, int bBig);

	void DrawSelf();

	void WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID);

protected:
	WeaponType weaponChoice;
};

class SmallWeaponsMenu: public WeapEquipMenu_Base {
public:
	SmallWeaponsMenu(int ix, int iy, int iMyGroup, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	UnitType myType;
};

class BigWeaponsMenu: public WeapEquipMenu_Base {
public:
	BigWeaponsMenu(int ix, int iy, int iMyGroup, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	UnitType myType;
};

class EquipmentDW: public DragWindow {
public:
	EquipmentDW(int ix, int iy, int iMyGroup, int equipType);

	void DrawSelf();
	void WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID);

protected:
	string equipChoice;
};

class EngineMenu: public WeapEquipMenu_Base {
public:
	EngineMenu(int ix, int iy, int iMyGroup, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	EquipCat equipCat;
};

class ArmourMenu: public WeapEquipMenu_Base {
public:
	ArmourMenu(int ix, int iy, int iMyGroup, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	EquipCat equipCat;
};

class ShieldMenu: public WeapEquipMenu_Base {
public:
	ShieldMenu(int ix, int iy, int iMyGroup, int iParentID);
	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	EquipCat equipCat;
};

class CSTypeMenu: public Menu_Base {
public:
	CSTypeMenu(int ix, int iy, int iMyGroup);

	bool SwitchOnChoice(Uint16 x, Uint16 y);

protected:
	int myGroup;
};


//

class ExitNoSaveQ: public Menu_Base {
public:
	ExitNoSaveQ();
	bool SwitchOnChoice(Uint16 x, Uint16 y);
};

class ForceExitQ: public Menu_Base {
public:
	ForceExitQ(const string& error);
	bool SwitchOnChoice(Uint16 x, Uint16 y);
};

class WhichSaveGroup: public PopupMenu {
public:
	WhichSaveGroup(int iMyGroup, bool globalVar);
	bool SwitchOnChoice(Uint16 x, Uint16 y);
	
private:
	int myGroup;
};

} // end namespace

#endif

