/*
   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.
*/

#include "SetupBattle.h"

#include "Globals.h"
#include "Group.h"
#include "Stuff.h"
#include "PreBattle.h"

#include <sstream>
#include <boost/filesystem/exception.hpp>

using std::stringstream;
using std::getline;

namespace SetupBattle {
//static member
bool LoadSideMenu::imAlreadyOpen = false;

SetupBattle_State::SetupBattle_State() {
	globalSettings.randomSeed = standardRandomSeed;
	myWindows.push_back(GenWindow(50, 50, SB_PlayerList, 0, 0, WFLAG_STATIC | WFLAG_CANTCLOSE));

	int sideNum = 0;
	for (int i = 0; i != globalSettings.rememberFleets.size(); ++i) {
		if (CheckFleetExists(globalSettings.rememberFleets[i])) {
			sides.push_back(Side(globalSettings.rememberFleets[i]));
			sides[sideNum].FilesToSDStruct();
			sides[sideNum].LoadData(false);
			sideNum++;
		}
	}
	
	myWindows.push_back(GenWindow(0 , 0, SB_RandomSeed, 0, 0, WFLAG_STATIC | WFLAG_CANTCLOSE));
}

SetupBattle_State::~SetupBattle_State() {
	KillAllWindows();

	if (gsTo != GST_PreBattle)
		sides.clear();
}

void SetupBattle_State::Main() {
	DrawWorld();
}

void SetupBattle_State::MouseD(Uint8 button, Uint16 x, Uint16 y) {
	if (button == SDL_BUTTON_RIGHT)
		myWindows.push_back(GenWindow(x, y, SB_BasePU, 0, 0, 0));
}

void SetupBattle_State::Keyboard(SDL_keysym& keysym) {
	if (keysym.sym == SDLK_ESCAPE)
		gsTo = GST_MainMenu;
	else if (keysym.sym == SDLK_s) {
		if (sides.size())
			GoToBattle();
	}
}

void DrawWorld() {
	JSDL.BltFill(screenRect, 0);

	DrawAllWindows();
}

void KickFleet(int nSide) {
	vector<Side>::iterator iter = sides.begin() + nSide;

	sides.erase(iter);

	for (; iter != sides.end(); ++iter)
		iter->ChangeMySide(iter->mySide - 1);
}

void GoToBattle() {
	PreBattle::pbState = PBS_PreBattle;
	gsTo = GST_PreBattle;
}

///


BasePU::BasePU(int ix, int iy):
PopupMenu(ix, iy, none_constant, 0) {
	ClearItems();

	MenuItem tempItem;

	if (sides.size()) {
		tempItem.desc = "To battle";
		tempItem.choice = SB_ToBattle;
		AddItem(tempItem);
	}

	tempItem.desc = "Main menu";
	tempItem.choice = WC_Quit;
	AddItem(tempItem);

	InitRects();
}

bool BasePU::SwitchOnChoice(Uint16 x, Uint16 y) {
	if (currentSelection.choiceType == MCT_LeftCursor) {
		switch (currentSelection.choice) {
		case SB_ToBattle:
			GoToBattle();
			break;

		case WC_Quit:
			gsTo = GST_MainMenu;
			break;
		}
	}

	return false;
}

LoadSideMenu::LoadSideMenu(int iNSide, int iParentID):
nSide(iNSide), FileListMenu(iParentID) {
	imAlreadyOpen = true;

	MenuItem tempItem;

	tempItem.desc = "None";
	tempItem.choice = SB_Kick;
	AddItem(tempItem);

	AddBlankItem();

	AddFleets(FS_LoadSide);

	InitBorder();
}

bool LoadSideMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
	if (currentSelection.choiceType == MCT_LeftCursor) {
		switch (currentSelection.choice) {
		case SB_Kick:
			closed = true;
			if (nSide >= sides.size())
				break;

			KickFleet(nSide);
			break;

		case FS_LoadSide:
			closed = true;
			
			try {
				if (nSide < sides.size())
					sides[nSide] = Side(currentSelection.desc, nSide);
				else {
					sides.push_back(Side(currentSelection.desc));
					nSide = sides.size() - 1;
				}

				sides[nSide].FilesToSDStruct();
				sides[nSide].LoadData(false);
				//leave data lying about for whatever reason
			} catch (boost::filesystem::filesystem_error e) {
				string errorStr = e.what();
				ErrorBackToMM(errorStr);
			} catch(runtime_error e) {
				ErrorBackToMM(e.what());
			}
			break;
		}
	}

	return false;
}

PlayerList::PlayerList(int ix, int iy, int flags):
Menu_Base(ix, iy, none_constant, flags) {
	Update();
}

void PlayerList::Update() {
	ClearItems();

	MenuItem tempItem;
	tempItem.rect.h = lineGap << 2;

	tempItem.flags = MFLAG_CRECT | MFLAG_BOLD;
	for (int i = 0; i != sides.size(); ++i) {
		tempItem.desc = sides[i].name;;
		while (tempItem.desc.size() < maxNameLength)
			tempItem.desc+= ' ';

		stringstream playerInfoSS;
		playerInfoSS << '\n';

		playerInfoSS << "Commander: " << sides[i].commander << '\n';

		playerInfoSS << "Points: " << sides[i].myPoints << '\n';

		string tempStr;
		while (getline(playerInfoSS, tempStr))
			tempItem.desc+= tempStr + '\n';

		tempItem.choice = SB_SelectForce;
		tempItem.parem = i;
		AddItem(tempItem);
	}

	tempItem.flags = MFLAG_BOLD | MFLAG_CRECTWIDTH;
	for (int i = sides.size(); i != maxPlayers; ++i) {
		tempItem.desc = "Empty slot";
		while (tempItem.desc.size() < maxNameLength)
			tempItem.desc+= ' ';
		tempItem.choice = SB_SelectForce;
		tempItem.parem = i;
		AddItem(tempItem);
	}

	InitRects();
}

bool PlayerList::SwitchOnChoice(Uint16 x, Uint16 y) {
	if (currentSelection.choiceType == MCT_LeftCursor || currentSelection.choiceType == MCT_RightCursor)
		CreateLoadSideWindows(currentSelection.parem);

	return false;
}

RandomSeed::RandomSeed(int ix, int iy, int flags):
SliderWithUnits(globalSettings.screenWidth - sliderWinWidth - 100, 50, &(globalSettings.randomSeed), 0, 12345678, "Random seed", "", none_constant, flags)
{}

void CreateLoadSideWindows(int nSide) {
	if (!SetupBattle::LoadSideMenu::imAlreadyOpen) {
		myWindows.push_back(GenWindow(0, 0, WC_LargeBlankDW, "Select a side", 0, 0));
		myWindows.push_back(GenWindow(0, 0, SB_LoadSideMenu, nSide, windowIDs, 0));
	}
}

} // end namespace
