// vim:ts=2 sw=2
#include "uop.h"
#include <SDL/SDL.h>
#include "interfacehandler.h"
#include "interface.h"
#include "action.h"
#include "network.h"
extern SDL_Surface *screen;
extern Interface *intrface;
extern Action *action;
extern Network *network;
char *hairstyles[]={
"hairbald","hairshort","hairlong","hairpony","hairmohawk","hairpageboy",
"hairtopknot","haircurly","hairreceding",NULL};
char *beardstyles[]={
"facialnone","facialgoatee","faciallongbeard","facialshortbeard",
"facialmustache","facialshorfullbeard","faciallongfullbeard",
"facialvandyke",NULL};
InterfaceHandler::InterfaceHandler()
{
activeGump=NULL;
mouseX=mouseY=oldX=oldY=false;
activeText=primedText=NULL;
textFocus=0;
currentGump=NULL;
screenH = screen->h;
screenW = screen->w;
}
InterfaceHandler::~InterfaceHandler()
{
}
bool InterfaceHandler::handleEvents()
{
SDL_Event event;
bool updateAction=false;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_MOUSEMOTION:
mouseX=event.motion.x;
mouseY=event.motion.y;
break;
case SDL_MOUSEBUTTONDOWN:
if (activeGump)
activeGump->mouseDown(event.button.button,
event.button.x,event.button.y);
else if (gumpList.size())
{
bool hit=false;
vector<GumpMain *>::reverse_iterator i;
for (i=gumpList.rbegin();i!=gumpList.rend() && !hit;i++)
hit=(*i)->mouseDown(event.button.button,
event.button.x,event.button.y);
if (hit) currentGump=(*i);
}
updateAction=true;
break;
case SDL_MOUSEBUTTONUP:
if (activeGump)
activeGump->mouseUp(event.button.button,
event.button.x,event.button.y);
else if (gumpList.size())
{
bool hit=false;
vector<GumpMain *>::reverse_iterator i;
for (i=gumpList.rbegin();i!=gumpList.rend() && !hit;i++)
hit=(*i)->mouseUp(event.button.button,
event.button.x,event.button.y);
if (hit) currentGump=(*i);
}
updateAction=true;
break;
case SDL_KEYDOWN:
updateAction=processKey(event.key.keysym.sym,event.key.keysym.mod);
break;
case SDL_VIDEORESIZE:
screenW = event.resize.w;
screenH = event.resize.h;
break;
case SDL_QUIT:
exit(0);
}
}
if (mouseX!=oldX || mouseY!=oldY)
{
oldX=mouseX;
oldY=mouseY;
if (activeGump && !activeGump->mouseMove(mouseX,mouseY))
{
activeGump->mouseExit();
activeGump=NULL;
updateAction=true;
}
if (!activeGump && gumpList.size())
{
vector<GumpMain *>::reverse_iterator i;
for (i=gumpList.rbegin();i!=gumpList.rend() && !activeGump;i++)
{
currentGump=(*i);
activeGump=currentGump->mouseEnter(mouseX,mouseY);
}
if (!activeGump) currentGump=NULL;
}
if (activeGump) updateAction=true;
}
return updateAction;
}
void InterfaceHandler::addGump(string gump,int x,int y,int w,int h)
{
GumpMain *g=intrface->getGump(gump);
g->move(x,y,w,h);
gumpList.push_back(g);
}
void InterfaceHandler::addGump(string gump,void (Action::*onClose)(),
int x,int y,int w,int h)
{
GumpMain *g=intrface->getGump(gump);
g->close=onClose;
g->move(x,y,w,h);
gumpList.push_back(g);
}
void InterfaceHandler::removeAllGumps()
{
activeGump=NULL;
gumpList.clear();
primedText=activeText=textMessage=NULL;
activeStrings.clear();
textFocus=0;
currentGump=NULL;
}
void InterfaceHandler::draw()
{
vector<GumpMain *>::iterator i;
for (i=gumpList.begin();i!=gumpList.end();i++)
(*i)->draw();
}
void InterfaceHandler::buttonClicked(Uint32 ID)
{
switch (ID)
{
case 10013: //cancel
{
GumpMain *g=currentGump;
gumpList.pop_back();
if (g->close)
(action->*(g->close))();
}
break;
case 10019: //prev
if (currentGump && currentGump->gumpName=="shardselection")
{
removeAllGumps();
addGump("accountlogin");
network->disconnect();
}
break;
case 10020: //next
if (currentGump && currentGump->gumpName=="accountlogin")
action->signOn(*activeStrings[0],*activeStrings[1]);
if (currentGump && currentGump->gumpName=="shardselection")
action->selectServer(1);
if (currentGump && currentGump->gumpName=="charcreation-appearance")
action->selectName(*activeStrings[0]);
break;
case 10026: //quit
exit(0);
case 10042: //skin hue
showColorPicker(130502);
break;
case 10043: //hair hue
showColorPicker(130503);
break;
case 10044: //beard hue
showColorPicker(130504);
break;
case 10045: //shirt hue
showColorPicker(130505);
break;
case 10046: //pants hue
showColorPicker(130506);
break;
case 10047: //hairstyle
{
if (activeGump)
{
activeGump->mouseExit();
activeGump=NULL;
}
GumpVList *vlist=getVList(110005);
for (int i=0;hairstyles[i];i++)
vlist->add(new GumpVListChild(i+110005*100,
hairstyles[i],hairstyles[i],hairstyles[i],""));
}
break;
case 10048: //beard style
{
if (activeGump)
{
activeGump->mouseExit();
activeGump=NULL;
}
GumpVList *vlist=getVList(110006);
for (int i=0;beardstyles[i];i++)
vlist->add(new GumpVListChild(i+110006*100,
beardstyles[i],beardstyles[i],beardstyles[i],""));
}
break;
}
if ((ID/10)==10021) // char sel
{
int chr=ID%10;
if (chr>=maxCharacters) // create character
action->createCharacter(chr);
else
action->selectCharacter(chr);
}
}
void InterfaceHandler::buttonToggled(Uint32 ID,bool state)
{
}
void InterfaceHandler::vListChosen(Uint32 ID)
{
if (ID/100==110002) //server selection
action->selectServer(ID%100);
if (ID/100==110005) //hair
{
action->selectHair(ID%100);
GumpVList *vlist=getVList(110005);
if (activeGump)
{
activeGump->mouseExit();
activeGump=NULL;
}
vlist->clear();
}
if (ID/100==110006) //beard
{
action->selectBeard(ID%100);
GumpVList *vlist=getVList(110006);
if (activeGump)
{
activeGump->mouseExit();
activeGump=NULL;
}
vlist->clear();
}
if (ID/100==110007) // profession
action->selectProfession(ID%100);
}
void InterfaceHandler::colorChosen(Uint32 ID,Uint16 hue)
{
showColorPicker(0);
switch (ID)
{
case 130502:
action->selectSkinHue(hue);
break;
case 130503:
action->selectHairHue(hue);
break;
case 130504:
action->selectBeardHue(hue);
break;
case 130505:
action->selectShirtHue(hue);
break;
case 130506:
action->selectPantHue(hue);
break;
}
}
void InterfaceHandler::primeText(string &text)
{
primedText=&text;
}
void InterfaceHandler::message(string &message)
{
textMessage=&message;
}
GumpTextArea *InterfaceHandler::registerTextArea(GumpTextArea *textarea)
{
if (textarea->ID==30005)
{
textarea->textarea=new string();
activeStrings.push_back(textarea->textarea);
activeText=textarea->textarea;
}
if (textarea->ID==30006)
{
textarea->textarea=new string();
activeStrings.push_back(textarea->textarea);
textarea->password=true;
}
if (textarea->ID==30007)
{
version="Project:UO version 0.2.9 (alpha)";
textarea->textarea=&version;
}
if (textarea->ID==30008)
textarea->textarea=primedText;
if (textarea->ID==30013)
textarea->textarea=primedText;
if (textarea->ID==30019) //character name
{
textarea->textarea=new string();
activeStrings.push_back(textarea->textarea);
activeText=textarea->textarea;
}
if (textarea->ID==140402)
textarea->textarea=textMessage;
return textarea;
}
GumpVList *InterfaceHandler::registerVList(GumpVList *vlist)
{
vLists[vlist->ID]=vlist;
return vlist;
}
GumpVList *InterfaceHandler::getVList(Uint32 ID)
{
return vLists[ID];
}
GumpColorPicker *InterfaceHandler::registerColorPicker(GumpColorPicker *picker)
{
switch (picker->ID)
{
case 130502: picker->baseHue=1001; break;
case 130503: picker->baseHue=1101; break;
case 130504: picker->baseHue=1101; break;
case 130505: picker->baseHue=1; break;
case 130506: picker->baseHue=1; break;
}
colorPickers[picker->ID]=picker;
return picker;
}
void InterfaceHandler::showColorPicker(Uint32 ID)
{
map<Uint32,GumpColorPicker *>::iterator i;
for (i=colorPickers.begin();i!=colorPickers.end();i++)
(*i).second->visible=false;
if (ID) colorPickers[ID]->visible=true;
if (activeGump)
{
activeGump->mouseExit();
activeGump=NULL;
}
}
void InterfaceHandler::initCharacters(Uint8 numChars)
{
characters.clear();
maxCharacters=numChars;
curCharacter=0;
}
void InterfaceHandler::addCharacter(string chr)
{
characters.push_back(chr);
}
int InterfaceHandler::getNextCharacter()
{
return curCharacter++;
}
string &InterfaceHandler::getCharacter(int id)
{
return characters[id];
}
void InterfaceHandler::setProfession(string &profession)
{
this->profession=profession;
}
static char shifts[]={
'`','~','1','!','2','@','3','#','4','$','5','%','6','^','7','&',
'8','*','9','(','0',')','-','_','=','+','[','{',']','}',';',':',
'\'','\"',',','<','.','>','/','?','\\','|',0,0};
char InterfaceHandler::SDL2ASC(SDLKey c,SDLMod m)
{
char ch;
int i;
ch=c;
if (m&KMOD_SHIFT)
{
i=0;
if (c>='a' && c<='z')
ch=c-('a'-'A');
else
{
while (shifts[i*2] && shifts[(i++)*2]!=c);
if (shifts[(i-1)*2])
ch=shifts[(i-1)*2+1];
}
}
return ch;
}
bool InterfaceHandler::processKey(SDLKey c,SDLMod m)
{
char ch;
if (c>255) return false;
if (!activeText) return false;
if (c==SDLK_TAB)
{
textFocus++;
if (textFocus==activeStrings.size())
textFocus=0;
activeText=activeStrings[textFocus];
}
else if (c==SDLK_RETURN)
{
textFocus++;
if (textFocus==activeStrings.size())
{
//submit here
}
else
activeText=activeStrings[textFocus];
}
else if (c==SDLK_BACKSPACE || c==SDLK_DELETE)
{
if (activeText->length())
activeText->erase(activeText->end()-1);
}
else if (c)
{
ch=SDL2ASC(c,m);
(*activeText)+=ch;
}
return true;
}
void InterfaceHandler::focusTextArea(string *textArea)
{
textFocus = 0;
while ((activeStrings[textFocus] != textArea)
&& (textFocus < activeStrings.size()))
textFocus++;
activeText = activeStrings[textFocus];
}