/*************************************************************
*
* (c) 1999, 2000 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 "formedittop.h"
#include "formedittop.moc"

formedit::formedit( const char *fn = 0L ) : KTopLevelWidget()
{
startwin *stw;

	stw = new startwin();

	dialogOK = false;

	createMenuBar();
	createToolBar();
	createStatusBar();

	widget = new winedit( this, fn );

	connect( widget, SIGNAL( resetToolSignal() ), SLOT( resetMenu() ) );
	connect( widget, SIGNAL( showEvent(QString,QString) ),
		SLOT( runSrcEdit(QString,QString) ) );

	setMinimumSize( 600, 400 );

	setView( widget );

	setCaption( "VisKProg window editor" );

	delete stw;
}


void formedit::createMenuBar()
{

	accel = new KAccel(this);

	accel->insertStdItem( KAccel::New ); // START
	accel->insertStdItem( KAccel::Open );// These lines aren't necessary
                                             //
	accel->insertStdItem( KAccel::Save );// with KDE versions > 1.1.2
	accel->insertStdItem( KAccel::Quit );// STOP

	accel->connectItem( KAccel::New, this, SLOT( NewS() ) );
	accel->connectItem( KAccel::Open, this, SLOT( OpenS() ) );

	accel->connectItem( KAccel::Save, this, SLOT( SaveS() ) );
	accel->connectItem( KAccel::Quit, this, SLOT( QuitS() ) );

	fileMenu = new QPopupMenu;

	fileMenu->insertItem( "&New", ID_NEW );
	accel->changeMenuAccel( fileMenu, ID_NEW, KAccel::New );

	fileMenu->insertItem( "&Open ...", ID_OPEN );
	accel->changeMenuAccel( fileMenu, ID_OPEN, KAccel::Open );

	fileMenu->insertSeparator();

	fileMenu->insertItem( "&Save", ID_SAVE );
	accel->changeMenuAccel( fileMenu, ID_SAVE, KAccel::Save );
	fileMenu->insertItem( "&Save to ...", ID_SAVE_TO );

	fileMenu->insertSeparator();

	fileMenu->insertItem( "&Quit", ID_QUIT );
	accel->changeMenuAccel( fileMenu, ID_QUIT, KAccel::Quit );



	editMenu = new QPopupMenu;

	editMenu->insertItem( "&Copy", ID_COPY );
	editMenu->insertItem( "&Paste", ID_PASTE );
	editMenu->insertItem( "&Delete", ID_DELETE );

	editMenu->insertSeparator();
	
	editMenu->insertItem( "&Regional variables", ID_VARS );
	editMenu->insertItem( "Regional co&nstants", ID_CONST );
	editMenu->insertItem( "Regional user defined f&unctions", ID_FUNCTIONS );



	toolMenu = new QPopupMenu;

	toolMenu->insertItem( "&None (Select/Move)", ID_NO_TOOL );

	toolMenu->insertSeparator();

	toolMenu->insertItem( "&Widget (Sub window)", ID_WID );

	toolMenu->insertSeparator();

	toolMenu->insertItem( "&Button", ID_BUTTON );
	toolMenu->insertItem( "&Label", ID_LABEL );
	toolMenu->insertItem( "&Pixmap label", ID_PIXLABEL );
	toolMenu->insertItem( "Lin&eedit", ID_EDITW );
	toolMenu->insertItem( "L&ist", ID_LIST );
	toolMenu->insertItem( "&Check box", ID_CHECKW );
	toolMenu->insertItem( "Op&tion box", ID_OPTIONW );
	toolMenu->insertItem( "&Slider", ID_SLIDER );
	toolMenu->insertItem( "P&rocess control", ID_PROCCTRL );

	toolMenu->setItemChecked( ID_NO_TOOL, true );

	helpMenu = new QPopupMenu;
	helpMenu->insertItem( "&About", ID_ABOUT );
	helpMenu->insertItem( "&Help", ID_HELP );

	//Bar:
	mainMenu = new KMenuBar( this, "mainMenu" );

	mainMenu->insertItem( "&File", fileMenu );
	mainMenu->insertItem( "&Edit", editMenu );
	mainMenu->insertItem( "&Tool", toolMenu );
	mainMenu->insertSeparator();
	mainMenu->insertItem( "&Help", helpMenu );

	setMenu( mainMenu );

	accel->readSettings();

	connect( mainMenu, SIGNAL( activated(int) ), SLOT( cmd(int) ) );

} //createMenuBar()


void formedit::createToolBar()
{
KIconLoader il;
/* KDE standard icon names:

	"filenew.xpm"
	"fileopen.xpm"
	"filefloppy.xpm"
*/

	//mainToolBar:
	mainToolBar = new KToolBar( this );

	mainToolBar->insertButton( il.loadIcon( "filenew.xpm" ),
		ID_NEW, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true,  "New VK form" );

	mainToolBar->insertButton( il.loadIcon( "fileopen.xpm" ),
		ID_OPEN, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Open VK top form file" );

	mainToolBar->insertButton( il.loadIcon( "filefloppy.xpm" ),
		ID_SAVE, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Save file(s) to actual directory" );

	addToolBar( mainToolBar );


	//secondToolBar:
	secondToolBar = new KToolBar( this );

	secondToolBar->insertButton( il.loadIcon( "pointer.xpm" ),
		ID_NO_TOOL, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Pointer tool" );

	secondToolBar->insertSeparator();

	secondToolBar->insertButton( il.loadIcon( "widget.xpm" ),
		ID_WID, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Sub windows" );

	secondToolBar->insertButton( il.loadIcon( "button.xpm" ),
		ID_BUTTON, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Command button" );

	secondToolBar->insertButton( il.loadIcon( "label.xpm" ),
		ID_LABEL, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Text label" );

	secondToolBar->insertButton( il.loadIcon( "pixlabel.xpm" ),
		ID_PIXLABEL, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Pixmap label" );

	secondToolBar->insertButton( il.loadIcon( "ledit.xpm" ),
		ID_EDITW, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Line edit" );

	secondToolBar->insertButton( il.loadIcon( "list.xpm" ),
		ID_LIST, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Item list" );

	secondToolBar->insertButton( il.loadIcon( "check.xpm" ),
		ID_CHECKW, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Check box" );

	secondToolBar->insertButton( il.loadIcon( "option.xpm" ),
		ID_OPTIONW, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Option box" );

	secondToolBar->insertButton( il.loadIcon( "slider.xpm" ),
		ID_SLIDER, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Slider" );

	secondToolBar->insertButton( il.loadIcon( "procctrl.xpm" ),
		ID_PROCCTRL, SIGNAL(clicked(int)), this,
		SLOT(cmd(int)), true, "Process control" );

	secondToolBar->setToggle(ID_NO_TOOL);
	secondToolBar->setButton( ID_NO_TOOL, true );

	secondToolBar->setToggle(ID_WID);
	secondToolBar->setToggle(ID_BUTTON);
	secondToolBar->setToggle(ID_LABEL);
	secondToolBar->setToggle(ID_PIXLABEL);
	secondToolBar->setToggle(ID_EDITW);
	secondToolBar->setToggle(ID_LIST);
	secondToolBar->setToggle(ID_CHECKW);
	secondToolBar->setToggle(ID_OPTIONW);
	secondToolBar->setToggle(ID_SLIDER);
	secondToolBar->setToggle(ID_PROCCTRL);

	addToolBar( secondToolBar );

	

} //createToolBar();


void formedit::createStatusBar()
{
	statusBar = new KStatusBar( this );

	statusBar->insertItem( " ", ST_ID_TXT );
	statusBar->message( "Welcome!", 3000 );

	setStatusBar( statusBar );
	statusBar->show();
}


void formedit::uncheckTM()
{
	toolMenu->setItemChecked( ID_NO_TOOL, false );
	toolMenu->setItemChecked( ID_WID, false );
	toolMenu->setItemChecked( ID_BUTTON, false );
	toolMenu->setItemChecked( ID_LABEL, false );
	toolMenu->setItemChecked( ID_PIXLABEL, false );
	toolMenu->setItemChecked( ID_EDITW, false );
	toolMenu->setItemChecked( ID_CHECKW, false );
	toolMenu->setItemChecked( ID_OPTIONW, false );
	toolMenu->setItemChecked( ID_LIST, false );
	toolMenu->setItemChecked( ID_SLIDER, false );
	toolMenu->setItemChecked( ID_PROCCTRL, false );

	secondToolBar->setButton( ID_NO_TOOL, false );
	secondToolBar->setButton( ID_WID, false );
	secondToolBar->setButton( ID_BUTTON, false );
	secondToolBar->setButton( ID_LABEL, false );
	secondToolBar->setButton( ID_PIXLABEL, false );
	secondToolBar->setButton( ID_EDITW, false );
	secondToolBar->setButton( ID_CHECKW, false );
	secondToolBar->setButton( ID_OPTIONW, false );
	secondToolBar->setButton( ID_LIST, false );
	secondToolBar->setButton( ID_SLIDER, false );
	secondToolBar->setButton( ID_PROCCTRL, false );
}


QString formedit::getWHName( widgetHolder *wh )
{
int i;
QString ps[100], vs[100];

	wh->getProperties( ps, vs );

	for ( i = 0; ps[i] != "Name"; i++ )
	{
		if ( i == 99 || ps[i] == "" )
			fatal ( "In formedit::getWHName(...): Unexpected internal error." );

	}

	return( vs[i] );
}


void formedit::editVars()
{
widgetHolder *nms[MAX_SUBS+1];
QString nmsNames[MAX_SUBS+1];
int i;
	//Get the names of all widgets that may have own regional variables
	//(only sub windows, here simply called "Widgets"):

	widget->getSubs( "SubWindow", nms );

	//Invoke dialog:
	dialogOK = true;

	fvd = new vfDialog("Variable");	

	connect( fvd, SIGNAL(cancelButtonPressed()), SLOT(tabDialogCancel()) );

	for ( i = 0; i < MAX_SUBS+1; i++ )
		if ( nms[i] != 0L )
		{
			nmsNames[i] = getWHName( nms[i] );

			fvd->setMember( nmsNames[i], nms[i]->getVarNames(),
				nms[i]->getVarVals() );
		}
		else
			nmsNames[i] = "";

	fvd->show();

	if (dialogOK)
		for ( i = 0; i < MAX_SUBS+1; i++ )
			if ( nms[i] != 0L )
			{
				/* Since widgetHolder::getXYZ-functions return
				   pointers, this is used to SET these values here,
				   not to read them: */

				fvd->getMember( nmsNames[i], nms[i]->getVarNames(),
					nms[i]->getVarVals() );

			}

	delete fvd;

}


void formedit::editConst()
{
widgetHolder *nms[MAX_SUBS+1];
QString nmsNames[MAX_SUBS+1];
int i;

	//Get the names of all widgets that may have own regional constants
	//(only sub windows, here simply called "Widgets"):

	widget->getSubs( "SubWindow", nms );

	//Invoke dialog:
	dialogOK = true;

	fvd = new vfDialog("Constant");	

	connect( fvd, SIGNAL(cancelButtonPressed()), SLOT(tabDialogCancel()) );

	for ( i = 0; i < MAX_SUBS+1; i++ )
		if ( nms[i] != 0L )
		{
			nmsNames[i] = getWHName( nms[i] );

			fvd->setMember( nmsNames[i], nms[i]->getConstNames(),
				nms[i]->getConstVals() );
		}
		else
			nmsNames[i] = "";

	fvd->show();

	if (dialogOK)
		for ( i = 0; i < MAX_SUBS+1; i++ )
			if ( nms[i] != 0L )
			{
				/* Since widgetHolder::getXYZ-functions return
				   pointers, this is used to SET these values here,
				   not to read them: */

				fvd->getMember( nmsNames[i], nms[i]->getConstNames(),
					nms[i]->getConstVals() );

			}

	delete fvd;

}


void formedit::editFuncs()
{
widgetHolder *nms[MAX_SUBS+1];
QString nmsNames[MAX_SUBS+1];
int i;

	//Get the names of all widgets that may have own functions
	//(only sub windows, here simply called "Widgets"):

	widget->getSubs( "SubWindow", nms );

	//Invoke dialog:
	dialogOK = true;

	fvd = new vfDialog("Function");	

	connect( fvd, SIGNAL(cancelButtonPressed()), SLOT(tabDialogCancel()) );

	for ( i = 0; i < MAX_SUBS+1; i++ )
		if ( nms[i] != 0L )
		{
			nmsNames[i] = getWHName( nms[i] );

			fvd->setMember( nmsNames[i], nms[i]->getFuncNames(),
				nms[i]->getFuncVals() );
		}
		else
			nmsNames[i] = "";

	fvd->show();

	if (dialogOK)
		for ( i = 0; i < MAX_SUBS+1; i++ )
			if ( nms[i] != 0L )
			{
				/* Since widgetHolder::getXYZ-functions return
				   pointers, this is used to SET these values here,
				   not to read them: */

				fvd->getMember( nmsNames[i], nms[i]->getFuncNames(),
					nms[i]->getFuncVals() );

			}

	delete fvd;

}


void formedit::openNew()
{
	if (widget->closeAndNew())
		statusBar->message( "New file created.", 3000 );
		
}


void formedit::open()
{
	QString openFile = KFileDialog::getOpenFileName( 0L, "*.vktf" );

	if(!openFile.isNull())
		if (widget->open(openFile))
			statusBar->message( "File(s) opened.", 3000 );
}


void formedit::saveTo()
{
	QString newDir = KFileDialog::getDirectory( QDir::current().absPath() );

	if ( !newDir.isNull() )
	{
		if ( !widget->setDir( newDir ) )
		{
			KMsgBox::message( 0L, "Sorry.", "No such directory or permission denied." );
			statusBar->message( "NOT saved.", 3000 );

			return;
		}

		if ( !widget->save() )
		{
			KMsgBox::message( 0L, "Sorry.",
				"Failed to save (some) file(s).\nMaybe permission denied or can't overwrite." );

			statusBar->message( "NOT saved.", 3000 );
			return;
		}
		else
			statusBar->message( "Files(s) saved to " +newDir +".", 3000 );

	}


} //saveTo()


void formedit::save()
{
	if ( !widget->hasName() )
		saveTo();
	else
	{

		if ( !widget->isModified() )
		{
			statusBar->message( "No changes need to be saved.", 3000 );
			return;
		}

		if ( !widget->save() )
		{
			KMsgBox::message( 0L, "Sorry.",
				"Failed to save (some) file(s).\nMaybe permission denied or can't overwrite." );

			statusBar->message( "NOT saved.", 3000 );
			return;
		}
		else
			statusBar->message( "Files(s) saved.", 3000 );

	}

}


void formedit::NewS() //SLOT
{
	cmd( ID_NEW );
}

void formedit::OpenS() //SLOT
{
	cmd( ID_OPEN );
}

void formedit::SaveS() //SLOT
{
	cmd( ID_SAVE );
}

void formedit::QuitS() //SLOT
{
	cmd( ID_QUIT );
}

void formedit::cmd( int id ) //SLOT
{
	switch (id)
	{
		case ID_NEW:
			openNew();
			break;

		case ID_OPEN:
			open();
			break;

		case ID_SAVE:
			save();
			break;

		case ID_SAVE_TO:
			saveTo();
			break;

		case ID_QUIT:
			KApplication::getKApplication()->quit();
			break;


		case ID_COPY:
			break;

		case ID_PASTE:
			break;

		case ID_DELETE:
			break;

		case ID_VARS:
			editVars();
			break;

		case ID_CONST:
			editConst();
			break;

		case ID_FUNCTIONS:
			editFuncs();
			break;


		case ID_NO_TOOL:
			uncheckTM();
			toolMenu->setItemChecked( ID_NO_TOOL, true );
			secondToolBar->setButton( ID_NO_TOOL, true );
			widget->setTool( ID_NO_TOOL );
			break;

		case ID_WID:
			uncheckTM();
			toolMenu->setItemChecked( ID_WID, true );
			secondToolBar->setButton( ID_WID, true );
			widget->setTool( ID_WID );
			break;

		case ID_BUTTON:
			uncheckTM();
			toolMenu->setItemChecked( ID_BUTTON, true );
			secondToolBar->setButton( ID_BUTTON, true );
			widget->setTool( ID_BUTTON );
			break;

		case ID_LABEL:
			uncheckTM();
			toolMenu->setItemChecked( ID_LABEL, true );
			secondToolBar->setButton( ID_LABEL, true );
			widget->setTool( ID_LABEL );
			break;

		case ID_PIXLABEL:
			uncheckTM();
			toolMenu->setItemChecked( ID_PIXLABEL, true );
			secondToolBar->setButton( ID_PIXLABEL, true );
			widget->setTool( ID_PIXLABEL );
			break;

		case ID_EDITW:
			uncheckTM();
			toolMenu->setItemChecked( ID_EDITW, true );
			secondToolBar->setButton( ID_EDITW, true );
			widget->setTool( ID_EDITW );
			break;

		case ID_LIST:
			uncheckTM();
			toolMenu->setItemChecked( ID_LIST, true );
			secondToolBar->setButton( ID_LIST, true );
			widget->setTool( ID_LIST );
			break;

		case ID_CHECKW:
			uncheckTM();
			toolMenu->setItemChecked( ID_CHECKW, true );
			secondToolBar->setButton( ID_CHECKW, true );
			widget->setTool( ID_CHECKW );
			break;

		case ID_OPTIONW:
			uncheckTM();
			toolMenu->setItemChecked( ID_OPTIONW, true );
			secondToolBar->setButton( ID_OPTIONW, true );
			widget->setTool( ID_OPTIONW );
			break;

		case ID_SLIDER:
			uncheckTM();
			toolMenu->setItemChecked( ID_SLIDER, true );
			secondToolBar->setButton( ID_SLIDER, true );
			widget->setTool( ID_SLIDER );
			break;

		case ID_PROCCTRL:
			uncheckTM();
			toolMenu->setItemChecked( ID_PROCCTRL, true );
			secondToolBar->setButton( ID_PROCCTRL, true );
			widget->setTool( ID_PROCCTRL );
			break;

		case ID_ABOUT:
			KMsgBox::message( 0L, "About KWinedit",
				QString ("KWinedit for VisKProg v0.1.7 (Mar 2000)\n\n")
					+("Written by Christoph Pinkel <de_cp@linuxstart.com>\n")
					+("Please get the latest VisKProg version at\n")
					+("http://www.linuxstart.com/~vk") );
			break;

		case ID_HELP:
			KApplication::getKApplication()->invokeHTMLHelp("kwinedit/kwinedit.html", "");
			break;

		default:
			fatal ( "In formedit::cmd(): No such menu command." );

	} //switch

} //cmd(...)



void formedit::resetMenu() //SLOT
{
	uncheckTM();

	toolMenu->setItemChecked( ID_NO_TOOL, true );
	secondToolBar->setButton( ID_NO_TOOL, true );
}


void formedit::runSrcEdit( QString eName, QString defCont )
{
KProcess *kp;
QFile f( eName );
QDir d = QDir::current();

	if ( !f.exists() )
	{
		if( !f.open( IO_WriteOnly ) )
		{
			KMsgBox::message( 0L, "Error",
				QString ("File access error: Can't open\n")
					+eName +(" for write access.") );
			return;
		}

		f.writeBlock( defCont, strlen(defCont) );

		f.close();
	}

	debug( "Starting ksrcedit for %s", (const char *)eName );

	kp = new KProcess();

	kp->setExecutable( "kvkedit" );
	*kp << eName;

	kp->start();

}


void formedit::tabDialogCancel() //SLOT
{
	dialogOK = false;
}