#ifdef WIN32
#include "startmenu.h"
#include "lprintf.h"
#include "lib.h"

#define START_MENU "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MenuOrder\\Start Menu\\Programs\\"
#include <shlobj.h>
#include <io.h>

struct smfolder {
	char* path;
};

int sm_split(char* fullname, char** name);
char* sm_folder_path(char* name, char* path, int bfsz);
int CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathArgs, LPSTR lpszPathLink, LPSTR lpszDesc, LPSTR workdir);

int sm_add(char* fullname, char* target, char* args, char* startin, SMFolder** xf)
{
	SMFolder* f = NULL;
	char path[BFSZ];	
	char *name;

	if (xf) *xf = NULL;

	ncpy(path,fullname,BFSZ-1);
	if (!sm_split(fullname,&name))
		return FALSE;

	if (*fullname) {
		f = sm_open(fullname,TRUE);
		if (!f) return FALSE;
	}

	if (!sm_add_item(f,name,target,args,startin)) {
		sm_free(&f);		
		return FALSE;
	}

	if (xf) *xf = f;
	else sm_free(&f);

	return TRUE;
}

int sm_del(char* fullname, SMFolder** xf)
{
	SMFolder* f = NULL;
	char path[BFSZ];	
	char *name;

	if (xf) *xf = NULL;

	ncpy(path,fullname,BFSZ-1);
	if (!sm_split(fullname,&name))
		return FALSE;

	if (*fullname) {
		f = sm_open(fullname,FALSE);
		if (!f) return FALSE;
	}

	if (!sm_del_item(f,name)) {
		sm_free(&f);
		return FALSE;
	}

	if (xf) *xf = f;
	else sm_free(&f);

	return TRUE;

}

SMFolder* sm_open(char* folder, int create)
{
	char path[BFSZ];
	SMFolder* f;

	if (access(sm_folder_path(folder,path,BFSZ),00) != 0) {
		if (!create) return NULL;
		lib_create_dir(path,0700);
	}

	f = calloc(1,sizeof(SMFolder));	
	f->path = strdup(path);

	return f;
}

int sm_add_item(SMFolder* f, char* name, char* target, char* args, char* startin)
{
	char link[BFSZ];
	char tbf[BFSZ];

	if (!name) return FALSE;
	if (!args) args = "";

	if (!target || !*target) {
		if (f) lprintf(link,BFSZ,"%s%s",f->path,name);
		else sm_folder_path(name,link,BFSZ-1);
		return lib_mkdir(link,0700);
	}	

	if (!strstr(target,"://"))
		target = win_slash(target,tbf);

	if (!startin) {
		if (f) startin = f->path;
		else startin = "";
	}
	
	if (f) lprintf(link,BFSZ,"%s%s.lnk",f->path,name);
	else {
		sm_folder_path("",link,BFSZ-1);
		lpcat(link,BFSZ,"%s.lnk",name);
	}

	return CreateLink(target,args,link,name,startin);	
}

int sm_del_item(SMFolder* f, char* name)
{
	char link[BFSZ];

	if (!name) return FALSE;

	if (f) lprintf(link,BFSZ,"%s%s",f->path,name);
	else {
		sm_folder_path("",link,BFSZ-1);
		ncat(link,name,BFSZ-1);
	}

	if (rmdir(link) == 0)
		return TRUE;

	ncat(link,".lnk",BFSZ-1);

	if (remove(link) == 0)
		return TRUE;

	return FALSE;
}

void sm_free(SMFolder** f)
{
	if (!f || !*f) return ;
	free((*f)->path);
	free(*f);
}

/*
SMFolder* sm_folder_open(char* name) {
	char path[BFSZ];
	SMFolder* f;

	if (access(sm_folder_path(name,path,BFSZ),00) != 0)
		return NULL;

	f = calloc(1,sizeof(SMFolder));	
	f->path = strdup(path);

	return f;
}

SMFolder* sm_folder_new(SMFolder* parent, char* name) {
	SMFolder* f = calloc(1,sizeof(SMFolder));
	char path[BFSZ];

	if (parent) lprintf(path,BFSZ,"%s%s\\",name);
	else sm_folder_path(name,path,BFSZ);		

	lib_create_dir(path,0700);
	f->path = strdup(path);

	return f;
}

void sm_folder_free(SMFolder** f) {
	if (!f || !*f) return ;
	free((*f)->path);
	free(*f);
}

int sm_folder_add_item(SMFolder *f, char* name, char* target, char* args, char* startin) {
	char link[BFSZ];
	char tbf[BFSZ];

	if (!f) return FALSE;
	if (!name) return FALSE;
	if (!target) return FALSE;
	if (!args) args = "";

	if (!strstr(target,"://"))
		target = win_slash(target,tbf);

	if (!startin)
		startin = f->path;

	lprintf(link,BFSZ,"%s%s.lnk",f->path,name);
	return CreateLink(target,args,link,name,startin);
}

int sm_folder_del_item(SMFolder *f, char* name) {
	if (!f) return FALSE;
	if (!name) return FALSE;
	return TRUE;
}
*/

int sm_split(char* fullname, char** name)
{
	char *p,*last = NULL;
	int length = 0;

	for(p = fullname; *p; p++) {
		if (issep(*p)) last = p;
		length++;
	}
	if (last) *last++ = 0;
	else {
		memmove(&fullname[1],fullname,length);
		last = &fullname[1];
		fullname[0] = 0;
	}
	*name = last;
	return TRUE;
}

char* sm_folder_path(char* name, char* path, int bfsz)
{
	char xsys[BFSZ];
	char* sys;

	sys = getenv("USERPROFILE");
	if (!sys) {
		system_dir(xsys,BFSZ);
		sys = xsys;
	}
	if (name) lprintf(path,bfsz,"%s\\Start Menu\\Programs\\%s\\",sys,name);
	else lprintf(path,bfsz,"%s\\Start Menu\\Programs\\",sys);
	return path;
}

int CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathArgs, LPSTR lpszPathLink, LPSTR lpszDesc, LPSTR workdir)
{
    HRESULT hres;
    IShellLink* psl;

    if (CoInitialize(NULL)!=S_OK) printf("coinitialize failed\n");
    hres = CoCreateInstance(&CLSID_ShellLink, NULL,
       CLSCTX_INPROC_SERVER, &IID_IShellLink, &psl);

    if (hres!=S_OK) printf("CreatInstance failed %d\n",hres);
    if (hres==REGDB_E_CLASSNOTREG) printf("Clasnotreg\n");
    if (hres==CLASS_E_NOAGGREGATION) printf("noagreg\n");

    if (SUCCEEDED(hres)) {
        IPersistFile* ppf;

        psl->lpVtbl->SetPath(psl, lpszPathObj);
		psl->lpVtbl->SetArguments(psl, lpszPathArgs);
        psl->lpVtbl->SetDescription(psl, lpszDesc);
    	psl->lpVtbl->SetWorkingDirectory(psl, workdir);
        hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf);

        if (SUCCEEDED(hres)) {
            WORD wsz[MAX_PATH];

            MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);
            hres = ppf->lpVtbl->Save(ppf, wsz, TRUE);
            ppf->lpVtbl->Release(ppf);
        }

        psl->lpVtbl->Release(psl);
    }

    CoUninitialize();
    return SUCCEEDED(hres);
}
#endif
