#include "i18n.h"
#include "skedmenu.h"
#include <vdr/tools.h>
#include <vdr/status.h>

cSkedMenu::cSkedMenu(void) : cOsdMenu(tr("Softcam.Key EDitor"),20)
{
	LoadSoftCam();
	Draw();
}

void cSkedMenu::Draw(void)
{
	Clear();
	Skins.Message(mtStatus, tr(""));
	SetHelp(tr("Save"),NULL,NULL,NULL); // Ecrire Fichier(schreiben der Datei / die Datei schreiben)
	Display();
	char *message;
	asprintf(&message,"%s %i %s %i %s",tr("The SoftCam.Key file contains "), SoftCamFileKeyNbr,tr(" keys and "),SoftCamFileTotalNbr - SoftCamFileKeyNbr,tr(" remarks"));
	display(message);
	asprintf(&message,"%s %i %s %s","    - ", SoftCamFileSecaNbr, "Seca", tr("Keys"));
	display(message);
	asprintf(&message,"%s %i %s %s","    - ", SoftCamFileViacNbr, "Viaccess", tr("Keys"));
	display(message);
	asprintf(&message,"%s %i %s %s","    - ", SoftCamFileNagraNbr, "Nagra", tr("Keys"));
	display(message);
	asprintf(&message,"%s %i %s %s","    - ", SoftCamFileIrdetoNbr, "Irdeto", tr("Keys"));
	display(message);
	asprintf(&message,"%s %i %s %s","    - ", SoftCamFileUnknownNbr, tr("unknown"), tr("Keys"));
	display(message);
	Add(new cOsdItem(tr("Add key"),osUser1));
	Add(new cOsdItem(tr("Import keys from ca.cache"),osUser4));
	Add(new cOsdItem(tr("Show keys"),osUser2));
	Add(new cOsdItem(tr("Search new keys"),osUser3));
	SetCurrent(Get(6));
	free(message);
	Display();
}

cSkedMenu::~cSkedMenu(void)
{
}

void cSkedMenu::display(char *text)	// Affiche (Anzeige)
{
	cOsdItem *item= new cOsdItem(text);
	item->SetSelectable(false);
	Add(item);
}


void cSkedMenu::LoadSoftCam(void)
{
	char SKFile[200] = {0};
	FILE *f = NULL;
	SoftCamFileKeyNbr=0;
	SoftCamFileTotalNbr=0;
	SoftCamFileSecaNbr=0;
	SoftCamFileViacNbr=0;
	SoftCamFileNagraNbr=0;
	SoftCamFileIrdetoNbr=0;
	SoftCamFileUnknownNbr=0;
	sprintf(SKFile,cPlugin::ConfigDirectory());
	strcat(SKFile,"/SoftCam.Key");
	f=fopen(SKFile,"r");
	if (f)
	{
		char buff[512] = {0};	// line buffer increased from 256 to 512
		while(fgets(buff,sizeof(buff)-1,f)) {
			if( (buff[0]!=';') && (buff[0]!='\n') && (buff[1]!='\n')) 
			{
			if (buff[0]=='S') {SoftCamFileSecaNbr=SoftCamFileSecaNbr+1;}
			else if (buff[0]=='V') {SoftCamFileViacNbr=SoftCamFileViacNbr+1;}
			else if (buff[0]=='N') {SoftCamFileNagraNbr=SoftCamFileNagraNbr+1;}
			else if (buff[0]=='I') {SoftCamFileIrdetoNbr=SoftCamFileIrdetoNbr+1;}
			else {SoftCamFileUnknownNbr=SoftCamFileUnknownNbr+1;}
			InsertTableau(buff,SoftCamFileKeyNbr);
			SoftCamFileKeyNbr=SoftCamFileKeyNbr+1;
			}
			SoftCamFileTotalNbr=SoftCamFileTotalNbr+1;
		}
	fclose(f);
	}

}

void cSkedMenu::InsertTableau(char *Line,int pos)
{
	Key Cle = {0};
	strcpy(Cle.Type,strtok(Line," \t;"));
	strcpy(Cle.Prov,strtok(NULL," \t;"));
	char temp[6] = {0};
	strcpy(temp,strtok(NULL," \t;"));
	if (!strncmp(temp,"ROM",3) )
	{
		strcpy(Cle.NRom,temp);
		strcpy(Cle.OK,strtok(NULL," \t;"));
	}
	else
	{
		strcpy(Cle.NRom,"");
		strcpy(Cle.OK,temp);
	}
	strcpy(Cle.PlainCle,strtok(NULL," \t;"));
	tableau[pos]=Cle;
}


void cSkedMenu::ImportKey()
{
	char CaFile[200] = {0};
	FILE *f = NULL;
	FILE *f2 = NULL;
	char SKFile[200] = {0};
	sprintf(SKFile,cPlugin::ConfigDirectory());
        strcat(SKFile,"/SoftCam.Key");
	sprintf(CaFile,cPlugin::ConfigDirectory());
	strcat(CaFile,"/ca.cache");
	f=fopen(CaFile,"r");
	f2=fopen(SKFile,"a"); 
	if (f)
		{
		char buff[256];
		Key Cle;
		while(fgets(buff,sizeof(buff),f)) 
			{
			 if (!strncmp(buff,":::ECM",6)) {
				 fclose(f);
				 fclose(f2);
				 LoadSoftCam();
				 Draw();
				 break;
				 }
			 if (buff[0]!='#' && buff[0]!=':') 
			 {
				strcpy(Cle.Type,strtok(buff," \t;"));
				strcpy(Cle.Prov,strtok(NULL," \t;"));
				strcpy(Cle.OK,strtok(NULL," \t;"));
				strcpy(Cle.PlainCle,strtok(NULL," \t;"));
				// Remplir les 0 manquant
				char *NewProv = NULL;
				unsigned int ProvLen=0;
				if (!strcmp(Cle.Type,"V"))
					{
					 ProvLen=6; 
					}
				else if (!strcmp(Cle.Type,"S"))
				{
					ProvLen=4;
				}
				else if (!strcmp(Cle.Type,"N"))
				{
					ProvLen=6;
				}
				else if (!strcmp(Cle.Type,"I"))
				{
					ProvLen=2;
				}
				 if (strlen(Cle.Prov)<ProvLen)
				 {
				 asprintf(&NewProv,"%s",Cle.Prov);
					 int loop=ProvLen-strlen(Cle.Prov);
					 for(int i=0;i<loop;i++)
					 {
						 asprintf(&NewProv,"0%s",NewProv);
					 }
				 }
				//Fin remplissage
				char *Line;
			        asprintf(&Line,"%s %s %s %s\n",Cle.Type,NewProv,Cle.OK,Cle.PlainCle);
				fputs(Line,f2);
				 }
			}
		}
}

eOSState cSkedMenu::ProcessKey(eKeys Key)
{
	eOSState state = cOsdMenu::ProcessKey(Key);
	switch(state) {
		case osUser1:
			return(AddSubMenu(new cSkedAdd(*this)));
			break;
		case osUser2:
			return(AddSubMenu(new cSkedVisu(*this)));
			break;
		case osUser3:
			return(AddSubMenu(new cSkedSearch(*this)));
			break;
		case osUser4:
			ImportKey();
			Skins.Message(mtStatus,tr("Keys imported")); // Cles Importees (Schlüssel importiert)
			sleep(Setup.OSDMessageTime);
			Skins.Message(mtStatus,"");
			break;
		default: 
			break;
	}
	if (!HasSubMenu())
	{
		switch(Key)
		{
			case kRed:
				SaveSK();
				break;
			default:
				Skins.Message(mtStatus, tr(""));
				break;
		}
	}
	return state;
}

void cSkedMenu::SaveSK(void)
{
	fprintf(stderr,"%s\n","EnregSK");
	FILE *f = NULL;
	char SKFile[200] = {0};
	char *skline = NULL;
	strcpy(SKFile,cPlugin::ConfigDirectory());
	strcat(SKFile,"/SoftCam.Key");
	fprintf(stderr,"%s\n",SKFile);
	f=fopen(SKFile,"w");
	if(f)
	for (int i=0; i<SoftCamFileKeyNbr;i++)
	{
		asprintf(&skline,"%s %s %s %s\n",tableau[i].Type,tableau[i].Prov,tableau[i].OK,tableau[i].PlainCle);
		fputs(skline,f);
		free(skline);
	}
	fclose(f);
	Skins.Message(mtStatus, tr("File saved!")); // Enregistre (speichern)
	
}

cSkedAdd::cSkedAdd(cSkedMenu &SK) 
:cOsdMenu(tr("Softcam.Key EDitor"),20)
{
        //static const char allowed[] = { "abcdefghijklmnopqrstuvwxyz0123456789-_" };
	SKMenu=&SK;
	strcpy(type,"V");
	strcpy(oldtype," ");
	strcpy(prov,"000000");
	strcpy(clenum,"00");
	strcpy(cleval,"0000000000000000");
	provlen=7;
	DrawMenu();
}


void cSkedAdd::DrawMenu(void)
{
	SetHelp(tr("Add"),NULL,NULL,NULL);	// Ajouter (zufügen)
	Add(new cMenuEditChrItem(tr("Encryption system"),type,"VSIN"));
	Add(new cMenuEditStrItem(tr("Provider"),prov,provlen,tr("0123456789ABCDEF")));
	Add(new cMenuEditStrItem(tr("Number of key"),clenum,3,tr("0123456789ABCDEF")));
	Add(new cMenuEditStrItem(tr("Key"),cleval,17,tr("0123456789ABCDEF")));
}


cSkedAdd::~cSkedAdd(void)
{
}

eOSState cSkedAdd::ProcessKey(eKeys Key) {
	eOSState state = cOsdMenu::ProcessKey(Key);
	int i=Current();
	//char skline[50];

	if (i == 0) CheckProv();
	if (state == osUnknown || state == osContinue) {
	switch (Key) {
		case kRed : 
			cSkedMenu::Key Cle;
			strcpy(Cle.Type,type);
			strcpy(Cle.Prov,prov);
			strcpy(Cle.OK,clenum);
			strcpy(Cle.PlainCle,cleval);
			SKMenu->tableau[SKMenu->SoftCamFileKeyNbr]=Cle;
			SKMenu->SoftCamFileKeyNbr+=1;
			if (!strcmp(type,"V")) {SKMenu->SoftCamFileViacNbr+=1;}
			else if (!strcmp(type,"S")) {SKMenu->SoftCamFileSecaNbr+=1;}
			else if (!strcmp(type,"N")) {SKMenu->SoftCamFileNagraNbr+=1;}
			else if (!strcmp(type,"I")) {SKMenu->SoftCamFileIrdetoNbr+=1;}
			Skins.Message(mtStatus,tr("Key added!")); // Cle Ajoutee! (Schlüssel hinzugefügt)
			break;
		case kOk : 
		case kGreen:
			SetHelp(tr("Add"),NULL,NULL,NULL); // // Ajouter (hinzufügen)
			break;
		default : 
			Skins.Message(mtStatus,"");
			break;
	}
	}
if (state==16) {SKMenu->Draw();}
return state;
}

void cSkedAdd::CheckProv(void) {
	if (strcmp(type,oldtype)) {
		if (!strcmp(type,"V")) {
			provlen=7;
			strcpy(prov,"000000");
		}	
		else if (!strcmp(type,"S")) {
			provlen=5;
			strcpy(prov,"0000");
		}
		else if (!strcmp(type,"N")) {
			provlen=5;
			strcpy(prov,"0000");
		}
		else if (!strcmp(type,"I")) {
			provlen=3;
			strcpy(prov,"00");
		}
		strcpy(oldtype,type);
		Clear();
		DrawMenu();
		SetCurrent(Get(0));
	}
}

/*cSkedVisu::cSkedVisu(void) : cOsdMenu(tr("Visualisation des cle"),20)
{
	char *buf;
	for (int i=0;i<SKMenu->SoftCamFileKeyNbr;i++)
	{
	asprintf(&buf,"%s : %s : %s : %s ",SKMenu.tableau[i]->Type, SKMenu->tableau[i]->Prov, SKMenu->tableau[i].OK, SKMenu->tableau[i].PlainCle);
	display(buf,true);
	}
}*/

cSkedVisu::cSkedVisu(cSkedMenu &SK) : cOsdMenu(tr("Show keys"),20) // Visualisation des cle (Visualisierung der Schlüssel / sehen der Schlüssel)
{
	SKMenu=&SK;
	char *buf = NULL;
	for (int i=0;i<SKMenu->SoftCamFileKeyNbr;i++)
	{
	if (!strcmp(SKMenu->tableau[i].NRom,""))
	{
		asprintf(&buf,"%s : %s : %s : %s ",SKMenu->tableau[i].Type, SKMenu->tableau[i].Prov, SKMenu->tableau[i].OK, SKMenu->tableau[i].PlainCle);
	}
	else
	{
		asprintf(&buf,"%s : %s : %s : %s : %s ",SKMenu->tableau[i].Type, SKMenu->tableau[i].Prov, SKMenu->tableau[i].NRom, SKMenu->tableau[i].OK, SKMenu->tableau[i].PlainCle);
	}
		display(buf,true);
	}
}

cSkedVisu::~cSkedVisu(void)
{
}

void cSkedVisu::display(char *text,bool Sel)
{
	cOsdItem *item= new cOsdItem(text);
	item->SetSelectable(Sel);
	Add(item);
}

eOSState cSkedVisu::ProcessKey(eKeys Key)
{
	eOSState state = cOsdMenu::ProcessKey(Key);
	return state;
}


cSkedSearch::~cSkedSearch(void)
{
}

void cResultMenu::display(char *text,bool Sel)
{
	cOsdItem *item= new cOsdItem(text);
	item->SetSelectable(Sel);
	Add(item);
}

/*cSkedSearch::cSkedSearch(void) : cOsdMenu(tr("Recherche de cle"),20)
{
	strcpy(type,"V");
	strcpy(oldtype," ");
	strcpy(prov,"000000");
	provlen=7;
	SearchMenu();
}*/

cSkedSearch::cSkedSearch(cSkedMenu &SK) : cOsdMenu(tr("Search new keys"),20) // Recherche de cle (suchen nach Schlüsseln)
{
	SKMenu=&SK;
	strcpy(type,"V");
	strcpy(oldtype," ");
	strcpy(prov,"000000");
	provlen=7;
	SearchMenu();

}

void cSkedSearch::SearchMenu(void)
{
	SetHelp(tr("Search"),NULL,NULL,NULL); // Rechercher
	Add(new cMenuEditChrItem(tr("Encryption system"),type,"VSIN"));
	Add(new cMenuEditStrItem(tr("Provider"),prov,provlen,tr("0123456789ABCDEF")));
}

cResultMenu::cResultMenu(char *type,char *prov,cSkedMenu &SK): cOsdMenu(tr("Search result"),20) { // "Resultat de la recherche"
	//cSkedMenu SKMenu;
	SKMenu=&SK;
	char *buf = NULL;
	for(int i=0;i<SKMenu->SoftCamFileKeyNbr;i++)
		{
			if (!strcmp(SKMenu->tableau[i].Type,type))
			{ if (!strcmp(SKMenu->tableau[i].Prov,prov))
				{
					asprintf(&buf,"%s : %s : %s : %s", SKMenu->tableau[i].Type, SKMenu->tableau[i].Prov, SKMenu->tableau[i].OK, SKMenu->tableau[i].PlainCle);
					display(buf,true);
				}	
			}
		}
}

eOSState cSkedSearch::ProcessKey(eKeys Key) {
	eOSState state = cOsdMenu::ProcessKey(Key);
	int i=Current();
	if (i==0) CheckProv();
	if (state == osUnknown || state == osContinue) {
		if (!HasSubMenu()){
		switch (Key) {
			case kRed:
				AddSubMenu(new cResultMenu(type,prov,*SKMenu));
				break;	
			case kOk:
				SetHelp(tr("Search"),NULL,NULL,NULL); // Rechercher
				break;
			default: break;
		}
		}
	}
return state;
}

void cSkedSearch::CheckProv(void)
{
	if (strcmp(type,oldtype)) {
		if (!strcmp(type,"V")) {
			provlen=7;
			strcpy(prov,"000000");
		}
		else if (!strcmp(type,"S")) { 
			provlen=5;
			strcpy(prov,"0000");
		}
		else if (!strcmp(type,"N")) { 
			provlen=5;
			strcpy(prov,"0000");
		}
		else if (!strcmp(type,"I")) { 
			provlen=3;
			strcpy(prov,"00");
		}
		strcpy(oldtype,type);
		Clear();
		SearchMenu();
		SetCurrent(Get(0));
	}
		
}


cResultMenu::~cResultMenu(void)
{
}

eOSState cResultMenu::ProcessKey(eKeys Key)
{
	eOSState state = cOsdMenu::ProcessKey(Key);
	switch(Key)
	{
		case kOk: SetHelp(NULL,NULL,NULL,NULL);
		default:break;
	}
	return state;
	if (state==16) 
	{
		CloseSubMenu();
	}
}
