/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#include <Winreg.h>
#include <Shlwapi.h>
#include <stdio.h>


#define SO_PATH_SIZE		4096 
#define MOZ_PLUGIN_DLL_NAME "npsopluginmi.dll"
extern "C" {
int lc_isInstalled(const  char* realFilePath)
{
	HKEY hKeySoftware;
	HKEY hMozillaPlugins;
	HKEY hStarOffice;
	char sSoPath[SO_PATH_SIZE];
	char sPluginPath[SO_PATH_SIZE];

	LONG ret;
	ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,  "SOFTWARE",  0,  KEY_READ, &hKeySoftware);
	if(ret != ERROR_SUCCESS){
		ret = RegOpenKeyEx(HKEY_CURRENT_USER,  "SOFTWARE",  0,  KEY_READ, &hKeySoftware);
		if(ret != ERROR_SUCCESS){
			return -1;
		}
	}
	ret = RegOpenKeyEx(hKeySoftware,  "MozillaPlugins",  0,  KEY_READ, &hMozillaPlugins);
	if(ret != ERROR_SUCCESS){
		RegCloseKey(hKeySoftware);
		if( ret == ERROR_FILE_NOT_FOUND)
			return 1;
		else 
			return -1;
	}
	ret = RegOpenKeyEx(hMozillaPlugins,  "@sun.com/npsopluginmi;version=1.0",  0,  KEY_READ, &hStarOffice);
	if(ret != ERROR_SUCCESS){
		RegCloseKey(hKeySoftware);
		RegCloseKey(hMozillaPlugins);
		if( ret == ERROR_FILE_NOT_FOUND)
			return 1;
		else 
			return -1;
	}
	
	if((realFilePath == NULL) || (strlen(realFilePath) == 0) || (strlen(realFilePath) >= SO_PATH_SIZE)) 
	    ret = -1;	    
	else{
	    sprintf(sSoPath,"%s", realFilePath);    
	    ret = 0;
	} 
	//ret =  GetCurrentDirectory( SO_PATH_SIZE, sSoPath);
	//ret = GetEnvironmentVariable("prog", sSoPath, SO_PATH_SIZE);
	// GetCurrentDirectory return the char number of the string
	if(ret == 0){
		DWORD  dType = REG_SZ;
		DWORD  dSize = SO_PATH_SIZE;
		ret = RegQueryValueEx (hStarOffice, "Path", NULL,  &dType , (LPBYTE) sPluginPath, &dSize);
		if(ret == ERROR_SUCCESS){
			if(strcmp(sPluginPath, sSoPath) == 0)
				ret = 0;
			else
				ret = 1;
		}
		else
			ret = -1;
	}
	else 
		ret = -1;
	RegCloseKey(hStarOffice);	
	RegCloseKey(hMozillaPlugins);	
	RegCloseKey(hKeySoftware);
	return ret;
}

int lc_uninstallPlugin(const  char*)
{
	HKEY hKeySoftware;
	HKEY hMozillaPlugins;
	HKEY hStarOffice;

	LONG ret;
	ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,  "SOFTWARE",  0,  KEY_READ|KEY_WRITE, &hKeySoftware);
	if(ret != ERROR_SUCCESS){
		ret = RegOpenKeyEx(HKEY_CURRENT_USER,  "SOFTWARE",  0,  KEY_READ|KEY_WRITE, &hKeySoftware);
		if(ret != ERROR_SUCCESS){
			return -1;
		}
	}
	ret = RegOpenKeyEx(hKeySoftware,  "MozillaPlugins",  0,  KEY_READ|KEY_WRITE, &hMozillaPlugins);
	if(ret != ERROR_SUCCESS){
		RegCloseKey(hKeySoftware);
		if( ret == ERROR_FILE_NOT_FOUND)
			return 0;
		else 
			return -1;
	}

	ret = RegOpenKeyEx(hMozillaPlugins,  "@sun.com/npsopluginmi;version=1.0",  0,  KEY_READ|KEY_WRITE, &hStarOffice);
	if(ret != ERROR_SUCCESS){
		RegCloseKey(hKeySoftware);
		RegCloseKey(hMozillaPlugins);
		if( ret == ERROR_FILE_NOT_FOUND)
			return 0;
		else 
			return -1;
	}
	RegCloseKey(hStarOffice);
	ret = SHDeleteKey(hMozillaPlugins,  "@sun.com/npsopluginmi;version=1.0");
	if(ret != ERROR_SUCCESS){
		ret = -1;
	}
	RegFlushKey(hMozillaPlugins);
	RegCloseKey(hMozillaPlugins);
	RegCloseKey(hKeySoftware);
	return ret;
}

int lc_installPlugin(const  char* realFilePath)
{
	HKEY hKeySoftware;
	HKEY hMozillaPlugins;
	HKEY hStarOffice;
	char sSoPath[SO_PATH_SIZE];
	DWORD  sState;


	LONG ret;
	ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,  "SOFTWARE",  0,  KEY_READ|KEY_WRITE, &hKeySoftware);
	if(ret != ERROR_SUCCESS){
		ret = RegOpenKeyEx(HKEY_CURRENT_USER,  "SOFTWARE",  0,  KEY_READ|KEY_WRITE, &hKeySoftware);
		if(ret != ERROR_SUCCESS){
			return -1;
		}
	}
	ret = RegOpenKeyEx(hKeySoftware,  "MozillaPlugins",  0,  KEY_READ|KEY_WRITE, &hMozillaPlugins);
	if(ret != ERROR_SUCCESS){
		RegCreateKeyEx(hKeySoftware,  
			"MozillaPlugins",  
			0,  
			NULL,  
			REG_OPTION_NON_VOLATILE, 
			KEY_READ|KEY_WRITE, 
			NULL,
			&hMozillaPlugins,
			&sState);
	}

	ret = RegCreateKeyEx(hMozillaPlugins,  
		"@sun.com/npsopluginmi;version=1.0",  
		0,  
		NULL,  
		REG_OPTION_NON_VOLATILE, 
		KEY_READ|KEY_WRITE, 
		NULL,
        &hStarOffice, 
		&sState);
	if(ret != ERROR_SUCCESS){
		RegCloseKey(hKeySoftware);
		RegCloseKey(hMozillaPlugins);
		return -1;
	}
	
	RegFlushKey(hStarOffice);
    RegFlushKey(hMozillaPlugins);
	
	
	if((realFilePath == NULL) || (strlen(realFilePath) == 0) || (strlen(realFilePath) >= SO_PATH_SIZE)) 
	    ret = -1;	    
	else{
	    sprintf(sSoPath,"%s", realFilePath); 
	    ret = 0; 
	}
	   
	//ret =  GetCurrentDirectory( SO_PATH_SIZE, sSoPath);
	// GetCurrentDirectory return the char number of the string
	if(ret == 0){
		ret = RegSetValueEx( hStarOffice, "Path", 0, REG_SZ,  (LPBYTE) sSoPath, strlen(sSoPath) + 1);
		if(ret == ERROR_SUCCESS)
			ret = 0;
		else
			ret = -1;
	}
	else 
		ret = -1;
    RegFlushKey(hStarOffice);
    RegFlushKey(hMozillaPlugins);
    RegCloseKey(hStarOffice);
    RegCloseKey(hMozillaPlugins);
	RegCloseKey(hKeySoftware);
	RegFlushKey(HKEY_LOCAL_MACHINE);

	return ret;
}
}
