/*
   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 "RTS.h"

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

namespace RTS {

SideInfo::SideInfo(int ix, int iy, int iMySide, int flags):
DragWindow(ix, iy, none_constant, flags), mySide(iMySide) {
	borderColor = sides[mySide].color;
}

bool SideInfo::MouseD(Uint8 button, Uint16 x, Uint16 y) {
	bool ret = DragWindow::MouseD(button, x, y);

	if (ret == true && button == SDL_BUTTON_RIGHT)
		myWindows.push_back(GenWindow(x, y, RTS_InfoChoicePU, myID, 0, 0));

	return ret;
}

void SideInfo::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
	GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
	if (targetID == all_constant || targetID == myID) {
		switch (theMessage) {
		case RTS_SideStats:
		case RTS_SideVars:
		case RTS_SideSaveGroups:
		case RTS_SideAIDebug:
			myWindows.push_back(GenWindow(rect.x, rect.y, theMessage, mySide, 0, 0));
			closed = true;
			break;
		}
	}
}

SideStatsInfo::SideStatsInfo(int ix, int iy, int iMySide):
SideInfo(ix, iy, iMySide, 0) {
	rect.w = 210;
	rect.h = 130;

	InitRects();
}

void SideStatsInfo::DrawSelf() {
	theText.clear();

	AddSideTitle(mySide);

	char output[32];
	WindowText outputStr = "Commander: " + sides[mySide].commander;
	theText.push_back(outputStr);

	int numberLeft = sides[mySide].GetTotalCapShips();
	if (numberLeft)
		sprintf(output, "Capital ships left: %d", numberLeft);
	else
		sprintf(output, "Capital ships left: none");
	theText.push_back(WindowText(output));

	numberLeft = sides[mySide].GetTotalUnits();
	if (numberLeft)
		sprintf(output, "Units left: %d", numberLeft);
	else
		sprintf(output, "Units left: none");
	theText.push_back(WindowText(output));

	if (numberLeft)
		sprintf(output, "Total health left: %d", sides[mySide].GetTotalHealth());
	else
		sprintf(output, "Total health left: 0");
	theText.push_back(WindowText(output));

	DragWindow::DrawSelf();
}

////

GroupInfo::GroupInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
DragWindow(ix, iy, none_constant, flags), mySide(iMySide), myGroup(iMyGroup) {
	borderColor = sides[mySide].color;
}

bool GroupInfo::MouseD(Uint8 button, Uint16 x, Uint16 y) {
	bool ret = DragWindow::MouseD(button, x, y);

	if (ret == true && button == SDL_BUTTON_RIGHT)
		myWindows.push_back(GenWindow(x, y, RTS_InfoChoicePU, myID, 1, 0));

	return ret;
}

void GroupInfo::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
	GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);

	if (targetID == all_constant || targetID == myID) {
		switch (theMessage) {
		case RTS_GroupStats:
		case RTS_GroupShieldsInfo:
		case RTS_GroupStatusReport:
		case RTS_GroupAIReport:
		case RTS_GroupVars:
		case RTS_GroupSaveGroups:
		case RTS_GroupTimers:
			myWindows.push_back(GenWindow(rect.x, rect.y, theMessage, mySide, myGroup, 0));
			closed = true;
			break;
		}
	}
}

GroupStatsInfo::GroupStatsInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
	rect.w = 310;
	rect.h = 200;

	InitRects();
}

void GroupStatsInfo::DrawSelf() {
	theText.clear();

	char output[48];

	AddGroupTitle(mySide, myGroup);

	theText.push_back(WindowText(sides[mySide].groups[myGroup].GetUnitName()));

	int numberLeft = sides[mySide].groups[myGroup].GetUnitsLeft();
	string asterisks;
	if (numberLeft)
		asterisks.insert(asterisks.end(), numberLeft, '*');
	else
		asterisks = "Destroyed";

	int health = sides[mySide].groups[myGroup].GetHealth();
	if (health > 0) {
		sprintf(output, "Total health: %d", health);
		theText.push_back(WindowText(output));
	}

	string outputStr = "Engine: " + sides[mySide].groups[myGroup].GetEngineName();
	theText.push_back(WindowText(outputStr));

	outputStr = "Shield: " + sides[mySide].groups[myGroup].GetShieldName();
	theText.push_back(WindowText(outputStr));

	outputStr = "Armour: " + sides[mySide].groups[myGroup].GetArmourName();
	theText.push_back(WindowText(outputStr));

	if (sides[mySide].groups[myGroup].GetType() != UT_SmShUnit) {
		sprintf(output, "Small weapon: %s * %d", weaponLookup[sides[mySide].groups[myGroup].GetSmallType()].name.c_str(), sides[mySide].groups[myGroup].GetSmallNumber());
		theText.push_back(WindowText(output));
	} else {
		outputStr = "Small weapon: " + weaponLookup[sides[mySide].groups[myGroup].GetSmallType()].name;
		theText.push_back(WindowText(outputStr));
	}

	if (sides[mySide].groups[myGroup].GetType() == UT_SmShUnit) {
		sprintf(output, "Big weapon: %s * %d", weaponLookup[sides[mySide].groups[myGroup].GetBigType()].name.c_str(), sides[mySide].groups[myGroup].GetBigAmmo());
		theText.push_back(WindowText(output));
	} else {
		outputStr = "Big weapon: " + weaponLookup[sides[mySide].groups[myGroup].GetBigType()].name;
		theText.push_back(WindowText(outputStr));
	}

	DragWindow::DrawSelf();
}

GroupShieldsInfo::GroupShieldsInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
	rect.w = 250;
	rect.h = 150;

	InitRects();
}

void GroupShieldsInfo::DrawSelf() {
	theText.clear();

	char output[48];

	AddGroupTitle(mySide, myGroup);

	theText.push_back(WindowText("Shields (recharge) - Armour"));

	int shieldC, shieldM, shieldR, armourC, armourM;

	for (int i = 0; i != sides[mySide].groups[myGroup].GetUnitsLeft(); ++i) {
		sides[mySide].groups[myGroup].GetShAndAr(shieldC, shieldM, shieldR, armourC, armourM, i);
		sprintf(output, "Unit %d: %d/%d (%d) - %d/%d", i+1, shieldC, shieldM, shieldR, armourC, armourM);
		theText.push_back(WindowText(output));

	}

	DragWindow::DrawSelf();
}

GroupStatusReport::GroupStatusReport(int ix, int iy, int iMySide, int iMyGroup, int flags):
GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
	rect.w = 300;
	rect.h = 220;

	InitRects();
}

void GroupStatusReport::DrawSelf() {
	theText.clear();
	const AICommands* pCommands = sides[mySide].groups[myGroup].GetTheCommands();
	char output[32];

	AddGroupTitle(mySide, myGroup);

	CoordsInt center = sides[mySide].groups[myGroup].GetCenter();
	sprintf(output, "Position: %d, %d", center.x, center.y);
	theText.push_back(WindowText(output));
	
	CoordsFloat speeds = sides[mySide].groups[myGroup].GetSpeeds();

	sprintf(output, "Speed x: %.2f", speeds.x);
	theText.push_back(WindowText(output));

	sprintf(output, "Speed y: %.2f", speeds.y);
	theText.push_back(WindowText(output));

	theText.push_back(WindowText(""));

	theText.push_back(WindowText(MoveComToString(*pCommands)));

	if (pCommands->moveCommand != MC_NoMove) {
		sprintf(output, "Distance: %d", pCommands->moveTargetDist);
		theText.push_back(WindowText(output));
	} else
		theText.push_back(WindowText("Distance: N/A"));

	theText.push_back(WindowText(""));

	theText.push_back(WindowText(FireComToString(*pCommands)));

	if (pCommands->bFire) {
		sprintf(output, "Distance: %d", pCommands->fireTargetDist);
		theText.push_back(WindowText(output));
	} else
		theText.push_back(WindowText("Distance: N/A"));

	DragWindow::DrawSelf();
}

GroupAIReport::GroupAIReport(int ix, int iy, int iMySide, int iMyGroup, int flags):
GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
	rect.w = 300;
	rect.h = 270;
	
	//it works without this but relying on uninitialised memory to be different to memset to 0 memory is rather dodge, so we have it
	const AICommands* pCommands = sides[mySide].groups[myGroup].GetTheCommands();
	string tempStr = MoveComToString(*pCommands) + '\n' + FireComToString(*pCommands);
	reports.push_back(tempStr);
	oldCommands = *pCommands;

	InitRects();
}

void GroupAIReport::DrawSelf() {
	const AICommands* pCommands = sides[mySide].groups[myGroup].GetTheCommands();
	
	theText.clear();
	AddGroupTitle(mySide, myGroup);
	
	//remove blank line
	theText.erase(theText.end() - 1);
	
	string tempStr = "AI script: " + sides[mySide].groups[myGroup].GetAIFilename();
	theText.push_back(WindowText(tempStr));	
	theText.push_back(WindowText(""));
	
	if (
	pCommands->bFire != oldCommands.bFire ||
	pCommands->fireTarget != oldCommands.fireTarget ||
	pCommands->moveCommand != oldCommands.moveCommand ||
	pCommands->bInverse != oldCommands.bInverse ||
	pCommands->moveTarget != oldCommands.moveTarget) {
		tempStr = MoveComToString(*pCommands) + '\n' + FireComToString(*pCommands);
		reports.push_back(tempStr);
		oldCommands = *pCommands;
		
		if (reports.size() > maxMessageVectorSize)
			reports.erase(reports.begin());
	}

	for (list<string>::const_iterator iter = reports.begin(); iter != reports.end(); ++iter) {
		theText.push_back(WindowText(*iter));
		//each string has a newline
		theText.push_back(WindowText(""));
	}

	DragWindow::DrawSelf();
}

InfoChoicePU::InfoChoicePU(int ix, int iy, int iInfoWinID, int groupOptions):
PopupMenu(ix, iy, iInfoWinID, 0), createNew(false) {
	MenuItem tempItem;
	if (groupOptions)
		AddGroupOptions(tempItem);
	else
		AddSideOptions(tempItem);
	InitRects();
}

InfoChoicePU::InfoChoicePU(int ix, int iy, int iMySide, int iMyGroup, int groupOptions, int iParentID):
PopupMenu(ix, iy, iParentID, 0), mySide(iMySide), myGroup(iMyGroup), createNew(true) {
	MenuItem tempItem;

	if (groupOptions) {
		tempItem.desc = "Side info:";
		tempItem.choice = WC_Nothing;
		AddItem(tempItem);
		AddBlankItem();
	}

	AddSideOptions(tempItem);

	if (groupOptions) {
		AddBlankItem();
		tempItem.desc = "Group info:";
		tempItem.choice = WC_Nothing;
		AddItem(tempItem);
		AddBlankItem();
		AddGroupOptions(tempItem);

		AddBlankItem();
		tempItem.desc = "Cycle group information (F4)";
		tempItem.choice = RTS_CycleGroupInfo;
		AddItem(tempItem);
	}
	
	InitRects();
}

void InfoChoicePU::AddSideOptions(MenuItem& tempItem) {
	tempItem.desc = "Stats";
	tempItem.choice = RTS_SideStats;
	AddItem(tempItem);

	tempItem.desc = "Global script variables";
	tempItem.choice = RTS_SideVars;
	AddItem(tempItem);

	tempItem.desc = "Global script saved groups";
	tempItem.choice = RTS_SideSaveGroups;
	AddItem(tempItem);
	
	tempItem.desc = "AI error messages";
	tempItem.choice = RTS_SideAIDebug;
	AddItem(tempItem);
}

void InfoChoicePU::AddGroupOptions(MenuItem& tempItem) {
	tempItem.desc = "Stats";
	tempItem.choice = RTS_GroupStats;
	AddItem(tempItem);

	tempItem.desc = "Shields/Armour";
	tempItem.choice = RTS_GroupShieldsInfo;
	AddItem(tempItem);

	tempItem.desc = "Status report";
	tempItem.choice = RTS_GroupStatusReport;
	AddItem(tempItem);

	tempItem.desc = "AI Report";
	tempItem.choice = RTS_GroupAIReport;
	AddItem(tempItem);

	tempItem.desc = "Group script variables";
	tempItem.choice = RTS_GroupVars;
	AddItem(tempItem);

	tempItem.desc = "Group script saved groups";
	tempItem.choice = RTS_GroupSaveGroups;
	AddItem(tempItem);

	tempItem.desc = "Group script timers";
	tempItem.choice = RTS_GroupTimers;
	AddItem(tempItem);
}

bool InfoChoicePU::SwitchOnChoice(Uint16 x, Uint16 y) {
	if (currentSelection.choiceType == MCT_LeftCursor) {
		if (currentSelection.choice == RTS_CycleGroupInfo)
			CycleGroupInfoType();
		else if (createNew) {
			if (currentSelection.choice == RTS_GroupStats
				|| currentSelection.choice == RTS_GroupStats
				|| currentSelection.choice == RTS_GroupShieldsInfo
				|| currentSelection.choice == RTS_GroupStatusReport
				|| currentSelection.choice == RTS_GroupAIReport
				|| currentSelection.choice == RTS_GroupVars
				|| currentSelection.choice == RTS_GroupSaveGroups
				|| currentSelection.choice == RTS_GroupTimers)
				SelectGroup(mySide, myGroup, currentSelection.choice);
			else
				myWindows.push_back(GenWindow(rect.x, rect.y, currentSelection.choice, mySide, 0, 0));
			MessageWindows(WC_YouClose, 0, 0, parentID, myID);
			closed = true;
		} else {
			MessageWindows(currentSelection.choice, 0, 0, parentID, myID);
			closed = true;
		}
	}

	return false;
}

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

	tempItem.flags = MFLAG_CRECT;
	for (int i = 0; i != sides.size(); ++i) {
		tempItem.desc = sides[i].name;
		tempItem.choice = WC_SidePU;
		tempItem.parem = i;
		AddItem(tempItem);
	}

	tempItem.flags = 0;

	AddBlankItem();

	tempItem.desc = "Game Info";
	tempItem.choice = RTS_GameInfo;
	AddItem(tempItem);

	tempItem.desc = "Options";
	tempItem.choice = RTS_OptPU;
	AddItem(tempItem);

	if (gsTo == GST_PreBattle) {
		AddBlankItem();

		if (PreBattle::pbState == PBS_PreBattle) {
			tempItem.desc = "Start battle";
			tempItem.choice = PB_IntoBattle;
			AddItem(tempItem);
		} else {
			tempItem.desc = "Save and exit";
			tempItem.choice = PB_SaveAndExit;
			AddItem(tempItem);
		}
	}

	InitRects();
}

bool BasePU::SwitchOnChoice(Uint16 x, Uint16 y) {
	if (currentSelection.choiceType == MCT_LeftCursor) {
		switch (currentSelection.choice) {
		case WC_SidePU:
			myWindows.push_back(GenWindow(WC_SidePU, currentSelection.parem, 0, RTS_GroupStats));
			closed = true;
			break;

		case RTS_OptPU:
			myWindows.push_back(GenWindow(rect.x, rect.y, RTS_OptPU, 0, 0, 0));
			closed = true;
			break;

		case RTS_GameInfo:
			myWindows.push_back(GenWindow(0, 0, RTS_GameInfo, 0, 0, WFLAG_TILED));
			closed = true;
			break;

		case PB_IntoBattle:
			gsTo = GST_Battle;
			closed = true;
			break;

		case PB_SaveAndExit:
			gsTo = GST_ForceSelect;
			closed = true;
			break;
		}
	}

	if (currentSelection.choiceType == MCT_RightCursor && currentSelection.choice == WC_SidePU)
		myWindows.push_back(GenWindow(x, y, RTS_InfoChoicePU, currentSelection.parem, 0, 0, myID, 0));

	return false;
}

OptPU::OptPU(int ix, int iy):
StandardOptions(ix, iy, none_constant, 0) {
	Update();
}

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

	MenuItem tempItem;

	tempItem.desc = "Game speed";
	tempItem.choice = RTS_SetGameSpeed;
	AddItem(tempItem);

	tempItem.desc = "Scroll speed";
	tempItem.choice = RTS_SetScrollSpeed;
	AddItem(tempItem);

	AddBlankItem();

	tempItem.desc = "Toggle group numbers";
	tempItem.choice = RTS_GroupNums;
	AddItem(tempItem);

	tempItem.desc = "Toggle group boundaries";
	tempItem.choice = RTS_GroupRects;
	AddItem(tempItem);

	AddBlankItem();

	PushBackSharedItems();
	
	AddBlankItem();

	tempItem.desc = "Restart battle";
	tempItem.choice = RTS_RestartQ;
	AddItem(tempItem);

	tempItem.desc = "Return to main menu";
	tempItem.choice = WC_Quit;
	AddItem(tempItem);

	InitRects();
}

RestartQ::RestartQ():
Menu_Base(0, 0, none_constant, 0) {
	MenuItem tempItem;
	tempItem.rect.h = lineGap << 1;

	tempItem.desc = "Are you sure you want to restart the battle?";
	tempItem.choice = WC_Nothing;
	AddItem(tempItem);

	tempItem.rect.h = lineGap;

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

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

	InitRects();

	CentreWindow();
}

bool RestartQ::SwitchOnChoice(Uint16 x, Uint16 y) {
	if (currentSelection.choiceType == MCT_LeftCursor) {
		switch(currentSelection.choice) {
		case WC_Yes:
			gsTo = GST_PreBattle;
			closed = true;
			break;

		case WC_No:
			closed = true;
			break;
		}
	}

	return false;
}

GameInfo::GameInfo(int ix, int iy, int flags):
DragWindow(ix, iy, none_constant, flags) {
	rect.w = 250;
	rect.h = 150;

	InitRects();
}

void GameInfo::DrawSelf() {
	theText.clear();
	
	theText.push_back(WindowText("Game Info:", 1));	
	theText.push_back(WindowText(""));
	
	char output[50];
	sprintf(output, "Elapsed frames: %d", frameCounter);
	theText.push_back(WindowText(output));
	
	DragWindow::DrawSelf();
}

SideVarsInfo::SideVarsInfo(int ix, int iy, int iMySide):
SideInfo(ix, iy, iMySide, 0) {
	rect.w = 200;
	rect.h = 230;
	InitRects();
}

void SideVarsInfo::DrawSelf() {
	theText.clear();
	AddSideTitle(mySide);
	char output[32];
	for (int i = 0; i != nAIVars; ++i) {
		sprintf(output, "$global%d:    %d", i, sides[mySide].scriptVars[i]);
		theText.push_back(WindowText(output));
	}

	DragWindow::DrawSelf();
}

SideAIErrors::SideAIErrors(int ix, int iy, int iMySide):
SideInfo(ix, iy, iMySide, 0) {
	rect.w = 580;
	rect.h = 270;
	InitRects();
}

void SideAIErrors::DrawSelf() {
	theText.clear();
	AddSideTitle(mySide);

	for (list<string>::const_iterator iter = sides[mySide].aiErrorReports.begin(); iter != sides[mySide].aiErrorReports.end(); ++iter) {
		theText.push_back(WindowText(*iter));
		//each string has a newline
		theText.push_back(WindowText(""));
	}

	DragWindow::DrawSelf();
}

GroupVarsInfo::GroupVarsInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
	rect.w = 200;
	rect.h = 230;

	InitRects();
}

void GroupVarsInfo::DrawSelf() {
	theText.clear();
	AddGroupTitle(mySide, myGroup);
	char output[32];
	for (int i = 0; i != nAIVars; ++i) {
		sprintf(output, "$%d:    %d", i, sides[mySide].groups[myGroup].GetScriptVar(i));
		theText.push_back(WindowText(output));
	}

	DragWindow::DrawSelf();
}

SideSaveGroupsInfo::SideSaveGroupsInfo(int ix, int iy, int iMySide):
SideInfo(ix, iy, iMySide, 0) {
	rect.w = 200;
	rect.h = 230;

	InitRects();
}

void SideSaveGroupsInfo::DrawSelf() {
	theText.clear();
	AddSideTitle(mySide);
	char output[32];
	for (int i = 0; i != nAIVars; ++i) {
		CoordsInt saveGroup = sides[mySide].saveGroups[i];
		sprintf(output, "$globalg%d:    %d-%d", i, saveGroup.x + 1, saveGroup.y + 1);
		theText.push_back(WindowText(output));
	}

	DragWindow::DrawSelf();
}

GroupSaveGroupsInfo::GroupSaveGroupsInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
	rect.w = 200;
	rect.h = 230;

	InitRects();
}

void GroupSaveGroupsInfo::DrawSelf() {
	theText.clear();
	AddGroupTitle(mySide, myGroup);
	char output[32];
	for (int i = 0; i != nAIVars; ++i) {
		CoordsInt saveGroup = sides[mySide].groups[myGroup].GetSaveGroup(i);
		sprintf(output, "$g%d:    %d-%d", i, saveGroup.x + 1, saveGroup.y + 1);
		theText.push_back(WindowText(output));
	}

	DragWindow::DrawSelf();
}

GroupTimersInfo::GroupTimersInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
	rect.w = 200;
	rect.h = 230;

	InitRects();
}

void GroupTimersInfo::DrawSelf() {
	theText.clear();
	AddGroupTitle(mySide, myGroup);
	char output[32];
	for (int i = 0; i != nAIVars; ++i) {
		sprintf(output, "$timer%d:    %d", i, sides[mySide].groups[myGroup].GetScriptTimer(i));
		theText.push_back(WindowText(output));
	}

	DragWindow::DrawSelf();
}

GameSpeedSlider::GameSpeedSlider(int ix, int iy, int flags):
SliderWithUnits(ix, iy, maxWorldUpdateInterval - worldUpdateInterval, 0, maxWorldUpdateInterval, "Game speed", "", none_constant, flags) {}

bool GameSpeedSlider::MouseM(Uint8 state, Uint16 x, Uint16 y) {
	bool ret = Slider::MouseM(state, x, y);

	if (bSliderDrag)
		SetWorldUpdateInterval(maxWorldUpdateInterval - sliderVar);

	return ret;
}

void GameSpeedSlider::DrawSelf() {
	sliderVar = maxWorldUpdateInterval - worldUpdateInterval;
	if (paused || worldUpdateInterval == standardInterval) {
		Slider::DrawSelf();
		int x = rect.x + smallBorderSize;
		int y = rect.y + smallBorderSize;
		char output[48];
		if (paused)
			sprintf(output, "%s: Paused", varName.c_str());
		else
			sprintf(output, "%s: %d - Normal", varName.c_str(), *varPointer);
		normalFonts.BlitString(x, y, 0, output);
	} else
		SliderWithUnits::DrawSelf();
}

ScrollSpeedSlider::ScrollSpeedSlider(int ix, int iy, int flags):
SliderWithUnits(ix, iy, maxScrollInterval - scrollInterval, 0, maxScrollInterval, "Scroll speed", "", none_constant, flags) {}

bool ScrollSpeedSlider::MouseM(Uint8 state, Uint16 x, Uint16 y) {
	bool ret = Slider::MouseM(state, x, y);
	
	scrollInterval = maxScrollInterval - sliderVar;
	
	if (scrollInterval > standardInterval - 10 && scrollInterval < standardInterval + 10) {
		scrollInterval = standardInterval;
		sliderVar = maxScrollInterval - scrollInterval;
	}
	
	return ret;
}

} //end namespace

