#include "uninstall.h"
#include "wmParser.h"
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>

struct stInstalledThemell *addInstalledTheme(struct stInstalledThemell **,char *,char *,int,int);
int checkDirName(char *);

/* Function definitions for the theme removal functions */
void removeOldTheme(struct stInstalledThemell *);
void removeNewTheme(struct stInstalledThemell *);
void checkLine(char *);
int checkForFile(char *,char *,char *,char *);
void removeBackground(char *);
void removePixmap(char *);
void getType(char *,char *);

struct stInstalledThemell *getInstalledList(char *themePath,int installType)
{
	struct stInstalledThemell *first=NULL,*temp,*current;
	DIR *themeDir;
	struct dirent *dirEntry;
	char name[NAME_MAX];
	struct stat entryStat;
	int error;
	char fullname[PATH_MAX+NAME_MAX];
	
	/* Attempt to open the directory passed to us */
	themeDir=opendir(themePath);
	/* If we can't open the directory... */
	if (themeDir==NULL) {
		/* Give the user an error message */
		printf("Unable to open directory: %s\n",themePath);
		/* Return a null to indicate an error occured */
		return (NULL);
	}
	
	/* Read through the directory entries */
	while ((dirEntry=readdir(themeDir))!=NULL) {
		/* Copy the directory name into a variable to make handling a little
		   easier */
		strncpy(name,dirEntry->d_name,NAME_MAX);
		/* Make sure that we don't have the current directory or the 
		   directory above us */
		if (strncmp(name,".",NAME_MAX) && strncmp(name,"..",NAME_MAX)) {
			/* Get the full path name for the file */
			strncpy(fullname,themePath,PATH_MAX);
			strncat(fullname,"/",1);
			strncat(fullname,name,NAME_MAX);
			/* Get information about the file */
			error=stat(fullname,&entryStat);
			/* Did we get an error getting the file information... */
			if (error) {
				/* Let the user know about the error */
				printf("Unable to read information of %s\n",fullname);
				/* Return NULL to indicate an error condition */
				closedir(themeDir);
				return (NULL);
			}
			/* Is it a regular file... */
			if (S_ISREG(entryStat.st_mode)) {
				addInstalledTheme(&first,name,fullname,OLD_THEME,installType);
			}
			/* Is it a directory ... */
			if (S_ISDIR(entryStat.st_mode)) {
				/* Is it a 0.60 type theme file... */
				if (checkDirName(name)==NEW_THEME) {
					addInstalledTheme(&first,name,fullname,NEW_THEME,installType);
				} else {
					current=addInstalledTheme(&first,name,fullname,DIRECTORY,installType);
					temp=getInstalledList(fullname,installType);
					current->child=temp;
				}
			}
		}
	}
	closedir(themeDir);
	return (first);
}

struct stInstalledThemell *addInstalledTheme(struct stInstalledThemell **pFirst,char *themeName,char *filename,int themeType,int installType)
{
	struct stInstalledThemell *temp,*seeknode,*seeknode_last;
	
	temp=(struct stInstalledThemell *)malloc(sizeof(struct stInstalledThemell));
	strncpy(temp->filename,filename,512);
	strncpy(temp->name,themeName,80);
	temp->themeType=themeType;
	temp->installType=installType;
	temp->child=NULL;
	
	seeknode_last=NULL;
	seeknode=*pFirst;
	while ((seeknode!=NULL) && (strncasecmp(seeknode->name,themeName,80) < 0)) {
		seeknode_last=seeknode;
		seeknode=seeknode->next;
	}
	temp->prev=seeknode_last;
	temp->next=seeknode;
	if (temp->next) temp->next->prev=temp;
	if (!seeknode_last) {
		*pFirst=temp;
	} else {
		seeknode_last->next=temp;
	}
	
	return temp;
}

int checkDirName(char *filename)
{
	if (strlen(filename)<8) {
		return DIRECTORY;
	}
	if (strncmp(&filename[strlen(filename)-7],".themed",7)==0) {
		filename[strlen(filename)-7]='\0';
		return NEW_THEME;
	}
	return DIRECTORY;
}

/* Functions to handle the removal of the theme files */

void uninstallTheme(struct stInstalledThemell *pCurrent)
{
	if (pCurrent==NULL) return;
	if (pCurrent->themeType==OLD_THEME) removeOldTheme(pCurrent);
	else removeNewTheme(pCurrent);
}

void removeOldTheme(struct stInstalledThemell *pCurrent)
{
	char line[256];
	int error;
	FILE *f;
	
	f=fopen(pCurrent->filename,"r");
	if (f==NULL) return;
	while (!feof(f)) {
		fgetvalue(line,f);
		if (!feof(f)) checkLine(line);
	}
	fclose(f);
	error=unlink(pCurrent->filename);
}

void checkLine(char *line)
{
	int test;
	char name[80];
	char value[80];
	char filename[256];

	test=strspn(line," \t");
	strcpy(name,"");
	getNameValuePair(&line[test],name,value);
	if (strlen(name)>2) {
		name[strlen(name)-1]='\0';
	}
	if (checkForFile(name,"WorkspaceBack",value,filename)) {
		removeBackground(filename);
	}
	else if (checkForFile(name,"FTitleBack",value,filename)) {
		removePixmap(filename);
	}
	else if (checkForFile(name,"PTitleBack",value,filename)) {
		removePixmap(filename);
	}
	else if (checkForFile(name,"UTitleBack",value,filename)) {
		removePixmap(filename);
	}
	else if (checkForFile(name,"MenuTitleBack",value,filename)) {
		removePixmap(filename);
	}
	else if (checkForFile(name,"MenuTextBack",value,filename)) {
		removePixmap(filename);
	}
	else if (checkForFile(name,"IconBack",value,filename)) {
		removePixmap(filename);
	}
//	else printf("%s\n",line);
}

int checkForFile(char *name,char *check,char *value,char *filename)
{
	char type[80];
	char middle[80];

	if (strcmp(name,check)) return 0;
	
	getType(value,type);
	if (!strcmp(type,"tpixmap")||!strcmp(type,"spixmap")||
	    !strcmp(type,"thgradient")||!strcmp(type,"tdgradient")) {
		getMiddleValue(value,middle);
		strcpy(filename,middle);
		return 1;
	} else {
//		printf("%s of type %s\n",name,type);
	}
	return 0;
}

void removeBackground(char *filename)
{
	char fullname[512];
	int error;
	
	strcpy(fullname,"/usr/local/share/WindowMaker/Backgrounds/");
	strcat(fullname,filename);
	error=unlink(fullname);
	strcpy(fullname,getenv("HOME"));
	strcat(fullname,"/GNUstep/Library/WindowMaker/Backgrounds/");
	strcat(fullname,filename);
	error=unlink(fullname);
}

void removePixmap(char *filename)
{
	struct stDirectoryll *current;
	char fullname[512];
	int error;

	current=getIconPath();
	while (current!=NULL) {
		strcpy(fullname,current->name);
		strcat(fullname,"/");
		strcat(fullname,filename);
		error=unlink(fullname);
		current=current->next;
	}
}

void getType(char *value,char *type)
{
	int length,count,mcount;
	
	length=strlen(value);
	count=mcount=0;
	strcpy(type,"");
	while (((value[count]=='(')||(value[count]==' ')||(value[count]=='\t'))&&(count<length)) count++;
	if (count==length) return;
	while ((value[count]!=',')&&(count<length)) {
		type[mcount]=value[count];
		count++;
		mcount++;
	}
	type[mcount]='\0';
}

void removeNewTheme(struct stInstalledThemell *current)
{
	DIR *thisDir;
	struct dirent *dirEntry;
	char fullpath[512];
	int error;

	thisDir=opendir(current->filename);
	if (thisDir==NULL) {
		showMessageDialog("Error","Unable to open directory");
		return;
	}
	while ((dirEntry=readdir(thisDir))!=NULL) {
		if ((strcmp(dirEntry->d_name,"."))&&(strcmp(dirEntry->d_name,".."))) {
			strcpy(fullpath,current->filename);
			strcat(fullpath,"/");
			strcat(fullpath,dirEntry->d_name);
			error=unlink(fullpath);
			if (error) {
				showMessageDialog("Error","Unable to remove file");
				closedir(thisDir);
				return;
			}
		}
	}
	closedir(thisDir);
	rmdir(current->filename);
}


syntax highlighted by Code2HTML, v. 0.9.1