
#include "mediaplugin.h"

char* mediaplugin::_st_curDirectory = NULL;
char* mediaplugin::_st_mountCmd = NULL;
mediaType mediaplugin::_st_curMediaType = unknown;
char* mediaplugin::_st_tmpCdrom = NULL;
device* mediaplugin::_st_curDevice = NULL;
cMediadStatus* mediaplugin::_st_status = NULL;
int mediaplugin::_st_refCount = 0;

mediaplugin::mediaplugin(const char* pluginName) 
{
	_pluginName = strdup(pluginName);
	_pluginDescription = NULL;
	_needsUmount = false;
	_needsDirectory = false;
	_found = false;
	_doAutoStart = false;
	// default search mode should be a or method
	_sMode = Or;	
	_st_refCount++;
	_activated = true;
}

mediaplugin::mediaplugin(const mediaplugin& plugin)
{
	_patterns.clear();
	for(unsigned int i = 0; i < plugin._patterns.size(); i++)
		_patterns.push_back(plugin._patterns[i]);
	if(plugin._pluginName)
		_pluginName = strdup(plugin._pluginName);
	else
		_pluginName = NULL;
	if(plugin._pluginDescription)
		_pluginDescription = strdup(plugin._pluginDescription);
	else
		_pluginDescription = NULL;
	_needsUmount = plugin._needsUmount;
	_needsDirectory = plugin._needsDirectory;
	_found = plugin._found;
	_doAutoStart = plugin._doAutoStart;
	_sMode = plugin._sMode;	
	_st_refCount++;
	_activated = plugin._activated;
}

mediaplugin& mediaplugin::operator=(mediaplugin const& plugin)
{
	_patterns.clear();
	for(unsigned int i = 0; i < plugin._patterns.size(); i++)
		_patterns.push_back(plugin._patterns[i]);
	if(plugin._pluginName)
		_pluginName = strdup(plugin._pluginName);
	else
		_pluginName = NULL;
	if(plugin._pluginDescription)
		_pluginDescription = strdup(plugin._pluginDescription);
	else
		_pluginDescription = NULL;
	_needsUmount = plugin._needsUmount;
	_needsDirectory = plugin._needsDirectory;
	_found = plugin._found;
	_doAutoStart = plugin._doAutoStart;
	_sMode = plugin._sMode;	
	_activated = plugin._activated;
	return *this;
}

mediaplugin::~mediaplugin() 
{
	if(_pluginName)
		free(_pluginName);
	_patterns.clear();
	// free static stuff
	if(_st_refCount-- == 0) 
	{
		if(_st_curDirectory) free(_st_curDirectory);
		if(_st_mountCmd) free(_st_mountCmd);
		if(_st_tmpCdrom) { 
			free(_st_tmpCdrom);
			_st_tmpCdrom = NULL;
		}
	}
}

bool mediaplugin::searchPattern() 
{
	switch(_sMode) {
		case And:
		{
			_found = true;
			for(vector<pattern>::iterator i = _patterns.begin(); i != _patterns.end(); i++)
				switch ((*i).searchMethod) {
					case State:
						char* path;
						struct stat buf;
						asprintf(&path, "%s/%s", _st_curDirectory, (*i).searchPattern);
						if (!stat(path, &buf) == 0) 
						{
							fprintf(stderr, "cur path %s", path);
							if(!(*i).caseSensitive)
							{
								free(path);
								char *upperBuffer = strdup((*i).searchPattern);
								strToUpper(upperBuffer);
								asprintf(&path, "%s/%s", _st_curDirectory, upperBuffer);
							fprintf(stderr, "cur path %s", path);
								free(upperBuffer);
								if (!stat(path, &buf) == 0) 
									_found = false;			
							} else
									_found = false;			
						}
						else
							_pluginDescription = (*i).patternDescription;
						free(path);
						break;

					case Find:
						if (!TestType(_st_curDirectory, (*i).searchPattern, (*i).caseSensitive))
							_found = false;
						else
							_pluginDescription = (*i).patternDescription;
						break;
					case MediaType:
						if((*i).mediaT != _st_curMediaType)
							_found = false;
						else
							_pluginDescription = (*i).patternDescription;
						break;
				}
			return _found;
			break;
		}
		case Or:
		{
			_found = false;
			for(vector<pattern>::iterator i = _patterns.begin(); i != _patterns.end(); i++)
				switch ((*i).searchMethod) {
					case State:
						char* path;
						struct stat buf;
						asprintf(&path, "%s/%s", _st_curDirectory, (*i).searchPattern);
						if (stat(path, &buf) == 0) {
							_found = true;			
							_pluginDescription = (*i).patternDescription;
							free(path);
							return _found;
						} 
						else if(!(*i).caseSensitive)
						{
							free(path);
							char *upperBuffer = strdup((*i).searchPattern);
							strToUpper(upperBuffer);
							asprintf(&path, "%s/%s", _st_curDirectory, upperBuffer);
							free(upperBuffer);
							if (stat(path, &buf) == 0) 
							{
								_found = true;			
								_pluginDescription = (*i).patternDescription;
								free(path);
								return _found;
							}
						} else
							free(path);
						break;

					case Find:
						if (TestType(_st_curDirectory, (*i).searchPattern, (*i).caseSensitive)) {
							_found = true;
							_pluginDescription = (*i).patternDescription;
							return _found;
						}
						break;
					case MediaType:
						if((*i).mediaT == _st_curMediaType) {
							_found = true;
							_pluginDescription = (*i).patternDescription;
							return _found;
						}
						break;
				}
		}
	}
	return false;
}

void mediaplugin::setCurrentDevice(device* dev)
{
	if(_st_curDirectory)
		free(_st_curDirectory);
	_st_curDirectory = strdup(dev->getMountPoint());
	_st_curDevice = dev;
	_st_curMediaType = dev->getCurMediaType();
}

void mediaplugin::setMountCmd(const char* mount)
{
	if(_st_mountCmd)
		free(_st_mountCmd);
	_st_mountCmd = strdup(mount);
}

int mediaplugin::TestType(const char *dir, const char *file, bool caseSensitive) {
  	int cnt=0;
  	char *cmd = NULL;
		if(caseSensitive)
	  	asprintf(&cmd, FINDCMD, dir, file);
		else
	  	asprintf(&cmd, FINDICMD, dir, file);
  	FILE *p = popen(cmd, "r");
  	if (p) {
    		char *s;
    		cReadLine r;
    		while ((s = r.Read(p)) != NULL) {
    			if(strcmp(s,"")!=0) cnt++;
   		}
  	}
	DPRINT("TYPE %s %d\n", cmd, cnt);
	fclose(p);
  	free(cmd);
  	return cnt;
}


cOsdObject * mediaplugin::startPlugin() 
{
	cPlugin *p = cPluginManager::GetPlugin(getName());
	cOsdObject *osd = NULL;
	if (checkPluginAvailable(p)) {
		osd = p->MainMenuAction();
	}
	return osd;
}

void mediaplugin::preStartUmount() 
{
	if(_needsUmount)
			_st_curDevice->umount();
}

bool mediaplugin::checkPluginAvailable(bool ignoreActivation) 
{
	cPlugin *p = cPluginManager::GetPlugin(getName());
	if(p && (_activated || ignoreActivation))
		return true;
	else
		return false;
}

bool mediaplugin::checkPluginAvailable(const cPlugin* plugin) 
{
	if(!plugin)
	{
		Skins.Message(mtError, tr("Missing appropriate PlugIn!"));

		if (_needsUmount) { // Unmount again if nothing found
			_st_curDevice->umount();
		}
		return false;
	}
	return true;
}

void mediaplugin::setStatus(cMediadStatus* status)
{
	_st_status = status;
}

int* mediaplugin::isAutoStartSetup() 
{
	return &_doAutoStart;
}

int* mediaplugin::isActiveSetup() 
{
	return &_activated;
}

void mediaplugin::strToUpper(char *lower)
{
	for (char *iter = lower; *iter != '\0'; ++iter)
	{
	   *iter = std::toupper(*iter);
	}
}
