/*
   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 "Menu_Base.h"
#include "Globals.h"
#include "RTS.h"

#include <boost/filesystem/operations.hpp>

Menu_Base::Menu_Base(int ix, int iy, int iParentID, int flags):
GenWindow_Base(ix, iy, iParentID, flags), newItemx(0), newItemy(0), highlight(-1) {}

bool Menu_Base::MouseD(Uint8 button, Uint16 x, Uint16 y) {
	bool ret = GenWindow_Base::MouseD(button, x, y);
	
	if (highlight != -1) {
		if (button == SDL_BUTTON_LEFT)
			currentSelection.choiceType = MCT_LeftCursor;
		else if (button == SDL_BUTTON_RIGHT)
			currentSelection.choiceType = MCT_RightCursor;		
	}
	
	bool derivedInput = SwitchOnChoice(x, y);

	if (derivedInput == true)
		return derivedInput;
	else
		return ret;
}

bool Menu_Base::MouseM(Uint8 state, Uint16 x, Uint16 y) {
	bool ret = false;
	currentSelection.choiceType = MCT_None;
	highlight = -1;

	//cursor inside window?
	if (x >= rect.x
	    	&& y >= rect.y
	    	&& x < rect.x + rect.w
	    	&& y < rect.y + rect.h) {
		for (int i = 0; i != items.size(); ++i) {
			if (x - rect.x >= items[i].rect.x
			        && y - rect.y >= items[i].rect.y
			        && x - rect.x < items[i].rect.x + items[i].rect.w
			        && y - rect.y < items[i].rect.y + items[i].rect.h) {
				//return true even if nothing in particular is highlighted
				ret = true;
				if (items[i].choice != WC_Nothing) {
					highlight = i;

					currentSelection.desc = items[i].desc;
					currentSelection.choice = items[i].choice;
					currentSelection.parem = items[i].parem;
					
					currentSelection.choiceType = MCT_Highlight;
					return true;
				}
			}
		}
	}

	return ret;
}

void Menu_Base::DrawSelf() {
	GenWindow_Base::DrawSelf();

	if (highlight != -1) {
		SDL_Rect tempRect;
		tempRect.x = items[highlight].rect.x + rect.x;
		tempRect.y = items[highlight].rect.y + rect.y;
		tempRect.w = items[highlight].rect.w;
		tempRect.h = items[highlight].rect.h;

		JSDL.BltFill(tempRect, veryDarkGold);
	}

	for (int i = 0; i != items.size(); ++i) {
		int x = items[i].rect.x + rect.x + smallBorderSize;
		int y = items[i].rect.y + rect.y + smallBorderSize;

		if (items[i].flags & MFLAG_CRECT) {
			colorRect.x = x;
			colorRect.y = y;
			JSDL.BltFill(colorRect, sides[items[i].parem].color);
		}

		if (items[i].flags & MFLAG_CRECT || items[i].flags & MFLAG_CRECTWIDTH)
			x+= colorRect.w + (smallBorderSize << 1);

		if (items[i].flags & MFLAG_BOLD) {
			int endOfTitle = items[i].desc.find('\n');
			string tempStr = items[i].desc.substr(0, endOfTitle - 1);
			boldFonts.BlitString(x, y, 0, tempStr);

			if (endOfTitle != string::npos) {
				tempStr = items[i].desc.substr(endOfTitle, string::npos);
				normalFonts.BlitString(x, y, 0, tempStr);
			}
		} else if (items[i].flags & MFLAG_FADED)
			normalFonts.BlitString(x, y, 1, items[i].desc);
		else
			normalFonts.BlitString(x, y, 0, items[i].desc);
	}
}

void Menu_Base::InitRects() {
	//width
	int longestIndex = 0;
	int longest = 0;
	rect.h = 0;

	for (int i = 0; i != items.size(); ++i) {
		int currentLength = 0;

		if (items[i].flags & MFLAG_CRECT || items[i].flags & MFLAG_CRECTWIDTH)
			currentLength+= colorRect.w + (smallBorderSize << 1);

		for (int j = 0; j != items[i].desc.size(); ++j) {
			if (items[i].desc[j] != '\n')
				++currentLength;
			else {
				if (currentLength > longest) {
					longestIndex = i;
					longest = currentLength;
				}

				currentLength = 0;
			}
		}

		if (currentLength > longest)
			longest = currentLength;

		rect.h+= items[i].rect.h;
	}

	int tempLetterWidth;
	if (items[longestIndex].flags & MFLAG_BOLD)
		tempLetterWidth = boldLetterWidth;
	else
		tempLetterWidth = normalLetterWidth;

	int menuWidth = (longest + 1) * tempLetterWidth;

	for (int i = 0; i != items.size(); ++i)
		items[i].rect.w = menuWidth;

	//overall dimensions
	rect.w = menuWidth;

	//orientation
	if (rect.x > globalSettings.screenWidth * 3 /4)
		rect.x-= menuWidth;

	if (rect.y > globalSettings.screenHeight >> 1)
		rect.y-= items.size() * lineGap;

	InitBorder();
}

void Menu_Base::AddItem(MenuItem& tempItem) {
	tempItem.rect.x = newItemx;
	tempItem.rect.y = newItemy;
	items.push_back(tempItem);

	newItemy += tempItem.rect.h;
}

void Menu_Base::AddBlankItem() {
	MenuItem tempItem;
	tempItem.choice = WC_Nothing;
	AddItem(tempItem);
}

///

FileListMenu::FileListMenu(int iParentID):
Menu_Base(0, 0, iParentID, 0) {
	rect.w = 600;
	rect.h = lineGap * 20;

	CentreWindow();

	rect.y+= lineGap;
}

FileListMenu::~FileListMenu() {
	MessageWindows(WC_YouClose, 0, 0, parentID, myID);
}

void FileListMenu::AddDirectory(const string& directory, const string& findExtension, WindowChoice itemChoice) {
	namespace fs = boost::filesystem;

	MenuItem tempItem;

	fs::directory_iterator directoryEnd; // default construction yields past-the-end
	for (fs::directory_iterator iter(directory); iter != directoryEnd; ++iter) {
		string filename = iter->leaf();

		if (filename.find('.') == filename.npos)
			continue;

		string fileExtension = filename.substr(filename.find('.'), filename.size() -1);

		if (fileExtension != findExtension)
			continue;

		filename = filename.substr(0, filename.find('.'));

		tempItem.desc = filename;
		tempItem.choice = itemChoice;
		AddItem(tempItem);

		if (rect.y + newItemy + tempItem.rect.h > rect.y + rect.h) {
			newItemy = 0;
			newItemx += menuItemWidth;
		}
	}
}

void FileListMenu::AddFleets(WindowChoice itemChoice) {
	namespace fs = boost::filesystem;

	MenuItem tempItem;

	fs::directory_iterator directoryEnd; // default construction yields past-the-end
	for (fs::directory_iterator iter(globalSettings.bdp + "fleets/"); iter != directoryEnd; ++iter) {
		if (fs::is_directory(*iter)) {
			string fleetName = iter->leaf();

			if (CheckFleetExists(fleetName)) {
				tempItem.desc = fleetName;
				tempItem.choice = itemChoice;
				AddItem(tempItem);

				if (rect.y + newItemy + tempItem.rect.h > rect.y + rect.h) {
					newItemy = 0;
					newItemx += menuItemWidth;
				}
			}
		}	
	}
}

void FileListMenu::AddFleetFiles(int whichSide, const string& findExtension, WindowChoice itemChoice) {
	namespace fs = boost::filesystem;

	MenuItem tempItem;

	fs::path iterPath(GetFleetDir(whichSide));
	fs::directory_iterator directoryEnd; // default construction yields past-the-end
	for (fs::directory_iterator iter(iterPath); iter != directoryEnd; ++iter) {
		string filename = iter->leaf();

		if (filename.find('.') == filename.npos)
			continue;
			
		string beforeDot = filename.substr(0, filename.find('.'));
		
		//it's the main side data file, ignore
		if (beforeDot == sides[whichSide].name)
			continue;
			
		string fileExtension = filename.substr(filename.find('.'));

		if (fileExtension != findExtension)
			continue;		

		tempItem.desc = beforeDot;
		tempItem.choice = itemChoice;
		AddItem(tempItem);

		if (rect.y + newItemy + tempItem.rect.h > rect.y + rect.h) {
			newItemy = 0;
			newItemx += menuItemWidth;
		}
	}
}

DeleteBox::DeleteBox(const string& iFilename, const string& iDirectory, int iParentID):
Menu_Base(0, 0, iParentID, 0), filename(iFilename), directory(iDirectory) {
	MenuItem tempItem;

	tempItem.desc = "Are you sure you wish to delete this file?";
	tempItem.choice = WC_Nothing;
	AddItem(tempItem);

	tempItem.desc = "Yes";
	tempItem.choice = WC_Yes;
	AddItem(tempItem);

	tempItem.desc = "No";
	tempItem.choice = WC_No;
	AddItem(tempItem);

	InitRects();
	CentreWindow();
}

bool DeleteBox::SwitchOnChoice(Uint16 x, Uint16 y) {
	if (currentSelection.choiceType == MCT_LeftCursor) {
		switch (currentSelection.choice) {
		case WC_Yes: {
			namespace fs = boost::filesystem;
			fs::path tempPath(directory + filename + ".dat");

			fs::remove(tempPath);
			MessageWindows(WC_ExpensiveUpdate, 0, 0, parentID, myID);
			closed = true;
			}
			break;

		case WC_No:
			closed = true;
			break;
		}
	}

	return false;
}


