/*******************************************************************************
  TPI - flexible but useless plug-in framework.
  Copyright (C) 2002-2009 Silky

  This library is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the Free
  Software Foundation; either version 2.1 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 Lesser General Public License
  for more details.

  You should have received a copy of the GNU Lesser General Public License along
  with this library; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

  $Id: TPIHandle.cpp,v 1.5 2009/08/28 12:41:29 sirakaba Exp $
*******************************************************************************/

//******************************************************************************
//    Includes
//******************************************************************************

#define wxUSE_DYNLIB_CLASS 1
#include "../header/plugin.h"
#include <wx/dynlib.h>
#include "TPIHandle.h"

//******************************************************************************
//    Class (TPIHandle)
//******************************************************************************

TPIHandle::~TPIHandle(void)
{
	this->FreeLibrary();
}

bool TPIHandle::InitLibrary(const wxString & _szLibName, const wxString & _szArcName, wxULongLong _llSubOption)
{
	this->lib.Load(_szLibName);
	if (! this->lib.IsLoaded())
	{
		return false;
	}

	if (_szArcName.IsEmpty())
	{
		return true;
	}

	if (! this->lib.HasSymbol(wxT("LoadPlugin")))
	{
		return false;
	}
	void * p = this->lib.GetSymbol(wxT("LoadPlugin"));
	if (! p)
	{
		return false;
	}

	return ((int (__stdcall *)(const wxString &, wxULongLong)) p)(_szArcName, _llSubOption) == TPI_ERROR_SUCCESS;
}

bool TPIHandle::FreeLibrary(void)
{
	if (! this->lib.IsLoaded())
	{
		return false;
	}

	if (! this->lib.HasSymbol(wxT("FreePlugin")))
	{
		return false;
	}
	void * p = this->lib.GetSymbol(wxT("FreePlugin"));
	if (! p)
	{
		return false;
	}
	((int (__stdcall *)(void *)) p)(NULL);

	this->lib.Unload();
	return true;
}

int TPIHandle::GetPluginInformation(unsigned int _uInfoId, wxULongLong _llSubOption, void * _pPtr)
{
	if (! this->lib.HasSymbol(wxT("GetPluginInformation")))
	{
		return -1;
	}
	void * p = this->lib.GetSymbol(wxT("GetPluginInformation"));
	if (! p)
	{
		return -1;
	}

	return ((int (__stdcall *)(unsigned int, wxULongLong, void *)) p)(_uInfoId, _llSubOption, _pPtr);
}

int TPIHandle::CheckArchive(const wxString & _szArcName, int * _nFileCount)
{
	if (! this->lib.HasSymbol(wxT("CheckArchive")))
	{
		return -1;
	}
	void * p = this->lib.GetSymbol(wxT("CheckArchive"));
	if (! p)
	{
		return -1;
	}

	return ((int (__stdcall *)(const wxString &, int *)) p)(_szArcName, _nFileCount);
}

int TPIHandle::OpenArchive(const wxString & _szArcName, void * * _hArchive)
{
	if (! this->lib.HasSymbol(wxT("OpenArchive")))
	{
		return -1;
	}
	void * p = this->lib.GetSymbol(wxT("OpenArchive"));
	if (! p)
	{
		return -1;
	}

	return ((int (__stdcall *)(const wxString &, void * *)) p)(_szArcName, _hArchive);
}

int TPIHandle::CloseArchive(void * _hArchive)
{
	if (! this->lib.HasSymbol(wxT("CloseArchive")))
	{
		return -1;
	}
	void * p = this->lib.GetSymbol(wxT("CloseArchive"));
	if (! p)
	{
		return -1;
	}

	return ((int (__stdcall *)(void *)) p)(_hArchive);
}

int TPIHandle::GetFileInformation(void * _hArchive, TPI_FILEINFO * _fiInfo, bool _bFirst)
{
	if (! this->lib.HasSymbol(wxT("GetFileInformation")) || ! _fiInfo)
	{
		return -1;
	}
	void * p = this->lib.GetSymbol(wxT("GetFileInformation"));
	if (! p)
	{
		return -1;
	}

	// Initialization.
	_fiInfo->dwAttribute    = 0;
	_fiInfo->dwCRC32        = 0;
	_fiInfo->tmAccess       = 0;
	_fiInfo->tmCreate       = 0;
	_fiInfo->tmModified     = 0;
	_fiInfo->uOSType        = 0;
	_fiInfo->llPackedSize   = 0;
	_fiInfo->llUnpackedSize = 0;
	_fiInfo->szStoredName   = wxEmptyString;
	_fiInfo->szMethod       = wxEmptyString;
	_fiInfo->wCompressRatio = 0;
	_fiInfo->llFileID       = 0;
	_fiInfo->pCustomInfo    = NULL;

	return ((int (__stdcall *)(void *, TPI_FILEINFO *, bool)) p)(_hArchive, _fiInfo, _bFirst);
}

int TPIHandle::GetArchiveInformation(void * _hArchive, TPI_ARCHIVEINFO * _aiInfo)
{
	if (! this->lib.HasSymbol(wxT("GetArchiveInformation")) || ! _aiInfo)
	{
		return -1;
	}
	void * p = this->lib.GetSymbol(wxT("GetArchiveInformation"));
	if (! p)
	{
		return -1;
	}

	// Initialization.
	_aiInfo->fSolid			= false;
	_aiInfo->fMMOptimize    = false;
	_aiInfo->fEncryptData   = false;
	_aiInfo->fEncryptHeader = false;
	_aiInfo->sCompressLevel = 0;
	_aiInfo->sRecoveryRecord= 0;
	_aiInfo->tmAccess       = 0;
	_aiInfo->tmCreate       = 0;
	_aiInfo->tmModified     = 0;
	_aiInfo->nSFXType       = 0;
	_aiInfo->uOSType        = 0;
	_aiInfo->llFileSize     = 0;
	_aiInfo->llPackedSize   = 0;
	_aiInfo->llReadSize     = 0;
	_aiInfo->llUnpackedSize = 0;
	_aiInfo->llSplitSize    = 0;
	_aiInfo->szComment      = wxEmptyString;
	_aiInfo->wCompressRatio = 0;
	_aiInfo->pCustomInfo    = NULL;

	return ((int (__stdcall *)(void *, TPI_ARCHIVEINFO *)) p)(_hArchive, _aiInfo);
}

int TPIHandle::Command(unsigned int _uCommand, TPI_SWITCHES * _swInfo, const wxString & _szArcName, const wxArrayString & _szFiles)
{
	if (! this->lib.HasSymbol(wxT("Command")))
	{
		return -1;
	}
	void * p = this->lib.GetSymbol(wxT("Command"));
	if (! p)
	{
		return -1;
	}

	return ((int (__stdcall *)(unsigned int, TPI_SWITCHES *, const wxString &, const wxArrayString &)) p)(_uCommand, _swInfo, _szArcName, _szFiles);
}

int TPIHandle::SetCallbackProc(TPI_PROC _prProc)
{
	if (! this->lib.HasSymbol(wxT("SetCallbackProc")))
	{
		return -1;
	}
	void * p = this->lib.GetSymbol(wxT("SetCallbackProc"));
	if (! p)
	{
		return -1;
	}

	return ((int (__stdcall *)(TPI_PROC)) p)(_prProc);
}
