// vim:ts=2 sw=2
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "uop.h"
#include <iostream>
#include "interface.h"
#include "gumps.h"
#include "uopconfig.h"
#include "action.h"
#include "network.h"
#include "interfacehandler.h"
#include "world.h"
extern UOPConfig *config;
extern Gumps *gumps;
extern Action *action;
extern Network *network;
extern Interface *intrface;
extern InterfaceHandler *interfaceHandler;
Interface::Interface()
{
}
Interface::~Interface()
{
}
void Interface::loadDef()
{
string line;
string intrfname=config->encapDatLoc("intrface.def");
deffile.open(intrfname.c_str());
if (!deffile.is_open())
{
#ifdef HAVE_CONFIG_H
intrfname = DATADIR;
intrfname += "/intrface.def";
deffile.open(intrfname.c_str());
if (!deffile.is_open())
{
#endif
cerr<<"Couldn't open "<<intrfname<<endl;
exit(1);
#ifdef HAVE_CONFIG_H
}
#endif
}
deffile.seekg(0,ios::end);
deflen=deffile.tellg();
deffile.seekg(4);
deflen-=4;
defbuffer=new char[deflen];
deffile.read(defbuffer,deflen);
deffile.close();
defptr=0;
string *workingLines=new string[256];
int numLines=0;
int numObjects=0;
InterfaceObject *workingObjects[40];
while (readLine(line))
{
int comments=line.find("//");
if (comments>=0)
line=line.substr(0,comments);
int triml=line.find_first_not_of(" ");
int trimr=line.find_last_not_of(" ");
if (triml<0 || trimr<0) continue;
line=line.substr(triml,trimr-triml);
if (line.length()==0) continue;
if (line[0]=='#')
{
triml=line.find_first_not_of(" ",1);
if (triml<0) continue;
line=line.substr(triml);
if (line=="enddef")
{
for (int i=0;i<numObjects;i++)
{
workingObjects[i]->numLines=numLines;
workingObjects[i]->lines=new string[numLines];
for (int l=0;l<numLines;l++)
workingObjects[i]->lines[l]=workingLines[l];
objects[workingObjects[i]->name]=workingObjects[i];
}
numObjects=0;
numLines=0;
}
else
workingObjects[numObjects++]=new InterfaceObject(line);
}
else
workingLines[numLines++]=line;
}
delete [] defbuffer;
}
bool Interface::readLine(string &line)
{
char ch;
line="";
do {
ch=defbuffer[defptr++];
if (ch!='\n') line+=ch;
defptr++;
} while (defptr<deflen && ch!='\n');
return defptr<deflen;
}
GumpMain *Interface::getGump(string gump)
{
if (objects[gump]) return objects[gump]->getGump();
return NULL;
}
InterfaceObject::InterfaceObject(string &name)
{
this->name=name;
}
GumpMain *InterfaceObject::getGump()
{
GumpMain *gump=new GumpMain(name);
for (int i=0;i<numLines;i++)
{
int tokenlen=lines[i].find_first_of(" ");
string args="";
if (tokenlen<0)
tokenlen=lines[i].length();
else
args=lines[i].substr(tokenlen+1);
string token=lines[i].substr(0,tokenlen);
//cerr<<token<<endl;
if (token[0]=='\t') // tabbed continuation of previous gump
{
token=token.substr(1);
if (token=="fontnumber")
{
GumpFontNumber *fn=new GumpFontNumber(args);
gump->getLast()->fontNumber=fn->fontNumber;
delete fn;
}
if (token=="emboss")
gump->getLast()->emboss=true;
if (token=="engrave")
gump->getLast()->engrave=true;
}
if (token=="rect") {
GumpRect *r=new GumpRect(args);
gump->sx=r->sx;
gump->sy=r->sy;
gump->sw=r->sw;
gump->sh=r->sh;
gump->hasRect=true;
delete r;
}
if (token=="partialhue") {
GumpPartialHue *ph=new GumpPartialHue(args);
gump->partial=ph->partial;
delete ph;
}
if (token=="fontcolor") {
GumpFontColor *fc=new GumpFontColor(args);
gump->fontcolor=fc->fontcolor;
delete fc;
}
if (token=="fancypantsaccountlogincastleandsunthingy") {
string tempCastle("9001 0 0 0");
gump->add(new GumpBackground(tempCastle));
}
if (token=="background") gump->add(new GumpBackground(args));
if (token=="interface") gump->add(new GumpInterface(args));
if (token=="sizablebackground") gump->add(new GumpSizableBackground(args));
if (token=="button") gump->add(new GumpButton(args));
if (token=="include") {
GumpMain *inc=intrface->getGump(args);
if (inc->hasRect)
{
gump->sx=inc->sx;
gump->sy=inc->sy;
gump->sw=inc->sw;
gump->sh=inc->sh;
inc->sx="0"; inc->sy="0";
inc->sw="R"; inc->sh="B";
}
gump->add(inc);
}
if (token=="layoutbutton") gump->add(new GumpLayoutButton(args));
if (token=="decoration") gump->add(new GumpDecoration(args));
if (token=="text") gump->add(new GumpText(args));
if (token=="interfacebutton") gump->add(new GumpInterfaceButton(args));
if (token=="interfaceradiobutton")
gump->add(new GumpInterfaceRadioButton(args));
if (token=="textarea")
gump->add(interfaceHandler->registerTextArea(new GumpTextArea(args)));
if (token=="numerictextarea")
gump->add(interfaceHandler->registerTextArea(new GumpTextArea(args)));
if (token=="layouttoggle") gump->add(new GumpLayoutToggle(args));
if (token=="toggle") gump->add(new GumpToggle(args));
if (token=="vlist")
gump->add(interfaceHandler->registerVList(new GumpVList(args)));
if (token=="colorpicker") gump->add(interfaceHandler->registerColorPicker(new GumpColorPicker(args)));
if (token=="hscrollbar") gump->add(new GumpHScrollBar(args));
if (token=="scene") gump->add(new Scene());
}
return gump;
}
/****** eval stuff ******/
static bool isOperator(char op,int &level)
{
if (op=='*' || op=='/') level=2;
else if (op=='+' || op=='-') level=1;
else return false;
return true;
}
static int findLowOp(const string &s)
{
int n=-1,level,min=3;
char ch;
int numParens=0;
for (unsigned int i=0;i<s.length();i++)
{
ch=s[i];
if (ch=='(') numParens++;
else if (ch==')') numParens--;
else if (isOperator(ch,level) && !numParens)
if (level<=min)
{
n=i;
min=level;
}
}
return n;
}
Sint16 myEval(string s,Sint16 w,Sint16 h)
{
if (s=="") return 0;
int numParens;
int n;
if (s[0]=='(' && s[s.length()-1]==')')
{
numParens=1;
n=0;
while (numParens) //this will totally hose if the parens are unbalanced
{
n++;
if (s[n]=='(') numParens++;
else if (s[n]==')') numParens--;
}
if (n==(int)s.length()-1)
return myEval(s.substr(1,s.length()-2),w,h); //unwrap parens
}
n=findLowOp(s);
if (n==-1)
{
if (s=="R") return w;
if (s=="B") return h;
if (s[0]=='g' && s[1]=='w' && (s[2]=='w' || s[2]=='h'))
{
if (s[2]=='w') return 640;
if (s[2]=='h') return 480;
}
if (s[0]=='g' && (s[1]=='w' || s[1]=='h'))
{
Sint16 v=0;
for (unsigned int i=2;i<s.length();i++)
{
v*=10;
v+=s[i]-'0';
}
GumpIndex &idx=gumps->getIndex(v);
if (s[1]=='w') return idx.width;
else return idx.height;
}
if (s[0]=='s' && (s[1]=='w' || s[1]=='h'))
{
if (s[1]=='w') return 640;
else return 480;
}
Sint16 v=0;
for (unsigned int i=0;i<s.length();i++)
{
v*=10;
v+=s[i]-'0';
}
return v;
}
else
{
char oper=s[n];
Sint16 l,r;
l=myEval(s.substr(0,n),w,h);
r=myEval(s.substr(n+1,s.length()-n-1),w,h);
switch (oper)
{
case '+': return l+r;
case '-': return l-r;
case '*': return l*r;
case '/': return l/r;
default: cerr<<"DOH"<<endl; break;
}
}
return 0;
}