#ifndef CODE_XCPROGRAM_CXX
#define CODE_XCPROGRAM_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: XCprogram.cxx,v 1.2 1998/07/29 23:02:31 schmitzj Exp $)
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *-----------------------------------------------------------------------
 */

#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>

#include "types.h"
#include "../include/defaults.h"
#include "../include/version.h"
#include <Xclasses/XCprogram.h>
#include <Xclasses/Xwindows.h>
#include <Xclasses/dlist.h>
#include <Xclasses/gfx_xpm.h>
#include <Xclasses/tools.h>
#include "include/XCprogram_p.h"

class pXCprogram *thisProgram=NULL;
class Xclasses serviceobjs(INTERNALOBJS);

extern Xclasses basegfxobject;
extern class Xwindows helpwin;
extern char *Xclasses_logo[];
XCprogram::XCprogram(char *name, ...) : Xcolors()
{
	if (thisProgram) fatal_printf("Duplicate XCprogram class!",this);
	va_list args;
	unsigned int argName,argData;

	Name("Xclasses_program");
	while (!(p=new pXCprogram))
	{
		outOfMemory("XCprogram");
	}
	p->o=this;
	{
		char *n=name;
		while (*n)
		{
			if (*n=='/')
			{
				if (*(n+1))
				{
					name=n+1;
				}
				else
				{
					*n=0;
				}
			}
			n++;
		}
	}
	Name(name);
	p->name=this;
	va_start(args,name);

	struct moreauthor *a1=NULL,*a2=(moreauthor*)&p->author2;
	while (argName=va_arg(args,unsigned int))
	{
		switch (argName)
		{
			case XCP_MultiAuthor:
				if (!a1 || a1->author)
				{
					a1=new moreauthor;
					a2->next=a1;
					a1->next=NULL;
					a1->what=NULL;
					a1->email=NULL;
					a1->author=NULL;
					p->mauthors++;
					a2=a1;
				}
				if (a1) a1->author=va_arg(args,char *);
				break;
			case XCP_MultiAuthorJob:
				if (!a1 || a1->what)
				{
					a1=new moreauthor;
					a2->next=a1;
					a1->next=NULL;
					a1->what=NULL;
					a1->email=NULL;
					a1->author=NULL;
					p->mauthors++;
					a2=a1;
				}
				if (a1) a1->what=va_arg(args,char *);
				break;
			case XCP_MultiAuthorEMail:
				if (!a1 || a1->email)
				{
					a1=new moreauthor;
					a2->next=a1;
					a1->next=NULL;
					a1->what=NULL;
					a1->email=NULL;
					a1->author=NULL;
					p->mauthors++;
					a2=a1;
				}
				if (a1) a1->email=va_arg(args,char *);
				break;
			case XCP_Author:
				p->author=va_arg(args,char *);
				break;
			case XCP_Description:
				p->desc=va_arg(args,char *);
				break;
			case XCP_Copyright:
				p->copyright=va_arg(args,char *);
				break;
			case XCP_Version:
				p->version=va_arg(args,char *);
				break;
			case XCP_Address:
				p->address=va_arg(args,char *);
				break;
			case XCP_EMail:
				p->email=va_arg(args,char *);
				break;
			case XCP_WWW:
				p->www=va_arg(args,char *);
				break;
			case XCP_OwnText:
				p->owntext=va_arg(args,char *);
				break;
			case XCP_OwnHTML:
				p->ownhtml=va_arg(args,char *);
				break;
			case XCP_XC_logo:
				{
					gfx_xpm *XClogo=new gfx_xpm;
					XClogo->Xpm(Xclasses_logo);				
					p->gfx=XClogo;
					XClogo->Name("Xclasses_logo");
					XClogo->ParentClass(this);
				}
				break;
			case XCP_Xclasses_logo:
				{
					gfx_xpm *XClogo=new gfx_xpm;
					XClogo->Xpm(Xclasses_logo);				
					p->gfx=XClogo;
					XClogo->Name("Xclasses_logo");
					XClogo->ParentClass(this);
					argData=va_arg(args,unsigned int);
				}
				break;
			case XCP_gfxobject:
				p->gfx=va_arg(args,gfx_object *);
				break;
			case XCP_Resources:
				p->resources=va_arg(args,char *);
				break;
			case XCP_MultiSortByJob:
				argData=va_arg(args,unsigned int);
				p->sortbyjob=1;
				break;
			case XCP_RequiredXclasses:
				{
					char *reqVers=va_arg(args,char *);
					char *req=reqVers;

					int rv=atoi(reqVers);
					while (*reqVers && *reqVers!='.') reqVers++;
					int rr=atoi(reqVers);
					while (*reqVers && *reqVers!='.') reqVers++;
					int rp=atoi(reqVers);

					reqVers=LibVersion();
					int lv=atoi(reqVers);
					while (*reqVers && *reqVers!='.') reqVers++;
					int lr=atoi(reqVers);
					while (*reqVers && *reqVers!='.') reqVers++;
					int lp=atoi(reqVers);

					if (!(lv>rv || (lv==rv && lr>rr) || (lv==rv && lr==rr && lp>=rp)))
					{
						fprintf(stderr,"Sorry!\nThis program required Xclasses %s!\nYou only have %s (%d.%d.%d - %d, %d).\n\n",req,LibVersion(),LibMajor(),LibMinor(),LibPatch(),LibCompile(),LibDate());
						exit(1);
					}
				}
				break;
			default:
				argData=va_arg(args,unsigned int);
				break;
		}
	}

	va_end(args);
	thisProgram=p;
	helpwin.ParentClass(serviceobjs);
	basegfxobject.ParentClass(serviceobjs);
	serviceobjs.ParentClass(this);

	XrmInitialize();
}
XCprogram::~XCprogram()
{
	if (p) delete p;
}
pXCprogram::pXCprogram()
{
	author=NULL;
	copyright=NULL;
	version=NULL;
	desc=NULL;
	address=NULL;
	email=NULL;
	www=NULL;
	owntext=NULL;
	ownhtml=NULL;
	gfx=NULL;
	author2=NULL;
	mauthors=0;
	resources=0;
	sortbyjob=0;
}
pXCprogram::~pXCprogram()
{
	moreauthor *a1=author2,*a2=NULL;
	
	while (a1)
	{
		a2=a1->next;
		delete a1;
		a1=a2;
	}
//	gfx_xpm *XClogo=(gfx_xpm*)FindObject(o->Name(),".Xclasses_logo");
//	if (XClogo) delete XClogo;
}

#endif
