/*************************************************************
*
* (c) 1999 Christoph Pinkel
* This is part of the VisKProg project.
*
* You may use it under the terms of the GPL licence.
* See COPYING for more details!
*
**************************************************************/

#include "vfdialog.h"
#include "vfdialog.moc"


/*********************************************************************************
	class addDialog:
**********************************************************************************/
addDialog::addDialog() : QDialog( 0L, "", true )
{
	isOK = false;

	label = new QLabel(this);

	fl = new QLineEdit(this);
	sl = new QLineEdit(this);

	ok = new QPushButton ( "OK", this );
	cancel = new QPushButton ( "Cancel", this );

	myType = Variable;

	connect( ok, SIGNAL(clicked()), SLOT(okClick()) );
	connect( cancel, SIGNAL(clicked()), SLOT(cancelClick()) );

	setMinimumSize( 400, 250 );

	fl->setFocus();
}


void addDialog::setType( iTypes tp )
{
	if ( tp == Variable )
	{
		label->setText( QString ("Please enter the name of your new regional variable\n")
			+("in the first line, and its initial value in the second one.") );

		setCaption( "Add new variable" );

		myType = Variable;
	}
	else if ( tp == Constant )
	{
		label->setText( QString ("Please enter the name of your new regional constant\n")
			+("in the first line, and its value in the second one.") );

		setCaption( "Add new constant" );

		myType = Constant;
	}
	else if ( tp == Function )
	{
		label->setText( QString ("Please enter the name of your new regional user defined\n")
			+("function in the first line, and the number of arguments,\n")
			+("the function takes, in the second one.") );

		setCaption( "Add new function" );

		myType = Function;
	}

}


QString addDialog::newEntry()
{
	if(isOK)
		return fl->text();
	else
		return "";
}


QString addDialog::newArgument()
{
	if(isOK)
		return sl->text();
	else
		return "";
}


void addDialog::resizeEvent( QResizeEvent * )
{
int iw = width() -20;
int ih = height() -20;

	label->setGeometry( 10, 10, iw, ih/4 );

	fl->setGeometry( 10, ih/4 +(ih/4-30)/2, iw, 30 );
	sl->setGeometry( 10, 2*(ih/4) +(ih/4-30)/2, iw, 30 );

	ok->setGeometry( width()/3 -40, 3*(ih/4) +(ih/4-30)/2, 80, 30 );
	cancel->setGeometry( 2*width()/3 -40, 3*(ih/4) +(ih/4-30)/2, 80, 30 );
}


void addDialog::okClick() //SLOT
{
QRegExp nameTest( "[a-z]+[az-0-9_]*" );
QString txt;
int len;
int i;

	nameTest.setCaseSensitive(false);

	if( nameTest.match( fl->text(), 0, &len ) != 0
		|| (unsigned)len != QString(fl->text()).length() )
	{
		KMsgBox::message( 0L, "Wrong name",
			QString("A name must be a string of alphanumeric\n")
			+("characters and '_', where the first character MUST be an\n")
			+("alphabetic character.\nPlease enter a correct name!") );

		fl->setText("");
		fl->setFocus();

		return;
	}


	txt = sl->text();


	if  ( myType == Function )
	{
		bool ok;

		i = txt.toInt(&ok);

		if ( (i < 0) || (i > 32) )
		{
				KMsgBox::message( 0L, "Wrong value",
					QString("Number of function arguments must be\n")
					+("between 0 and 32.") );

				sl->setText("");
				sl->setFocus();

				return;
		}

		if ( !ok )
		{
				KMsgBox::message( 0L, "Wrong value",
					QString("You've got to enter the number of\n")
					+("arguments that your function takes (An integer).") );

				sl->setText("");
				sl->setFocus();

				return;
		}
	}
	else
		for ( i = 1; (unsigned)i < txt.length(); i++ )
			if ( (txt[i] == '"' && txt[i-1] != '\\') || txt[0] == '"' )
			{
				KMsgBox::message( 0L, "Wrong value",
					QString("If you want to use a '\"' in your string,\n")
					+("write a backslash before: '\\\"' !") );

				sl->setText("");
				sl->setFocus();

				return;
			}

	isOK = true;

	accept();
}


void addDialog::cancelClick() //SLOT
{
	isOK = false;

	reject();
}


/*********************************************************************************
	class inVFD:
**********************************************************************************/

inVFD::inVFD( QWidget *parent, iTypes myNewType ) : QWidget(parent)
{
int i;

	for ( i = 0; i < 512; i++ )
	{
		entrs[0][i] = "";
		entrs[1][i] = "";
	}

	label = new QLabel(this);

	boxIndex = -1;

	box = new QListBox( this, "Box" );
	box->setAutoScrollBar(true);
	box->setAutoBottomScrollBar(true);

	addButton = new QPushButton( "Add", this );
	rmButton = new QPushButton( "Remove", this );

	rmButton->setEnabled(false);

	myType = myNewType;

	if ( myType == Variable )
		setCaption ( "Regional variables for window(s)..." );
	else if ( myType == Constant )
		setCaption ( "Regional constants for window(s)..." );
	else if ( myType == Function )
		setCaption ( "Regional user defined functions for window(s)..." );

	connect( box, SIGNAL(highlighted(int)), SLOT(highlighted(int)) );
	connect( addButton, SIGNAL(clicked()), SLOT(add()) );
	connect( rmButton, SIGNAL(clicked()), SLOT(rm()) );
}


void inVFD::setText( QString newText )
{
	label->setText( newText );
}


void inVFD::setEntries( QString newEntries[], QString newVals[] )
{
int i;
QString iStr;
QString sStr;
QString s2Str;

	if (myType == Variable)
	{
		iStr = "Variable ";
		sStr = " = \"";
		s2Str = "\"";
	}
	else if (myType == Constant)
	{
		iStr = "Constant ";
		sStr = "= \"";
		s2Str = "\"";
	}
	else if (myType == Function)
	{
		iStr = "Function ";
		sStr = " (with ";
		s2Str = " arguments)";
	}

	for( i = 0; newEntries[i] != ""; i++ )
	{
		if ( i == 511 )
			fatal ( "In inVFD::setEntries(...): Too many entries (Too many regionals)." );

		box->insertItem( QString ( iStr +newEntries[i]
			+sStr +newVals[i] +s2Str ), -1 );

		entrs[0][i] = newEntries[i];
		entrs[1][i] = newVals[i];
	}

	entrs[0][i] = "";

}


void inVFD::getEntries( QString e[], QString v[] )
{
int i = 0;

	do
	{
		e[i] = entrs[0][i];
		v[i] = entrs[1][i];

		i++;

	} while (entrs[0][i] != "");

	
	e[i] = "";
}


void inVFD::resizeEvent( QResizeEvent * )
{
	label->setGeometry( 10, 10, width()-20, height()/3 -20 );

	box->setGeometry( 10, height()/3, 2*(width()/3) -10, 2*(height()/3) -10 );

	addButton->setGeometry( 2*(width()/3)+10, height()/3, width()/3 -20,
		box->height()/2 -10 );

	rmButton->setGeometry( 2*(width()/3)+10, height()/3 +box->height()/2 +10,
		width()/3 -20, box->height()/2 -10 );
}


void inVFD::highlighted( int n ) //SLOT
{

	boxIndex = n;

	rmButton->setEnabled(true);
}


void inVFD::add() //SLOT
{
int i;
QString iStr;
QString sStr;
QString s2Str;

	nd = new addDialog();

	nd->setType( myType );

	nd->show();

	if (myType == Variable)
	{
		iStr = "Variable ";
		sStr = " = \"";
		s2Str = "\"";
	}
	else if (myType == Constant)
	{
		iStr = "Constant ";
		sStr = "= \"";
		s2Str = "\"";
	}
	else if (myType == Function)
	{
		iStr = "Function ";
		sStr = " (with ";
		s2Str = " arguments)";
	}

	if ( nd->newEntry() != "" )
		box->insertItem( QString ( iStr +nd->newEntry()
			+sStr +nd->newArgument() +s2Str ), -1 );


	for( i = 0; entrs[0][i] != ""; i++ )
		if ( i == 510 )
			fatal( "In inVFD::add(): Internal error." );		

	entrs[0][i] = nd->newEntry();
	entrs[1][i] = nd->newArgument();

}


void inVFD::rm() //SLOT
{
int i;

debug("%d", boxIndex );

	for( i = boxIndex+1; entrs[0][i] != ""; i++ )
	{
		entrs[0][i-1] = entrs[0][i];
		entrs[1][i-1] = entrs[1][i];
	}

	entrs[0][i-1] = "";
	entrs[1][i-1] = "";

	box->removeItem(boxIndex);

	if( box->count() == 0 )
		rmButton->setEnabled(false);
}


/*********************************************************************************
	class vfDialog:
**********************************************************************************/

vfDialog::vfDialog( QString type ): QTabDialog( 0L, "vfDialog", true )
{
int i;

	wIndex = 0;
	myType = type;

	for ( i = 0; i < MAX_SUBS; i++ )
		subNames[i] = "";


	if ( type == "Variable"  )
		setCaption( "Edit regional variables" );
	else if ( type == "Constant"  )
		setCaption( "Edit regional constants" );
	else if ( type == "Function"  )
		setCaption( "Edit regional functions" );

	setCancelButton();
}


void vfDialog::setMember( QString name, QString vf[], QString vfv[] )
{

	//init inVF:
	if ( myType == "Variable" )
	{
		widgets[wIndex] = new inVFD(this,Variable);
		widgets[wIndex]->setText( QString ("This is a list of all regional variables ")
			+("of (sub)window ") +(name) +(".") );

	}
	else if ( myType == "Constant" )
	{
		widgets[wIndex] = new inVFD(this,Constant);
		widgets[wIndex]->setText( QString ("This is a list of all regional constants ")
			+("of (sub)window ") +(name) +(".") );
	}
	else if ( myType == "Function" )
	{
		widgets[wIndex] = new inVFD(this,Function);
		widgets[wIndex]->setText( QString ("This is a list of all regional user defined ")
			+("functions of (sub)window ") +(name) +(".") );
	}
	else
		fatal( "In vfDialog::setMember(...): No such dialog type (Internal error)." );

	subNames[wIndex] = name;

	widgets[wIndex]->setEntries( vf, vfv );

	addTab( widgets[wIndex], name );

	wIndex++;

	if ( wIndex == MAX_SUBS )
		fatal( "In vfDialog::setMember(...): Unexpected internal error." );

}

void vfDialog::getMember( QString memberName, QString FS[], QString VS[] )
{
int i;

	for ( i = 0; i < MAX_SUBS; i++ )
		if ( subNames[i] == memberName )
		{
			widgets[i]->getEntries( FS, VS );
			return;
		}


}