program jef_program;

uses 'jef_program_variables.pas', 'jef_program_getmovie.pas', 'jef_program_getperson.pas', 'jef_program_home.pas', 'jef_program_options.pas', 'jef_program_utils.pas';

////////////////////////////////////////////////////////////////////////////////
// JeF's Interface is released for free use but Not for free Full Copying.    //
// I have spent many, many hours to build it and it should be understandable  //
// i want to stay credited for special features introduced in this interface. //
// So, feel free to read code, and get ideas to build your own script, but    //
// please don't publish full copy : ask me for new features instead...        //
////////////////////////////////////////////////////////////////////////////////

//updated by Vlad for Movienizer 5

const
	script_name='JeF';   // Fork from original_program.pas v5
	language='';
	version=39;
	author='JeF';

//show movies by selected user reference
//links like <a href='userref:Code,Text'>link</a>
function GetUserReference(code: integer; text: string): string;
begin
	result:=GetUserReference2(code, text, 1);
end;

//show movies by selected user reference
//links like <a href='userref:Code,Text'>link</a>
//links like <a href='userref:Code,Text,Page'>link</a>
function GetUserReference2(code: integer; text: string; page: integer): string;
var
	sl: TStringList;
	i, j, RecordCount: integer;
	s, s2, jOutFile, jOutStr, jFileName:string;
begin
	if (code=1) then begin
		i:=pos('\mainlogo',jLastPage);
		if (i>0) then begin
			j:=MyPos('.',jLastPage,i);
			s:=copy(jLastPage,i,j-i+1);
			s2:=s;
			if (s='\mainlogo.') 
				then s2:='\mainlogo2.'
			else s2:='\mainlogo.';
			delete(jLastPage,i,length(s));
			insert(s2,jLastPage,i);
		end;
	end;
	// Dump edition filepath to Temporary filepaths list TextFile
	if (code=10000) then begin
		sl:=TStringList.Create;
		sl.Add(Format('select filename from editions where code =%d ', [page]));
		RecordCount:=ExecuteSQL(sl.text);
		if RecordCount>0 then begin
			jFileName:=GetStringField('filename');
			sl.Clear;
			jOutFile:=ScriptsPath+'JeF_Sql_Result.csv';
			if MyFileExists(jOutFile) then sl.LoadFromFile(jOutFile);
			jOutStr:=jFileName+';Ed:'+IntToStr(page);    // 20100907-JeF
			if (pos(jOutStr,sl.Commatext)=0) then begin	   // 20100907-JeF
				sl.Add(jOutStr);   // 20100907-JeF
				sl.SaveToFile(jOutFile);
			end;
		end;
		sl.Free;
	end;
	result:=jLastPage;
end;

//show movies by selected manual
function GetReference(ReferenceCode, reference: integer): string;
begin
	result:=GetReference2(ReferenceCode, reference, 0);
end;

//show movies by selected manual
function GetReference2(ReferenceCode, reference, page: integer): string;
var
	XFid: integer;
	XFarg, all: string;
begin
	all:='';
	if (reference>100) then begin
		reference:=reference-12;
		XFid:=reference div 100000;
		XFarg:=IntToStr(ReferenceCode);
		while (length(XFarg)<9) do XFarg:='0'+XFarg;
		XFarg:=IntToStr(reference mod 100000)+XFarg;
		while (length(XFarg)<14) do XFarg:='0'+XFarg;
		all:=ExtraFeature(XFid,XFarg);
	end
	else begin
		SetIntXFvar(4,'CurPageNbr',1);
		all:=NewGetReference(ReferenceCode, reference);
	end;
	result:=all;
	jLastPage:=result;
end;
	
function NewGetReference(ReferenceCode, reference: integer): string;
var
  sl: TStringList;
  i, j, k, kol, RecordCount, rating: integer;
  all, s, description, year, director, writer, actor, bio, character, movie: string;
  jEdManualTypes, FileName, img, rate: string;
  jTargetPage, jListWidth: integer;							// 20090703-JeF
  AudioEditionMediaType: Integer;
begin
	SetIntXFvar(4,'ReferenceCode',ReferenceCode);
	SetIntXFvar(4,'reference',reference);
	jTargetPage:=GetIntXFvar(4,'CurPageNbr');
	s:=IntToStr(ReferenceCode);
	while (length(s)<9) do s:='0'+s;
	jHomePageCode:=s;
	s:=IntToStr(reference);
	while (length(s)<5) do s:='0'+s;
	jHomePageCode:='0004'+s+jHomePageCode;
	sl:=TStringList.Create;
	if ReferenceCode>0 then begin
	  jEdManualTypes:='1,2,4,5,6,7,10,19,20,21';
	  with sl do begin
		Clear;
		Add('select * from manuals');
		if ((Reference = 6) or (Reference = 7)) then
			Add(format('where code=%d and reference=%d', [ReferenceCode, 23]))
        else
			Add(format('where code=%d and reference=%d', [ReferenceCode, reference]));
	  end;
	  RecordCount:=ExecuteSQL(sl.text);
	  if RecordCount<=0 then
		exit;
	  ProgramReference:=GetStringField('name');

      //показываем фильмы по выбранному справочнику
      with sl do begin
        Clear;
		Add('select m.title, m.code, m.year, m.in_collection, m.rating, m.filename ');
		if (pos(IntToStr(reference),jEdManualTypes)>0) 
			then Add(',e.code ');
		Add('from movies m');
		if (pos(IntToStr(reference),jEdManualTypes)>0) 
			then Add('left outer join editions e on e.movie=m.code');
        //custom fields
        if (reference>=13) and (reference<=16) then begin
			i:=reference-12;
			Add(format('where m.custom%d=%d', [i, ReferenceCode]));
        end
        //video standard
        else if (reference=1) then begin
			//Add(format('where m.video_standard=%d', [ReferenceCode]));
			Add(format('where e.video_standard=%d', [ReferenceCode]));
        end
        //media format
        else if (reference=2) then begin
			//Add(format('where m.media_format=%d', [ReferenceCode]));
			Add(format('where e.media_format=%d', [ReferenceCode]));
        end
        //media type
        else if (reference=3) then begin
			Add(format('where m.media_type=%d', [ReferenceCode]));
        end
        //aspect ratio
        else if (reference=4) then begin
			//Add(format('where m.screen_ratio=%d', [ReferenceCode]));
			Add(format('where e.screen_ratio=%d', [ReferenceCode]));
        end
        //resolution
        else if (reference=5) then begin
			//Add(format('where m.resolution=%d', [ReferenceCode]));
			Add(format('where e.resolution=%d', [ReferenceCode]));
        end
		//2011-12-23 Vlad
        else if (reference=6) or (reference=7) then
        begin
			AudioEditionMediaType := 7 - reference;
    		Add(format('inner join audio_manuals em on em.edition=e.code and em.media_type=%d', [AudioEditionMediaType]));
    	    Add('inner join manuals mg on mg.code=em.reference');
    		Add(format('where mg.code=%d', [ReferenceCode]));
        end		
(*        //subtitles (6), audio tracks (7) or edition (21)
        else if (reference=6) or (reference=7) then begin
			Add(format('inner join editions_manuals em on em.edition=e.code and em.reference=%d', [reference]));
			Add('inner join manuals mg on mg.code=em.ref_code');
			Add(format('where mg.code=%d', [ReferenceCode]));
        end
*)        //location
        else if (reference=10) then begin
			//Add('inner join loans l on l.movie=m.code');
			Add('inner join loans l on l.edition=e.code');
			Add(format('where l.location=%d', [ReferenceCode]));
			Add('and (l.return_date='''' or l.return_date is null)');
        end
        //mpaa
        else if (reference=11) then begin
			Add(format('where m.mpaa=%d', [ReferenceCode]));
        end
		//video codec
        else if (reference=19) then begin
			//Add(format('where m.video_codec=%d', [ReferenceCode]));
			Add(format('where e.video_codec=%d', [ReferenceCode]));
        end
        //disc label
        else if (reference=20) then begin
			//Add(format('where m.disc_label=%d', [ReferenceCode]));
			Add(format('where e.disc_label=%d', [ReferenceCode]));
        end
        //edition type
        else if (reference=21) then begin
			Add(format('where e.edition=%d', [ReferenceCode]));
        end
        else begin
			Add(format('inner join movies_manuals mm on mm.movie=m.code and mm.reference=%d', [reference]));
			Add('inner join manuals mg on mg.code=mm.ref_code');
			Add(format('where mg.code=%d', [ReferenceCode]));
        end;
		
		i:=GetIntOption('ByManualsListOrder');
		if (i=0) then s:='order by m.year desc, m.title'
		else if (i=1) then s:='order by m.title, m.year'
		else s:='';
		Add(s);
      end;
      
      case reference of
			//video standard
			1: s:=format(GetLangStr(1134), [ProgramReference]);
			//media format
			2: s:=format(GetLangStr(1105), [ProgramReference]);
			//media type
			3: s:=format(GetLangStr(1106), [ProgramReference]);
			//aspect ratio
        	4: s:=format(GetLangStr(645), [ProgramReference]);
        	//resolution
        	5: s:=format(GetLangStr(633), [ProgramReference]);
        	//subtitles
        	6: s:=format(GetLangStr(634), [ProgramReference]);
        	//audio track
        	7: s:=format(GetLangStr(632), [ProgramReference]);
        	//genre
        	8: s:=format(GetLangStr(313), [ProgramReference]);
        	//country
        	9: s:=format(GetLangStr(314), [ProgramReference]);
        	//location
        	10: s:=format(GetLangStr(569), [ProgramReference]);
			//mpaa
			11: s:=format(GetLangStr(1135), [ProgramReference]);
        	//studio
			12: s:=format(GetLangStr(847)+'%s', [ProgramReference]);
			//custom 1-4
        	13: s:=GetLangStr(540)+': '+ProgramReference;
        	14: s:=GetLangStr(541)+': '+ProgramReference;
        	15: s:=GetLangStr(542)+': '+ProgramReference;
        	16: s:=GetLangStr(543)+': '+ProgramReference;
        	//custom list 1-2
        	17: s:=GetLangStr(544)+': '+ProgramReference;
        	18: s:=GetLangStr(545)+': '+ProgramReference;
        	//video codec
			19: s:=format(GetLangStr(857)+'%s', [ProgramReference]);
			//disc label   // 20090829-JeF
        	20: s:=format(GetLangStr(1001), [ProgramReference]);
			//edition
        	21: s:=format(GetLangStr(1140), [ProgramReference]);
	  else
			s:='';
      end;

	  jListWidth:=GetHTMLWidth-GetIntThmOption('ListOffWidth');
	  movie:=BuildList(sl.Text,'Movie',0,0,jListWidth,jTargetPage,0,3,4);
	  all:=BuildExtraPage(s,'<br>'+movie);
	  
	end;
	sl.Free;
	result:=all;
	jLastPage:=result;
end;


//show movies by selected year
function GetYear(YearCode: integer): string;
begin
	result:=GetYear2(YearCode, 1);
end;

//show movies by selected year
function GetYear2(YearCode, page: integer): string;
begin
	SetIntXFvar(5,'CurPageNbr',1);
	result:=NewGetYear(YearCode);
end;
	
function NewGetYear(YearCode: integer): string;
var
  sl: TStringList;
  i, kol, RecordCount: integer;
  s, description, director, writer, actor, bio, character, movie: string;
  all, FileName, img, y: string;
  jTargetPage, jListWidth, j, k: integer;
begin
	SetIntXFvar(5,'YearCode',YearCode);
	jTargetPage:=GetIntXFvar(5,'CurPageNbr');
	jHomePageCode:='00050'+IntToStr(YearCode)+'000000000';
 
	result:='';
	sl:=TStringList.Create;

	all:='';
	if YearCode>0 then begin
      with sl do begin
        Clear;
        Add('select m.title, m.code, m.year, m.in_collection');
        Add('from movies m');
        Add(format('where m.year=%d', [YearCode]));
        if jInCollection then Add(' and m.in_collection=1 ');
		Add('order by m.year desc, m.title');
      end;
      RecordCount:=ExecuteSQL(sl.text);
      if RecordCount>0 then begin
        movie:='<h1>'+format(GetLangStr(315), [YearCode])+'</h1><ol>';
        for i:=1 to RecordCount do begin
      	if GetIntegerField('m.in_collection')=1 then
					img:=format('<img src="%s" align="absmiddle">', [GetRscPath('movie.gif')])
				else
					img:='';

          y:=GetStringField('m.year');
          if y='' then
            movie:=movie+format('<li>%s<a href="movie:%d">%s</a>',
              [img, GetIntegerField('m.code'), GetStringField('m.title')])
          else
            movie:=movie+format('<li>%s<a href="movie:%d">%s</a> (%s)',
              [img, GetIntegerField('m.code'), GetStringField('m.title'), y]);
          GetNextRecord;
        end;
        movie:=movie+'</ol>';
        all:=all+movie;
	  end;

	  s:=format(GetLangStr(315), [YearCode]);
	  jListWidth:=GetHTMLWidth-GetIntThmOption('ListOffWidth');
	  if ThemeActive then begin
		movie:=BuildList(sl.Text,'Movie',0,0,jListWidth,jTargetPage,0,3,5);
		all:=BuildExtraPage(s,'<br>'+movie);
	  end
	  else begin
		movie:=BuildList(sl.Text,'Movie',0,0,jListWidth,jTargetPage,0,3,5);
		all:='<h1>'+s+'</h1><ol>'+movie+'</ol>';
	  end;

	  year:=IntToStr(YearCode);
	end;
	sl.Free;
	result:=all;
	jLastPage:=result;
end;


// 20090830-JeF
function GetTemplate(Card: string): string;
begin
	if (Card='home') then result:=jHomeCard.text
	else if (Card='movie') then result:=jMovieCard.text
	else if (Card='person') then result:=jPersonCard.text
	else if (Card='list') then result:=jListCard.text
	else if (Card='ThumbMovie') then result:=jThumbjMovieCard.text
	else if (Card='Thumb3Movie') then result:=jThumbjMovie3Card.text
	else if (Card='ThumbPerson') then result:=jThumbjPersonCard.text
	else if (Card='Thumb3Person') then result:=jThumbjPerson3Card.text
	else result:='';
end;

function GetSearchTop: string;   // TODO
begin
//showmessage('SearchTop');
	jSearchBuild:=True;
	jSearchType:='';
	jBuildPage.Clear;
	//result:='<h1>'+GetLangStr(1293)+'</h1>';
	result:='';
end;

function GetSearchBottom: string;   // TODO
var 
	sqlstr: string;
begin
//showmessage('SearchBottom:'+jBuildPage.commatext);
	jSearchBuild:=False;
	sqlstr:='';
	if (jSearchType='movie')
		then sqlstr:='select code, title, year, rating from movies where code in ('+jBuildPage.CommaText+')'
	else if (jSearchType='person') 
		then sqlstr:='select code, name from persons where code in ('+jBuildPage.CommaText+')';
	SetIntXFvar(6,'CurPageNbr',1);
	SetStrXFvar(6,'sql',sqlstr);
	SetStrXFvar(6,'sqldesc',GetLangStr(1293));
	jLastPage:=ExtraFeature(6,'00000000000000');
	result:=jLastPage;
end;

// 20090904-JeF
function ExtraFeature(XFid: integer; XFarg: string): string;
var
	//EFcode, EFcod1, EFcod2, EFval, EFval1, EFval2 : integer;
	XFval12, XFval15, XFval33, XFval64, XFval69, XFval105, jIntOptVal, jThumbMaxWidth, jListWidth: integer;
	LstCode, RecordCount, i, j, k: integer;
	XFidStr, s, s2, jPgTitle, jPgContent, jFileExt: string;
	sl, sl2: TStringList;
begin
//showmessage('Function '+inttostr(XFid)+' ('+XFarg+')');
	sl:=TStringList.create;
	sl2:=TStringList.create;
	XFval12:=StrToInt(copy(XFarg,1,2));
	XFval15:=StrToInt(copy(XFarg,1,5));
	XFval33:=StrToInt(copy(XFarg,3,3));
	XFval64:=StrToInt(copy(XFarg,6,4));
	XFval69:=StrToInt(copy(XFarg,6,9));
	XFval105:=StrToInt(copy(XFarg,10,5));
	XFidStr:=IntToStr(XFid);
	while (length(XFidStr)<4) do XFidStr:='0'+XFidStr;
	
	// Redirections to Standard Feature
	if (XFid=1) then begin
		s:=GetStrOption('HomePageCode');
		if (length(s)=18) and (s<>jHomePageCode) 
			then ExtraFeature(StrToInt(copy(s,1,4)),copy(s,5,14))
		else GetHome;
	end
	else if (XFid=2) then begin
		if (XFval69>0) then SetIntXFvar(2,'MovieCode',XFval69);
		GetMovie(GetIntXFvar(XFid,'MovieCode'),GetIntXFvar(XFid,'season'),GetBoolXFvar(XFid,'FullDesc'));
	end
	else if (XFid=3) then begin
		if (XFval69>0) then SetIntXFvar(3,'PersonCode',XFval69);
		GetPerson(GetIntXFvar(XFid,'PersonCode'),GetBoolXFvar(XFid,'FullBio'),GetBoolXFvar(XFid,'FullDesc'));
	end
	else if (XFid=4) then begin
		if (XFval69=0) 
			then NewGetReference(GetIntXFvar(4,'ReferenceCode'),GetIntXFvar(4,'reference'))
		else begin
			SetIntXFvar(4,'CurPageNbr',1);
			NewGetReference(XFval69,XFval15);
		end;
	end
	else if (XFid=5) then begin
		if (XFval15>0) and (XFval15<10000) then SetIntXFvar(5,'YearCode',XFval15);
		NewGetYear(GetIntXFvar(5,'YearCode'));
	end
	else if (XFid=6) then begin   // Search results
		jListWidth:=GetHTMLWidth-GetIntThmOption('ListOffWidth');
		if (pos('movie',GetStrXFvar(XFid,'sql'))>0) then s:='Movie' else s:='Person';
		jPgContent:='<br>'+BuildList(GetStrXFvar(XFid,'sql'),s,4,0,jListWidth,GetIntXFvar(XFid,'CurPageNbr'),9999,0,XFid);
		jLastPage:=BuildExtraPage(GetStrXFvar(XFid,'sqldesc'),jPgContent);
	end
	
	else if (XFid>=51) and (XFid<=200)					// Core Lists
	     or (XFid>=9001) and (XFid<=9900) then begin	// Extended Core Lists (internal)
		jHomePageCode:=XFidStr+'00000000000000';
		jListWidth:=GetHTMLWidth-GetIntThmOption('ListOffWidth');
		if (XFid=51) then begin   // CoreList : Most Recently Added Movies
			jPgContent:='<br>'+BuildList(GetStrXFvar(XFid,'sql'),'Movie',0,0,jListWidth,GetIntXFvar(XFid,'CurPageNbr'),0,3,XFid);
			jLastPage:=BuildExtraPage(GetLangStr(98),jPgContent);
		end
		else if (XFid=52) then begin   // CoreList : Most Recently Updated Movies
			jPgContent:='<br>'+BuildList(GetStrXFvar(XFid,'sql'),'Movie',0,0,jListWidth,GetIntXFvar(XFid,'CurPageNbr'),0,3,XFid);
			jLastPage:=BuildExtraPage(GetLangStr(99),jPgContent);
		end
		else if (XFid=53) then begin   // CoreList : Most Recently Added Persons
			jPgContent:='<br>'+BuildList(GetStrXFvar(XFid,'sql'),'Person',0,0,jListWidth,GetIntXFvar(XFid,'CurPageNbr'),0,3,XFid);
			jLastPage:=BuildExtraPage(GetLangStr(100),jPgContent);
		end
		else if (XFid=54) then begin   // CoreList : Most Recently Updated Persons
			jPgContent:='<br>'+BuildList(GetStrXFvar(XFid,'sql'),'Person',0,0,jListWidth,GetIntXFvar(XFid,'CurPageNbr'),0,3,XFid);
			jLastPage:=BuildExtraPage(GetLangStr(101),jPgContent);
		end
		else if (XFid=55) then begin   // CoreList : Wanted Movies by Most recent Add date
			jPgContent:='<br>'+BuildList(GetStrXFvar(XFid,'sql'),'Movie',0,0,jListWidth,GetIntXFvar(XFid,'CurPageNbr'),0,3,XFid);
			jLastPage:=BuildExtraPage(GetLangStr(814),jPgContent);
		end
		else if (XFid=56) then begin   // CoreList : Movies by disc number (coming from a source edition)
			s:='select disc_nom from editions where code='+IntToStr(XFval69);
			RecordCount:=ExecuteSQL(s);
			if RecordCount>0 then begin
				s:=GetStringField('disc_nom');
				SetStrXFvar(XFid,'sqlvar1',s);
				jPgContent:='<br>'+BuildList(GetStrXFvar(XFid,'sql'),'Movie',0,0,jListWidth,GetIntXFvar(XFid,'CurPageNbr'),0,3,XFid);
				jLastPage:=BuildExtraPage(Format(GetLangStr(1141),[s]),jPgContent);
			end;
		end
		else begin
			if (XFid=9002) and (XFval69=2) then LoadMovieList;   // Load Movie List  //20101224-JeF
			if (XFid=9003) and (XFval69=2) then LoadPersonList;   // Load Person List  //20101224-JeF
			if (jSqlStrings.IndexOfName('M'+XFidStr)<>-1) then s:='Movie'
			else if (jSqlStrings.IndexOfName('P'+XFidStr)<>-1) then s:='Person'
			else if (GetStrXFvar(XFid,'ListType')<>'') then s:=GetStrXFvar(XFid,'ListType')
			else s:='Custom';
			if (pos('INSERT',UpperCase(GetStrXFvar(XFid,'sql')))>0)
			or (pos('UPDATE',UpperCase(GetStrXFvar(XFid,'sql')))>0)
			or (pos('DELETE',UpperCase(GetStrXFvar(XFid,'sql')))>0)
				then s:='Custom';
			if (s='Custom') then ExeCustomSql(GetStrXFvar(XFid,'sql'),XFid)
			else begin
				jPgContent:='<br>'+BuildList(GetStrXFvar(XFid,'sql'),s,0,0,jListWidth,GetIntXFvar(XFid,'CurPageNbr'),0,3,XFid);
				jLastPage:=BuildExtraPage(GetStrXFvar(XFid,'sqldesc'),jPgContent);
			end;
		end;
	end
	else if (XFid=201) then begin
		if (XFval69<=1) then BuildScriptSettingsPage
		else if (XFval69=2) then ShowOptionsDialog;
		//else if (XFval69=3) then ShowDwnScrOptDialog('imdb');  // **obsolete**
	end
	else if (XFid=202) then begin
		SetTheme(GetStrOption('Theme'));
		jHomePageCode:=GetStrOption('HomePageCode');
		if (length(jHomePageCode)=18) 
			then jLastPage:=ExtraFeature(StrToInt(copy(jHomePageCode,1,4)),copy(jHomePageCode,5,14))
		else GetHome;
	end
	else if (XFid=203) then begin
		if (XFval69=999) then begin
			if (jThemes.IndexOf(GetStrOption('Theme'))>=jThemes.Count-1) 
				then SetTheme('Original')
			else SetTheme(jThemes[jThemes.IndexOf(GetStrOption('Theme'))+1]);
		end
		else SetTheme(jThemes[XFval69-1]);
		BuildScriptSettingsPage;
	end
	else if (XFid=204) then begin
		LoadOptions;
		jHomePageCode:=GetStrOption('HomePageCode');
		if (length(jHomePageCode)=18) 
			then ExtraFeature(StrToInt(copy(jHomePageCode,1,4)),copy(jHomePageCode,5,14))
		else GetHome;
	end
	else if (XFid=205) then begin
		if (XFval69=2) and GetBoolOption('LastAddUpdThumbs')
		or (XFval69=6) and NOT GetBoolOption('LastAddUpdThumbs') then begin
			SetBoolOption('LastAddUpdThumbs',NOT GetBoolOption('LastAddUpdThumbs'));
		end;
		GetHome;
	end
	else if (XFid=210) then begin
		if (XFval15=0) then BuildDbToolBoxPage
		else if (XFval15=1) then begin   // Reload Sql Strings
			LoadSqlStrings;
			BuildDbToolBoxPage;
		end
		else if (XFval15=2) then begin   // **obsolete** Export IMDB Ids
		end
		else if (XFval15=3) then begin   // Check Multimedia Files Path
			jHomePageCode:='021000003000000000';
			BuildMainNavBar(XFid,'111111111111');
			s2:=GetStrOption('FilePathCheckExcept');
			if (XFval69=1) and InputQuery(GetLangStr(1144),GetLangStr(1145),s2) then begin
				if (s2>'') then begin
					if (s2<>GetStrOption('FilePathCheckExcept')) then begin
						SetStrOption('FilePathCheckExcept',s2);
					end;
					sl.CommaText:=s2;
					for i:=0 to sl.count-1 do sl[i]:='or filename like '''+sl[i]+'%%'' ';
					delete(sl.text,1,2);
					s2:='and e.code not in (select code from editions where '+sl.text+')';
				end;
				s:='select m.code, m.title, e.filename from movies m ' + 
				   'left outer join editions e on e.movie=m.code where e.filename>'''' ' +
				   s2+' order by e.filename';
				RecordCount:=ExecuteSQL(s);
				sl.clear;
				for i:=1 to RecordCount do begin
					s2:=GetstringField('e.filename');
					if NOT (MyFileExists(s2)) then begin
						s2:=format('<li><a href="UpdateMovie:%d">', [GetIntegerField('m.code')]) +
							'<img src="'+GetRscPath('Movie.gif')+'" width="22" border="0" align="absmiddle" ' +
							'alt="'+ClearExtraSDQuotes(GetstringField('m.title'))+'"></a>&nbsp;'+s2;
						sl.Add(s2);
					end;
					GetNextRecord;
				end;
				if (sl.count>0) then begin
					sl.text:='<br><ol>'+sl.text+'</ol>';
				end;
				jLastPage:=BuildExtraPage(GetLangStr(1143),sl.text);
			end;
		end
		else if (XFval15=4) then begin   // Multimedia Files not in collection (from a text file list)
			s2:=GetStrOption('LastFileList');
			s2:=PromptForPath(GetLangStr(1149),s2,s2,GetLangStr(1150)+'|*.*',1,1);
			if (s2>'') then begin
				if MyFileExists(s2) then begin
					if (s2<>GetStrOption('LastFileList')) then begin
						SetStrOption('LastFileList',s2);
					end;
					sl.LoadFromFile(s2);
					i:=1;
					jFileExt:=Uppercase(ClearExtraSDQuotes(GetStrOption('IgnoreFileExt')));
					while (i<=sl.count) do begin
						if (length(sl[i-1]) < 6)
							then s:=UpperCase(sl[i-1])
						else s:=UpperCase(copy(sl[i-1],length(sl[i-1])-5,6));
						if (pos('.',s)>0) then while (s[1]<>'.') and (s>'') do delete(s,1,1);
						if (InList(s,jFileExt))  	// '.TXT,.NFO,.ASX,.BAT,.DB' 
						or (pos('.',s)=0) then begin
							sl.Delete(i-1);
							continue;
						end;
						sl[i-1]:=AsciiToAnsi(sl[i-1]);
						i:=i+1;
					end;
					sl.Sort;
					sl.SaveToFile(s2);
					for i:=1 to sl.Count do begin
						s:=ClearExtraSDQuotes(sl[i-1]);
						s2:='select filename from editions where filename = "'+s+'" limit 1;';
						RecordCount:=ExecuteSQL(s2);
						if (RecordCount>0) then sl[i-1]:=''
						else begin
							s2:=s;
							while (length(s2)>0) and (s2[length(s2)]<>'/') and (s2[length(s2)]<>'\') 
								do delete(s2,length(s2),1);
							sl[i-1]:='<li><a href="link:file://'+s2+'">'
									+'<img src="'+GetRscPath('Folder.png')+'" align="absmiddle" height=18 '
									+'alt="'+s2+'" border=0></a>&nbsp;'
									+'<a href="link:file://'+s+'">'+s+'</a>';
						end;
					end;
					sl.text:='<br><ol>'+sl.text+'</ol>';
					jLastPage:=BuildExtraPage(GetLangStr(1149),sl.text);
				end
				else showmessage(format(GetLangStr(1041),[s]));
			end;
		end;
	end
	else if (XFid=211) then begin
		s2:='select count(*) from editions ';
		RecordCount:=ExecuteSQL(s2);
		SetIntXFvar(XFid,'EdCount',GetIntegerField('count(*)'));
		s2:='select count(*) from editions where disc_nom is null or disc_nom = '''' ';
		RecordCount:=ExecuteSQL(s2);
		SetIntXFvar(XFid,'NoDiskCount',GetIntegerField('count(*)'));
		if (XFval15=0) then begin
			if (GetIntXFvar(XFid,'NoDiskCount')=0) then begin
				s2:=GetLangStr(1151);
				showmessage(s2);
				XFval15:=-1;
			end
			else begin
				s2:=GetLangStr(1152)
					+format(' %d editions',[GetIntXFvar(XFid,'NoDiskCount')])
					+#13#10+GetLangStr(1153);
				i:=MessageDlg(s2,mtCustom,mbYes+mbCancel, 0);
				if (i=mrCancel) then XFval15:=-1;
			end;
		end;
		if (XFval15<=4) then begin
			k:=0;
			sl2.clear;
			SetIntXFvar(XFid,'NumDiskCount',0);
			SetIntXFvar(XFid,'CharDiskCount',0);
			SetIntXFvar(XFid,'DiskCount',0);
			SetIntXFvar(XFid,'HighestDisk',0);
			SetStrXFvar(9001,'sql','nothing');
			s2:='select code, disc_nom from editions where disc_nom is not null and disc_nom > '''' ';
			RecordCount:=ExecuteSQL(s2);
			if (RecordCount>0) then begin
				for i:=1 to RecordCount do begin
					s2:=GetStringField('disc_nom');
					j:=StrToIntDef(s2,-1);
					if (j=-1) then begin
						sl2.Add(IntToStr(GetIntegerField('code')));
						SetIntXFvar(XFid,'CharDiskCount',GetIntXFvar(XFid,'CharDiskCount')+1);
					end
					else begin
						SetIntXFvar(XFid,'NumDiskCount',GetIntXFvar(XFid,'NumDiskCount')+1);
						if (j>k) then k:=j;
						sl.Add(format('%.4d=%d',[j,GetIntegerField('code')]));
					end;
					GetNextRecord;
				end;
				sl.Sort;
				SetIntXFvar(XFid,'DiskCount',GetIntXFvar(XFid,'CharDiskCount')+GetIntXFvar(XFid,'NumDiskCount'));
				SetIntXFvar(XFid,'HighestDisk',k);
				if (sl2.Count>0) then begin
					sl2.Text:='select m.code, m.title, m.year, m.rating, e.code from movies m '
							+'inner join editions e on e.movie=m.code where e.code in ('
							+sl2.CommaText
							+') order by e.disc_nom, m.code';
					SetStrXFvar(9001,'sql',sl2.Text);
				end;
				sl2.Clear;
				if (sl.Count>0) then begin
					for i:=1 to StrToIntDef(sl.Names[sl.Count-1],0) do begin
						s2:=format('%.4d',[i]);
						if (sl.IndexOfName(s2)=-1) 
							then sl2.Add(s2);
					end;
				end;
				SetStrXFvar(XFid,'Gaps',sl2.CommaText);
			end;
		end;
		if (XFval15=0) then begin
			sl.Clear;
			s2:='select code from editions where disc_nom is null or disc_nom = '''' ';
			RecordCount:=ExecuteSQL(s2);
			for i:=1 to RecordCount do begin
				sl.Add(IntToStr(GetIntegerField('code')));
				GetNextRecord;
			end;
			if (GetIntOption('DiscAutoNbrToolGapsMode')>1) then sl2.Clear;
			for i:=1 to sl.Count do begin
				if (sl2.Count>0) then begin
					sl[i-1]:=sl[i-1]+'='+sl2[0];
					sl2.Delete(0);
				end
				else begin
					k:=k+1;
					sl[i-1]:=sl[i-1]+'='+format('%.4d',[k]);
				end;
			end;
			for i:=1 to sl.Count do begin
				s:=sl.Names[i-1];
				s2:=format('update editions set disc_nom=''%s'' ',[sl.Values[s]])
					+format('where code=%s',[s]);
				RecordCount:=ExecuteSQL(s2);
			end;
			sl2.Clear;
			s2:='select m.code, m.title, m.year, m.rating, e.disc_nom, e.sort_order from movies m '
				+'inner join editions e on e.movie=m.code '
				+'where e.code in ('
				+sl.CommaText
				+') order by e.disc_nom, m.code';
			RecordCount:=ExecuteSQL(s2);
			for i:=1 to RecordCount do begin
				s:=sl.Names[i-1];
				s2:='<li>'+GetLangStr(391)+GetStringField('e.disc_nom')+' : '
					+format('<a href="movie:%d#%d">%d</a>',[GetIntegerField('m.code'),GetStringField('m.title')])
					+format(GetLangStr(1260),[GetIntegerField('e.sort_order')]);
				sl2.Add(s2);
			end;
			sl2.text:='<br><ol>'+sl2.text+'</ol>';
			jLastPage:=BuildExtraPage(GetLangStr(1154),sl2.text);
		end;
		if (XFval15=1) then begin  // List gaps
			if (sl2.Count=0) then showmessage(GetLangStr(1155))
			else begin
				s2:=ReplaceStr(sl2.CommaText,',',', ');
				s2:=GetLangStr(1156) +' :'+#13#10+#13#10+s2;
				showmessage(s2);
			end;
		end
		else if (XFval15=2) then begin  // List movies with non numeric Disk#
			if (GetStrXFvar(9001,'sql')='nothing') then showmessage(GetLangStr(1157))
			else begin
				SetStrXFvar(9001,'sqldesc',GetLangStr(1158));
				SetStrXFvar(9001,'ListType','Movie');
				SetIntXFvar(9001,'CurPageNbr',1);
				ExtraFeature(9001,'00000000000000');
			end;
		end
		else if (XFval15=3) then // nothing : just to set vars
		else if (XFval15=4) then begin  // Display counts
			SetDlgValue('TBD1_EdCount',GetStrXFvar(XFid,'EdCount'));
			SetDlgValue('TBD1_NoDiskCount',GetStrXFvar(XFid,'NoDiskCount'));
			SetDlgValue('TBD1_CharDiskCount',GetStrXFvar(XFid,'CharDiskCount'));
			SetDlgValue('TBD1_NumDiskCount',GetStrXFvar(XFid,'NumDiskCount'));
			SetDlgValue('TBD1_DiskCount',GetStrXFvar(XFid,'DiskCount'));
			SetDlgValue('TBD1_HighestDisk',GetStrXFvar(XFid,'HighestDisk'));
			ShowDialog('ToolBox_1');
		end
		else if (XFval15=5) then begin  // Toggle gaps mode
			SetStrOption('DiscAutoNbrToolGapsMode',IntToStr(3-GetIntOption('DiscAutoNbrToolGapsMode')));
			BuildDbToolBoxPage;
		end
		else if (XFval15=9) then begin  // Raz all Disk#
			s2:=#13#10+GetLangStr(1165);
			i:=MessageDlg(s2,mtWarning,mbOk+mbCancel, 0);
			if (i=mrOk) then begin
				s2:='update editions set disc_nom=null ';
				RecordCount:=ExecuteSQL(s2);
				showmessage(GetLangStr(1166));
			end;
		end;
	end
	else if (XFid=212) then begin  // filename renamer
		FileRenamer;
	end
	else if (XFid=213) then begin  
		if (GetStrXFvar(XFid,'PgContent')>'') then begin
			jHomePageCode:='0';
			BuildMainNavBar(213,'000000000000');
			if (XFval15>0) 
				then s2:=format('<a href="custom%.4d00000:1">',[XFval15])
			else s2:='<a href="command:back">';
			s:=s2+'<img src="'+GetRscPath('Backward.png')
				+'" border="0" align="absmiddle" '
				+'alt="'+GetLangStr(24)+'"></a><br>'
				+GetStrXFvar(XFid,'PgContent')
				+s2+'<img src="'+GetRscPath('Backward.png')
				+'" border="0" align="absmiddle" '
				+'alt="'+GetLangStr(24)+'"></a><br>';
			jLastPage:=BuildExtraPage(GetStrXFvar(XFid,'PgTitle'),s);
		end;
	end
	else if (XFid=214) then begin  // manuals renamer
		ManualsRenamer(XFval15);
	end

	else if (XFid=220) then begin   // Build Episodes List
		BuildEpisodesList(XFval69,XFval15);
	end
	
		
	else if (XFid=301) then begin
		if (GetIntXFvar(XFid,'CurPageNbr')<1) then SetIntXFvar(XFid,'CurPageNbr',1);
		GetMoviesHome;
	end
	else if (XFid=302) then begin
		if (GetIntXFvar(XFid,'CurPageNbr')<1) then SetIntXFvar(XFid,'CurPageNbr',1);
		GetPersonsHome;
	end


	else if (XFid=1001) then begin   // Home Page Featured DVD Toggle Icon select
		SetBoolOption('ShowFeaturedDVD',NOT GetBoolOption('ShowFeaturedDVD'));
		GetHome;
	end
	
	else if (XFid=1003) then begin   // MainBar SetAsHomePage Icon select
		SetStrOption('HomePageCode',jHomePageCode);
		if (jHomePageCode='0') 
			then GetHome
		else begin
			jLastPage:=ReplaceStr(jLastPage,'HomeBlue.png','HomeOrange.png');
			i:=pos('<a href="custom100300000:1">',jLastPage);
			if (i>0) then begin
				j:=MyPos('</a>&nbsp;',jLastPage,i+1);
				if (j>0) then delete(jLastPage,i,j-i+10);
			end;
		end;
	end
	else if (XFid=1004) then begin   // MainBar ToolbarToggle Icon select
		SetBoolOption('ToolbarVisibility',NOT GetBoolOption('ToolbarVisibility'));
		SetToolbarVisibility(GetBoolOption('ToolbarVisibility'));
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1005) then begin   // MainBar MenuBarToggle Icon select
		SetBoolOption('MenuVisibility',NOT GetBoolOption('MenuVisibility'));
		SetMenuVisibility(GetBoolOption('MenuVisibility'));
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1006) then begin   // MainBar SideBarToggle Icon select
		SetBoolOption('NavigationVisibility',NOT GetBoolOption('NavigationVisibility'));
		SetNavigationVisibility(GetBoolOption('NavigationVisibility'));
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1007) then begin   // MainBar FullScreenToggle Icon select
		if GetBoolOption('MenuVisibility')
		or GetBoolOption('ToolbarVisibility')
		or GetBoolOption('NavigationVisibility') then begin
			SetBoolOption('ToolbarVisibility',False);
			SetBoolOption('MenuVisibility',False);
			SetBoolOption('NavigationVisibility',False);
		end
		else begin
			SetBoolOption('ToolbarVisibility',True);
			SetBoolOption('MenuVisibility',True);
			SetBoolOption('NavigationVisibility',True);
		end;
		SetMenuVisibility(GetBoolOption('MenuVisibility'));
		SetToolbarVisibility(GetBoolOption('ToolbarVisibility'));
		SetNavigationVisibility(GetBoolOption('NavigationVisibility'));
		ExtraFeature(XFval69,'00000000000000');
	end

	
	else if (XFid=1011) then begin   // ListBar InCollection Icon Toggle
		SetBoolOption('InCollection',NOT jInCollection);
		jInCollection:=GetBoolOption('InCollection');
		s:=GetStrXFvar(XFval69,'sql');
		if jInCollection 
			then s:=ReplaceStr(s,'in_collection>=0 ','in_collection=1 ')
		else s:=ReplaceStr(s,'in_collection=1 ','in_collection>=0 ');
		SetStrXFvar(XFval69,'sql',s);
		SetIntXFvar(XFval69,'CurPageNbr',1);
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1012) then begin   // ListBar Refresh Icon select
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1013) then begin   // ListBar First Icon select
		SetIntXFvar(XFval69,'CurPageNbr',1);
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1014) then begin   // ListBar Prev Icon select
		if (GetIntXFvar(XFval69,'CurPageNbr')>1) 
			then SetIntXFvar(XFval69,'CurPageNbr',GetIntXFvar(XFval69,'CurPageNbr')-1);
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1015) then begin   // ListBar Next Icon select
		if (GetIntXFvar(XFval69,'CurPageNbr')<GetIntXFvar(XFval69,'LastPageNbr'))
			then SetIntXFvar(XFval69,'CurPageNbr',GetIntXFvar(XFval69,'CurPageNbr')+1);
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1016) then begin   // ListBar Last Icon select
		if (GetIntXFvar(XFval69,'LastPageNbr')>0) then SetIntXFvar(XFval69,'CurPageNbr',GetIntXFvar(XFval69,'LastPageNbr'));
		ExtraFeature(XFval69,'00000000000000');
	end
	else if (XFid=1017) then begin   // ListBar PageNumber Icon select
		if (XFval69>0) then SetIntXFvar(XFval15,'CurPageNbr',XFval69);
		ExtraFeature(XFval15,'00000000000000');
	end
	else if (XFid=1018) then begin   // ListBar TextFace/FullFace/ThumbFace Icons select
		jIntOptVal:=GetIntOption('ListFace');
		if (jIntOptVal<>XFval69) then begin
			// Recalculate TargetPageNumber
			if (jIntOptVal<=2 ) then i:=GetIntOption('TextListMaxItems')*(GetIntXFvar(XFval15,'CurPageNbr')-1)+1
			else if (jIntOptVal<=4 ) then i:=GetIntOption('RichListMaxItems')*(GetIntXFvar(XFval15,'CurPageNbr')-1)+1
			else if (jIntOptVal<=6 ) then i:=GetIntOption('ThumbListMaxItems')*(GetIntXFvar(XFval15,'CurPageNbr')-1)+1
			else i:=1;
			if (XFval69<=2 ) then j:=GetIntOption('TextListMaxItems')
			else if (XFval69<=4 ) then j:=GetIntOption('RichListMaxItems')
			else if (XFval69<=6 ) then j:=GetIntOption('ThumbListMaxItems')
			else j:=1;
			if ((i mod j)=0) then i:=trunc(i/j) else i:=trunc(i/j)+1;
			SetIntXFvar(XFval15,'CurPageNbr',i);
			// Save new Face selection
			SetStrOption('ListFace',IntToStr(XFval69));
		end;
		ExtraFeature(XFval15,'00000000000000');
	end
	else if (XFid=1019) then begin   // ListBar ZoomIn/ZoomOut Icon select
		jIntOptVal:=GetIntOption('ListThumbsWidth');
		jThumbMaxWidth:=(GetHTMLWidth-300) div 2;
		if (XFval69=1) and (jIntOptVal<jThumbMaxWidth) then begin // ZoomIn
			jIntOptVal:=jIntOptVal+20;
			if (jIntOptVal>jThumbMaxWidth) then jIntOptVal:=jThumbMaxWidth;
			SetStrOption('ListThumbsWidth',IntToStr(jIntOptVal));
		end
		else if (XFval69=2) and (jIntOptVal>80) then begin // ZoomOut
			jIntOptVal:=jIntOptVal-20;
			if (jIntOptVal<80) then jIntOptVal:=80;
			SetStrOption('ListThumbsWidth',IntToStr(jIntOptVal));
		end;
		ExtraFeature(XFval15,'00000000000000');
	end
	else if (XFid=1020) then begin   // ListBar SqlOrder Toggle Icon select : Year / Alphabetical
		if (XFval15=4) then begin
			jIntOptVal:=GetIntOption('ByManualsListOrder');
			SetStrOption('ByManualsListOrder',IntToStr(1-jIntOptVal));
			SetIntXFvar(4,'CurPageNbr',1);
			NewGetReference(GetIntXFvar(4,'ReferenceCode'),GetIntXFvar(4,'reference'));
		end;
	end

	else if (XFid=1031) then begin   // MoviesHome GenreListFaceToggle Icon select
		SetStrOption('MHomeGListState',IntToStr(1-GetIntOption('MHomeGListState')));
		GetMoviesHome;
	end
	else if (XFid=1032) then begin   // MoviesHome FilterReset Icon select
		s:=format(jSqlStrings.Values['C0301'],[IntToStr(XFval69)]);
		if NOT jInCollection then s:=ReplaceStr(s,'in_collection=1 ','in_collection>=0 ');
		SetStrXFvar(301,'sql',s);
		SetIntXFvar(301,'CurPageNbr',1);
		if (GetIntOption('GenreAutoCollapse')>=4) and (GetIntOption('MHomeGListState')>0) then begin 
			SetStrOption('MHomeGListState','0');
		end;
		GetMoviesHome;
	end
	else if (XFid=1033) then begin   // MoviesHome GenreListItem Icon select
		s:='select * from manuals where code='+IntToStr(XFval69)+' and reference=8';
		RecordCount:=ExecuteSQL(s);
		//if RecordCount>0 then SetStrXFvar(301,'sqldesc',format(GetLangStr(313),[GetStringField('name')])) 
		//else GetStrXFvar(301,'sqldesc'):='';
		s:=format(jSqlStrings.Values['C0301-g'],[IntToStr(XFval69)]);
		if NOT jInCollection then s:=ReplaceStr(s,'in_collection=1 ','in_collection>=0 ');
		SetStrXFvar(301,'sql',s);
		SetIntXFvar(301,'CurPageNbr',1);
		if (GetIntOption('GenreAutoCollapse') in [1,3,5,7]) and (GetIntOption('MHomeGListState')>0) then begin 
			SetStrOption('MHomeGListState','0');
		end;
		GetMoviesHome;
	end
	else if (XFid=1034) then begin   // MoviesHome AlphabetListItem Icon select
		s:=format(jSqlStrings.Values['C0301-a'],[chr(XFval69)]);
		if NOT jInCollection then s:=ReplaceStr(s,'in_collection=1 ','in_collection>=0 ');
		SetStrXFvar(301,'sql',s);
		SetIntXFvar(301,'CurPageNbr',1);
		if (GetIntOption('GenreAutoCollapse') in [2,3,6,7]) and (GetIntOption('MHomeGListState')>0) then begin 
			SetStrOption('MHomeGListState','0');
		end;
		GetMoviesHome;
	end

	else if (XFid=1051) then begin   // PersonsHome FilterReset Icon select
		s:=format(jSqlStrings.Values['C0302'],[IntToStr(XFval69)]);
		if NOT jInCollection then s:=ReplaceStr(s,'in_collection=1 ','in_collection>=0 ');
		SetStrXFvar(302,'sql',s);
		SetIntXFvar(302,'CurPageNbr',1);
		GetPersonsHome;
	end
	else if (XFid=1052) then begin   // PersonsHome AlphabetListItem Icon select
		s:=format(jSqlStrings.Values['C0302-a'],[chr(XFval69),chr(XFval69)]);
		if NOT jInCollection then s:=ReplaceStr(s,'in_collection=1 ','in_collection>=0 ');
		SetStrXFvar(302,'sql',s);
		SetIntXFvar(302,'CurPageNbr',1);
		GetPersonsHome;
	end

	else if (XFid=1101) then begin   // Explandable/Collapsable Blocks State toggle
		i:=(XFval15) div 10;
		j:=XFval15 mod 10;
		if (i<9999) then s:=format('TB%.4d',[i])
		else s:=format('TBS%.5dE%.4d',[XFval69 div 10000,XFval69 mod 10000]);
		if (j=1) then begin
			jLastPage:=BlockTag(jLastPage,s+'-','show');
			jLastPage:=BlockTag(jLastPage,s+'+','hide');
		end
		else if (j=0) then begin
			jLastPage:=BlockTag(jLastPage,s+'-','hide');
			jLastPage:=BlockTag(jLastPage,s+'+','show');
		end;
		if (i=1) then begin
			SetStrOption('NavBarState',IntToStr(1-GetIntOption('NavBarState')));
		end;
		
		//Begin of Temporary redirection work around
		if (i>1) then begin
			if (pos('<a class=Jump',jLastPage)=0) then begin
				s2:=BlockTag('','TB0001+','tag-s');
				delete(s2,length(s2),1);
				jLastPage:=ReplaceStr(jLastPage,s2,'<a class=Jump></a>'+s2);
			end;
			i:=pos('<a class=Jump',jLastPage);
			if (i>0) then begin
				j:=MyPos('</a>',jLastPage,i)+3;
				delete(jLastPage,i,j-i+1);
				s2:='<a class=Jump href="#'+s+'">'
					+'<img src="'+GetRscPath('toggle-down-g.png')
					+'" border="0" align="absmiddle"></a> ';
				insert(s2,jLastPage,i);
			end;
		end;
		//End of Temporary redirection work around
	end

	
	else if (XFid=9999) then  // Nothing : just return again jLastPage
	else begin
		showmessage('Unimplemented Function '+IntToStr(XFid)+' ('+XFarg+')');
	end;
	sl.free;
	sl2.free;
	result:=jLastPage;
end;

// 20090904-JeF
procedure BuildDbToolBoxPage;
var
	id, s, s2, s3: string;
	i, j, k: integer;
begin
	jHomePageCode:='021000000000000000';
	s:='<div class="ToolBox"><ol>'
		+'<li><a href="link:'+ScriptsPath+script_name+'_program_sql.ini"><img src="'+GetRscPath('ScriptEdit.png')+'" border="0" height="18" align="absmiddle" '
			+'alt="'+ScriptsPath+script_name+'_program_sql.ini"></a>&nbsp;'
			+'<a href="link:'+ScriptsPath+Script_Name+'_program_sql.ini">'
			+GetLangStr(1114)+' ('+GetLangStr(1115)+')</a>'
		+'<li><a href="custom021000000:1"><img src="'+GetRscPath('RefreshGreen.png')+'" border="0" height="18" align="absmiddle"></a>&nbsp;'
			+'<a href="custom021000001:1">'+GetLangStr(1118)+'</a>';

	// Numbering Tool
	s:=s+'</ol><h2>'+GetLangStr(1167)+'</h2><ol>';
	s:=s+'<li><a href="custom021100004:000000001">'+GetLangStr(1168)+'</a>'
		+'<li><a href="custom021100005:000000001">'+format(GetLangStr(1608),[UpperCase(GetLangStr(1608+GetIntOption('DiscAutoNbrToolGapsMode')))])+'</a>'
		+'<li><a href="custom021100000:000000001">'+GetLangStr(1169)+'</a>'
		+'<li><a href="custom021100001:000000001">'+GetLangStr(1156)+'</a>'
		+'<li><a href="custom021100002:000000001">'+GetLangStr(1158)+'</a>'
		+'<li><a href="custom021100009:000000001">'+GetLangStr(1170)+'</a>';

	// Attributes (Manuals) Renamer
	s:=s+'</ol><h2>'+GetLangStr(1193)+'</h2><ol>';
	s:=s+'<li>';
	s2:=ScriptsPath+'JeF_attributes_renamer.csv';
	s3:=jOriginalThemePath+'JeF_attributes_renamer-dft.csv';
	if NOT MyFileExists(s2) and MyFileExists(s3) 
		then CopyTextFile(s3,s2);
	if NOT MyFileExists(s2) 
		then s2:='<a href="custom021400000:000000001">'
	else s2:='<a href="link:'+ScriptsPath+'JeF_attributes_renamer.csv">';
	s:=s+s2+GetLangStr(1197)+'</a>'
		+'<li><a href="custom021400000:000000001">'+GetLangStr(1198)+'</a>'
		+'<li><a href="custom021400001:000000001">'+GetLangStr(1199)+'</a>';
		
	// Filenames Tools
	s:=s+'</ol><h2>'+GetLangStr(1188)+'</h2><ol>';
	s:=s+'<li><a href="custom021000003:000000001">'+GetLangStr(1142)+'</a>'
		+'<li><a href="custom021000004:000000001">'+GetLangStr(1149)+'</a>'
		+'<li><a href="custom021200000:000000001">'+GetLangStr(1174)+'</a>';
		
	// Movies Lists
	s:=s+'</ol><h2>'+GetLangStr(1110)+'</h1><ol>';
	for i:=51 to 200 do begin
		id:=IntToStr(i);
		while (length(id)<4) do id:='0'+id;
		if (jSqlStrings.IndexOfName('M'+id)<>-1) then begin
			s:=s+'<li><a href="custom'+id+'00001:1">'+GetStrXFvar(i,'sqldesc')+'</a>';
		end;
	end;
	// Persons Lists
	s:=s+'</ol><h2>'+GetLangStr(1111)+'</h1><ol>';
	for i:=51 to 200 do begin
		id:=IntToStr(i);
		while (length(id)<4) do id:='0'+id;
		if (jSqlStrings.IndexOfName('P'+id)<>-1) then begin
			s:=s+'<li><a href="custom'+id+'00001:1">'+GetStrXFvar(i,'sqldesc')+'</a>';
		end;
	end;
	// Other Lists
	s:=s+'</ol><h2>'+GetLangStr(1600)+'</h1><ol>'
		+'<li><a href="link:'+ScriptsPath+'JeF_Sql_Result.csv">'
			+'<img src="'+GetRscPath('ScriptEdit.png')+'" border="0" height="18" align="absmiddle" '
			+'alt="'+ScriptsPath+'JeF_Sql_Result.csv"></a>&nbsp;'
			+'<a href="link:'+ScriptsPath+'JeF_Sql_Result.csv" alt="'
			+ScriptsPath+'JeF_Sql_Result.csv">'
			+GetLangStr(1108)+'&nbsp;(JeF_Sql_Result.csv)</a>';
	for i:=51 to 200 do begin
		id:=IntToStr(i);
		while (length(id)<4) do id:='0'+id;
		if (jSqlStrings.IndexOfName('Z'+id)<>-1) then begin
			s:=s+'<li><a href="custom'+id+'00001:1">'+GetStrXFvar(i,'sqldesc')+'</a>';
		end;
	end;

	// Miscellaneous (Other Tools) : temporary disabled untill at least one other tool rises...
//	s:=s+'</ol><h2>'+GetLangStr(1189)+'</h1><ol>'
//		;

	s:=s+'</ol></div><br>';
	BuildMainNavBar(210,'111111111111');
	jLastPage:=BuildExtraPage(GetLangStr(1104),s);
end;

function BuildMovieListItem(MovieCode, EditionCode, ItemFace, ItemNbr, LastItemNbr, LetterWidth, ThumbWidth, ListWidth, XFid: integer): string;
var
	jSeen, jWanted, jRating, jDirLstLen, jActLstLen, RecordCount, i, j: integer;
	jTitle, jYear, jSeenIcon, jWantedIcon, jAge, jRate, jVideoFileName, jThumbPath, jDiskNbr, jName, s, sql, img: string;
	jGenres, jDirectors, jActors, jSeasons, jFirstAirYear, jLastAirYear: string;
	jExpLstTag: string;   // 20100907-JeF
begin
	s:='';
	jAge:='';
	jRate:='';
	jGenres:='';
	jDirectors:='';
	jActors:='';
	jExpLstTag:='';   // 20100907-JeF
	if (LetterWidth<10) then LetterWidth:=10;
	sql:='select * from movies '+format('where code=%d', [MovieCode]);
		
	RecordCount:=ExecuteSQL(sql);
	if RecordCount>0 then begin

		jTitle:=GetStringField('title');
		jYear:=GetStringField('year');
		jSeen:=GetIntegerField('seen');
		jWanted:=GetIntegerField('wanted');

		if (jYear>'') then jYear:=format(' (<a href="year:%s">%s</a>)',[jYear,jYear]);
		s:=GetStrXFvar(XFid,'StartDate');
		if (s>'') then begin
			i:=StrToIntDef(GetStringField('year'),0);
			if (i>0) then i:=GetAge(s,DateToStr(EncodeDate(i,06,30)));
			if (i>0) then jAge:='('+IntToStr(i)+')';
		end;
		jRating:=GetIntegerField('rating');
		if jRating>0 then jRate:=format(' <img src="%s" width=16 height=16 border=0 align="absmiddle">%d', [GetRscPath('BarUnit-On.gif'), jRating]);
		if jSeen=0 then
			jSeenIcon:=format('<img src="%s" border="0" align="absmiddle" alt="%s">',  [GetRscPath('not_seen.gif'), GetLangStr(328)])
		else
			jseenIcon:=format('<img src="%s" border="0" align="absmiddle" alt="%s">',  [GetRscPath('seen.gif'), GetLangStr(327)]);
		if jWanted=0 then
			jWantedIcon:=format('<img src="%s" border="0" align="absmiddle" alt="%s">',  [GetRscPath('not_wanted.gif'), GetLangStr(330)])
		else
			jWantedIcon:=format('<img src="%s" border="0" align="absmiddle" alt="%s">',  [GetRscPath('wanted.gif'), GetLangStr(329)]);
		

		// Edition Info
		jVideoFileName:='';
		jDiskNbr:='';
		if (EditionCode=0)
			then sql:='select * from editions '
					+format('where movie=%d ', [MovieCode])
					+'and filename>'''' '    // 20100907-JeF
					+'order by sort_order limit 1'
		else sql:='select * from editions '+format('where code=%d', [EditionCode]);
		RecordCount:=ExecuteSQL(sql);
		if RecordCount>0 then begin
			if (EditionCode=0) then EditionCode:=GetIntegerField('Code');
			s:=GetStringField('FileName');
			jVideoFileName:=ClearExtraSDQuotes(s);
			if (jVideoFileName>'') and NOT InList('ALL',UpperCase(GetStrOption('PlayButton'))) then begin
				if (XFid=4) and InList('ML',UpperCase(GetStrOption('PlayButton')))
				or (XFid=301) and InList('MH',UpperCase(GetStrOption('PlayButton')))
				then //Ok
				else jVideoFileName:='';
			end;
			jDiskNbr:=GetStringField('disc_nom');
			if (jDiskNbr>'') 
				then jDiskNbr:=format('<a href="custom005600001:%d">%s</a>', [GetIntegerField('code'), jDiskNbr]);
			// ExportToList Tag   // 20100907-JeF
			jExpLstTag:=Format('<a href="userref:10000,,%d">',[EditionCode])
						+'<img src="'+GetRscPath('AddToList.png')+'" align="absmiddle" height=18 '
						+'alt="'+jVideoFileName+'" border=0></a>';
		end;

		// ThumbPath
		jThumbPath:='';
		if (ItemFace>=3) then begin
			jThumbPath:=GetRscPath('no-cover.gif');
			sql:='select * from images '+format('where movie=%d and mode=1', [MovieCode]) + ' order by sort_order';
			RecordCount:=ExecuteSQL(sql);
			if RecordCount>0 
        //then jThumbPath:=ImagesPath+GetStringField('path');
        then jThumbPath:=GetThumb(GetStringField('path'),ThumbsCoversList,'nocover.gif',0,0,false);
		end;

		// Infos for RichList Face (3,4) : Thumb + All Text Infos
		if (ItemFace>=3) and (ItemFace<=4) then begin 

			// Genres
			sql:='select * from movies_manuals mm '
				+'join manuals m on m.code=mm.ref_code '
				+format('where mm.movie=%d and m.reference=8', [MovieCode]);
			RecordCount:=ExecuteSQL(sql);
			for i:=1 to RecordCount do begin
			  jGenres:=jGenres+format('<a href="genre:%d">%s</a>, ', [GetIntegerField('m.code'), GetStringField('m.name')]);
			  GetNextRecord;
			end;
			if jGenres<>'' then jGenres:=copy(jGenres, 1, length(jGenres)-2);

			// Directors (1) and Actors (3)
			sql:='select distinct p.code, p.name, p.in_collection, d.mode from data d '
				+'inner join persons p on p.code=d.person '
				+format('where d.movie=%d and d.mode in (1,3) ', [MovieCode])
				+'order by d.mode, d.sort_order';
			RecordCount:=ExecuteSQL(sql);
			jDirLstLen:=0;
			jActLstLen:=0;
			i:=0;
			while (i<RecordCount) do begin
				jName:=GetStringField('p.name');
				if GetIntegerField('p.in_collection')=1 
					then img:=format('<img src="%s" align="absmiddle">', [GetRscPath('person.gif')])
				else img:='';
				if GetIntegerField('d.mode')=1 then begin
					jDirLstLen:=jDirLstLen+length(jName);
					if (jDirLstLen*LetterWidth<ListWidth)
						then jDirectors:=jDirectors+img+format('<a href="person:%d">%s</a>, ', [GetIntegerField('p.code'), jName]);
				end
				else begin
					jActLstLen:=jActLstLen+length(jName);
					if (jActLstLen*LetterWidth<ListWidth*2)
						then jActors:=jActors+img+format('<a href="person:%d">%s</a>, ', [GetIntegerField('p.code'), jName])
					else i:=RecordCount;   // Max reached => End
				end;
				i:=i+1;
				GetNextRecord;
			end;
			if jDirectors<>'' then jDirectors:=copy(jDirectors, 1, length(jDirectors)-2);
			if jActors<>'' then jActors:=copy(jActors, 1, length(jActors)-2);

		end;

		// Seasons
		jSeasons:='';
		sql:='select distinct season from episodes '+format('where movie=%d ', [MovieCode])+'order by season';
		RecordCount:=ExecuteSQL(sql);
		//20101010-JeF
		if (RecordCount>0) and (GetStrOption('TitleTVTag')>'')
			then insert(GetStrOption('TitleTVTag'),jYear,3);
		if (ItemFace>=3) and (ItemFace<=4) then begin 
			for i:=1 to RecordCount do begin
				jSeasons:=jSeasons+format('<a href="movie:%d#%d">%d</a> ', [MovieCode, GetIntegerField('season'), GetIntegerField('season')]);
				GetNextRecord;
			end;
			if jSeasons<>'' then begin
				jFirstAirYear:='';
				jLastAirYear:='';
				if GetBoolOption('ShowMtAirYears') then begin
					sql:='select min(original_air_date) from episodes '
						+format('where movie=%d and original_air_date > "1899-01-01"', [MovieCode]);
					RecordCount:=ExecuteSQL(sql);
					if (RecordCount>0) then begin
						jFirstAirYear:=GetStringField('min(original_air_date)');
						jFirstAirYear:=copy(jFirstAirYear,1,4);
						if (jFirstAirYear<'1900') then jFirstAirYear:='';
					end;
					sql:='select max(original_air_date) from episodes '
						+format('where movie=%d and original_air_date > "1899-01-01"', [MovieCode]);
					RecordCount:=ExecuteSQL(sql);
					if (RecordCount>0) then begin
						jLastAirYear:=GetStringField('max(original_air_date)');
						jLastAirYear:=copy(jLastAirYear,1,4);
						if (jLastAirYear<'1900') or (jLastAirYear<jFirstAirYear) or (jLastAirYear<GetStringField('year')) 
							then jLastAirYear:='';
					end;
				end;
				if GetBoolOption('ShowMtAirYears') and ((jFirstAirYear>'') or (jLastAirYear>'')) then
					jSeasons:=copy(GetLangStr(517),1,length(GetLangStr(517))-1)+' ('+jFirstAirYear+'-'+jLastAirYear+') : '+jSeasons
				else
					jSeasons:=GetLangStr(517)+' '+jSeasons;
				delete(jSeasons, length(jSeasons), 1);
			end;
		end;

		// Build TexT Face Item
		if (ItemFace<=2) then begin 
			s:='';
			if (jVideoFileName>'') then s:=s+GetPlayTag(jVideoFileName)+' ';
			if jSeen=1 then s:=s+jSeenIcon+'&nbsp;';
			if jWanted=1 then s:=s+jWantedIcon+'&nbsp;';

			s:=s+format('<a href="movie:%d">%s</a>', [MovieCode, jTitle])+jYear+jRate;
			if GetBoolOption('ShowMtDiskNbr') and (jDiskNbr>'')
				then s:=s+'&nbsp;(#'+jDiskNbr+')';
			s:=s+'&nbsp;'+jExpLstTag;   // 20100907-JeF
			if (ItemFace=1) then s:=s+'<br>'
			else if (ItemFace=2) then s:='<li>'+s;
		end;

		// Build Rich Face Item
		if (ItemFace>=3) and (ItemFace<=4) then begin 
			s:='<table width="100%"><tr>';
			if (ItemFace=4) then s:=s+'<td style="text-align:right;vertical-align:top;width:'+IntToStr(10+length(IntToStr(LastItemNbr))*LetterWidth)+'px;">'+IntToStr(ItemNbr)+'.&nbsp;</td>';
			s:=s+format('<td><a href="movie:%d"><img src="%s" width="%d" border=0 align=left></a>', [MovieCode, jThumbPath, ThumbWidth]);
			if (jVideoFileName>'') then s:=s+GetPlayTag(jVideoFileName)+' ';
			if jSeen=1 then s:=s+jSeenIcon+'&nbsp;';   // 20111207-JeF
			if jWanted=1 then s:=s+jWantedIcon+'&nbsp;';   // 20111207-JeF
			s:=s+format('<a href="movie:%d"><b>%s</b></a>', [MovieCode, jTitle])+jYear+jRate;
			if GetBoolOption('ShowMtDiskNbr') and (jDiskNbr>'')
				then s:=s+'&nbsp;(#'+jDiskNbr+')';
			s:=s+'&nbsp;'+jExpLstTag;   // 20100907-JeF
			s:=s+'<br>';
			if (jGenres>'') then s:=s+GetLangStr(179)+': '+jGenres+'<br>';
			if (jDirectors>'') then s:=s+GetLangStr(181)+': '+jDirectors+'<br>';
			if (jActors>'') then s:=s+GetLangStr(164)+': '+jActors+'<br>';
			s:=s+jSeasons;
			s:=s+'</td></tr></table>';
		end;

		// Build Thumb Face Item
		if (ItemFace>=5) and (ItemFace<=6) then begin 
			s:='<td style="width:'+IntToStr(ThumbWidth)+'px;vertical-align:top;padding-top:5px;"><center><div style="vertical-align:top">';
			s:=s+format('<div><a href="movie:%d"><img src="%s" width="%d" border=0 align=left></a>', [MovieCode, jThumbPath, ThumbWidth]);
			s:=s+'</div><div style="vertical-align:bottom">';
			if (jVideoFileName>'') then s:=s+GetPlayTag(jVideoFileName)+' ';
			if (jAge>'') then s:=s+'<small>'+jAge+'</small><br>';
			s:=s+format('<a href="movie:%d"><b>%s</b></a>', [MovieCode, jTitle]);
			//if (jAge>'') then s:=s+'<small>'+jAge+'</small><br>';
			s:=s+'</center></td>';
		end;

	end;

	result:=s;
end;

function BuildPersonListItem(PersonCode, ItemFace, ItemNbr, LastItemNbr, LetterWidth, ThumbWidth, ListWidth, XFid: integer): string;
var
	jInColl, jRating, jActorCount, jActorCountInColl, RecordCount, i, j: integer;
	jPersonName, jBirthDate, jDeathDate, jAge, jRate, jThumbPath, jName, s, sql, img: string;
begin
	s:='';
	jAge:='';
	jRate:='';
	sql:=format('select * from persons where code=%d', [PersonCode]);
	RecordCount:=ExecuteSQL(sql);
	if RecordCount>0 then begin

		jPersonName:=GetStringField('name');
		jInColl:=GetIntegerField('in_collection');
		jBirthDate:=GetStringField('birth_date');
		if (length(jBirthDate)=10) then jBirthDate:=GetSmartDate(jBirthDate);
		jDeathDate:='';
		if GetBoolOption('ShowPtDateOfDeath') then begin
			jDeathDate:=GetStringField('death_date');
			if (length(jDeathDate)=10) then jDeathDate:=GetSmartDate(jDeathDate);
		end;

		s:=GetStrXFvar(XFid,'EndDate');
		if (s>'') and (jBirthDate>'') then begin
			i:=GetAge(jBirthDate,s);
			if (i>0) then jAge:='('+IntToStr(i)+')';
		end;
		
		jRating:=GetIntegerField('rating');
		if jRating>0 then jRate:=format(' <img src="%s" width=16 height=16 border=0 align="absmiddle">%d', [GetRscPath('BarUnit-On.gif'), jRating]);
		
		// ThumbPath
		jThumbPath:=GetRscPath('no-cover.gif');
		if (ItemFace>=3) then begin 
			sql:='select * from images '+format('where person=%d and mode=6', [PersonCode]) + ' order by sort_order';
			RecordCount:=ExecuteSQL(sql);
			if RecordCount>0 
        //then jThumbPath:=ImagesPath+GetStringField('path');
        then jThumbPath:=GetThumb(GetStringField('path'),ThumbsPhotosList,'nophoto.gif',0,0,false);
		end;

		// Infos for RichList Face (3,4) : Thumb + All Text Infos
		if (ItemFace>=3) and (ItemFace<=4) then begin 
			// Movies as Actor
			sql:='select distinct movie as amount from data '+format('where person=%d and mode=3', [PersonCode]);
			jActorCount:=ExecuteSQL(sql);
			// Movies as Actor and in collection
			sql:='select distinct d.movie as amount from data d inner join movies m on m.code=d.movie '
				+format('where d.person=%d and d.mode=3 and m.in_collection=1', [PersonCode]);
			jActorCountInColl:=ExecuteSQL(sql);
		end;

		// Build TexT Face Item
		if (ItemFace<=2) then begin 
			s:=format('<a href="person:%d">%s</a>', [PersonCode, jPersonName])+jRate;
			if (ItemFace=1) then s:=s+'<br>'
			else if (ItemFace=2) then s:='<li>'+s;
		end;

		// Build Rich Face Item
		if (ItemFace>=3) and (ItemFace<=4) then begin 
			s:='<table width="100%"><tr>';
			if (ItemFace=4) then s:=s+'<td style="text-align:right;vertical-align:top;width:'+IntToStr(10+length(IntToStr(LastItemNbr))*LetterWidth)+'px;">'+IntToStr(ItemNbr)+'.&nbsp;</td>';
			s:=s+format('<td><a href="person:%d"><img src="%s" width="%d" border=0 align=left></a>', [PersonCode, jThumbPath, ThumbWidth]);
			s:=s+format('<a href="person:%d"><b>%s</b></a>', [PersonCode, jPersonName]);
			s:=s+jRate+'<br>';
			if (jBirthDate>'') then s:=s+jBirthDate;
			if GetBoolOption('ShowPtDateOfDeath') and (jDeathDate<>'') then s:=s+' - '+jDeathDate;
			s:=s+'<br>';
			if (jActorCount>0) then begin
				s:=s+format('%s: %d', [GetLangStr(301), jActorCount]);
				if (jActorCountInColl>0) then s:=s+' ('+IntToStr(jActorCountInColl)+')';
			end;
			s:=s+'</td></tr></table>';
		end;

		// Build Thumb Face Item
		if (ItemFace>=5) and (ItemFace<=6) then begin 
			s:='<td style="width:'+IntToStr(ThumbWidth)+'px;vertical-align:top;padding-top:5px;"><center><div style="vertical-align:top">';
			s:=s+format('<div><a href="person:%d"><img src="%s" width="%d" border=0 align=left></a>', [PersonCode, jThumbPath, ThumbWidth]);
			s:=s+'</div><div style="vertical-align:bottom">';
			s:=s+format('<a href="person:%d"><b>%s</b></a>', [PersonCode, jPersonName]);
			if (jAge>'') then s:=s+'<br><small>'+jAge+'</small>';
			s:=s+'</center></td>';
		end;

	end;
	result:=s;
end;

// 20090904-JeF
function BuildList(SqlText, LType: string; LFace, TWidth, LWidth, TargetPageNbr, MaxCount, NavTag, XFid: integer): string;
var
	RecordCount, jThumbWidth, jMaxPerLine, jFirstItemNbr, LstCode, LstEdCode, rating, jLetterWidth, jTitleMaxWidth, i, j, k: integer;
	s, s2, s3, SqlPrefix, SqlEdPrefix, LstTitle, LstYear, LstRating, LstFileName, jNavBar: string;
	LstName, jCodeStr: string;
	sl, slData: TStringList;
begin
	s:='';
	sl:=TStringList.create;
	slData:=TStringList.create;
	jLetterWidth:=GetIntThmOption('TTLetterMaxWidth');
	jThumbWidth:=TWidth;
	if (jThumbWidth=0) then jThumbWidth:=GetIntOption('ListThumbsWidth');
	jMaxPerLine:=LWidth div (jThumbWidth+10);
	if (LFace=0) then LFace:=GetIntOption('ListFace');
	if (MaxCount=0) then begin
		if (LFace<=2) then MaxCount:=GetIntOption('TextListMaxItems')
		else if (LFace<=4) then MaxCount:=GetIntOption('RichListMaxItems')
		else if (LFace<=6) then MaxCount:=GetIntOption('ThumbListMaxItems');
	end;
	jFirstItemNbr:=(TargetPageNbr-1)*MaxCount+1;
	RecordCount:=0;
	if (pos('$',SqlText)>0) then begin
		SqlText:=ReplaceStr(SqlText,'$1',GetStrXFvar(XFid,'sqlvar1'));
		SqlText:=ReplaceStr(SqlText,'$2',GetStrXFvar(XFid,'sqlvar2'));
		SqlText:=ReplaceStr(SqlText,'$3',GetStrXFvar(XFid,'sqlvar3'));
	end;
	if (SqlText>'') then RecordCount:=ExecuteSQL(SqlText);
	jNavBar:='<center>'+BuildNavTag(XFid, TargetPageNbr, MaxCount, RecordCount)+'</center>';
	if RecordCount>0 then begin
		if (jFirstItemNbr>RecordCount) then jFirstItemNbr:=RecordCount;
		SqlPrefix:='';
		SqlEdPrefix:='ZZ';
		if (LType='Movie')  and (pos('m.code',SqlText)>0) and (pos('as code',SqlText)=0) then SqlPrefix:='m.';
		if (LType='Movie')  and (pos('e.movie',SqlText)>0) then SqlEdPrefix:='e.';
		if (LType='Person') and (pos('p.code',SqlText)>0) and (pos('as code',SqlText)=0) then SqlPrefix:='p.';
		i:=1;
		j:=1;
		sl.clear;
		while (j<=RecordCount) and (i<=jFirstItemNbr+MaxCount-1) do begin
			s2:='';
			if (LType='Movie') then begin
				jCodeStr:=IntToStr(GetIntegerField(SqlPrefix+'code'));
				if (slData.IndexOfName(jCodeStr+'-title')=-1) then begin
					sl.Add(jCodeStr);
					i:=i+1;
					slData.Add(jCodeStr+'-title='+GetStringField(SqlPrefix+'title'));
					slData.Add(jCodeStr+'-year='+GetStringField(SqlPrefix+'year'));
					slData.Add(jCodeStr+'-rating='+IntToStr(GetIntegerField(SqlPrefix+'rating')));
					if (pos(SqlEdPrefix+'code',SqlText)>0) 
						then slData.Add(jCodeStr+'-edCode='+IntToStr(GetIntegerField(SqlEdPrefix+'code')))
					else slData.Add(jCodeStr+'-edCode='+'0');
				end;
				if (slData.IndexOfName(jCodeStr+'-filename')=-1) 
				and (pos(SqlEdPrefix+'code',SqlText)>0) then begin
					slData.Values[jCodeStr+'-edCode']:=IntToStr(GetIntegerField(SqlEdPrefix+'code'));
					slData.Add(jCodeStr+'-filename='+GetStringField(SqlEdPrefix+'filename'));
				end;
			end
			else if (LType='Person') then begin
				jCodeStr:=IntToStr(GetIntegerField(SqlPrefix+'code'));
				if (slData.IndexOfName(jCodeStr+'-name')=-1) then begin
					sl.Add(jCodeStr);
					i:=i+1;
					slData.Add(jCodeStr+'-name='+GetStringField(SqlPrefix+'name'));
					slData.Add(jCodeStr+'-rating='+IntToStr(GetIntegerField(SqlPrefix+'rating')));
				end;
			end;
			j:=j+1;
			GetNextRecord;
		end;
		i:=1;
		while (i<jFirstItemNbr) do begin
			sl.delete(0);
			i:=i+1;
		end;
		// Calculate title/name max width = word max width in all titles/names to show
		jTitleMaxWidth:=0;
		i:=1;
		while (i<=sl.Count) do begin
			if (LType='Movie')
				then s3:=slData.Values[sl[i-1]+'-title']
			else if (LType='Person')
				then s3:=slData.Values[sl[i-1]+'-name'];
			s3:=ClearExtraBlankCharacters(s3);
			while (length(s3)>0) do begin
				while (s3[1]=' ') and (length(s3)>0) do delete(s3,1,1);
				k:=pos(' ',s3);
				if (k=0) then k:=length(s3);
				if (k>jTitleMaxWidth) then jTitleMaxWidth:=k;
				delete(s3,1,k);
			end;
			i:=i+1;
		end;
		if ((jTitleMaxWidth*jLetterWidth)>(jThumbWidth+10)) 
			then jMaxPerLine:=LWidth div (jTitleMaxWidth*jLetterWidth);
		i:=1;
		while (i<=sl.Count) do begin
// TODO
			LstCode:=StrToInt(sl[i-1]);
			LstRating:=slData.Values[sl[i-1]+'-rating'];
			LstEdCode:=0;
			LstFileName:='';
			if (LType='Movie') then begin
				LstTitle:=slData.Values[sl[i-1]+'-title'];
				LstYear:=slData.Values[sl[i-1]+'-year'];
				if (slData.IndexOfName(jCodeStr+'-edCode')>-1) 
					then LstEdCode:=StrToInt(slData.Values[sl[i-1]+'-edCode']);
				if (slData.IndexOfName(jCodeStr+'-filename')>-1) 
					then LstFileName:=slData.Values[sl[i-1]+'-filename'];
			end
			else if (LType='Person') then begin
				LstName:=slData.Values[sl[i-1]+'-name'];
			end;
			if (LType='Movie') then begin
				if (LstFileName>'') and NOT InList('ALL',UpperCase(GetStrOption('PlayButton'))) then begin
					if (XFid=4) and InList('ML',UpperCase(GetStrOption('PlayButton')))
					or (XFid=301) and InList('MH',UpperCase(GetStrOption('PlayButton')))
					then //ok
					else LstFileName:='';
				end;
				if (LFace=1) 					// 1=TextList		 : Title only, 1 entry per line
				or (LFace=2) then begin			// 2=OrderedTextList : Number + Title only, 1 entry per line
					s2:=BuildMovieListItem(LstCode, LstEdCode, LFace, jFirstItemNbr+i-1, jFirstItemNbr+MaxCount-1, jLetterWidth, jThumbWidth, LWidth, XFid);
				end
				else if (LFace=3) 				// 3=RichList		 : Thumb + All Text Infos, 1 entry per line
					 or (LFace=4) then begin	// 4=OrderedRichList : Number + Thumb + All Text Infos, 1 entry per line
					s2:=BuildMovieListItem(LstCode, LstEdCode, LFace, jFirstItemNbr+i-1, jFirstItemNbr+MaxCount-1, jLetterWidth, jThumbWidth, LWidth, XFid);
				end
				else if (LFace=5) 				// 5=ThumbsList	: Thumb + Title in a box, N entries per line
					 or (LFace=6) then begin	// 6=CenteredThumbsList	: Thumb + Name in a box, N entries per line, whole list centered
					 s2:=BuildMovieListItem(LstCode, LstEdCode, LFace, jFirstItemNbr+i-1, jFirstItemNbr+MaxCount-1, jLetterWidth, jThumbWidth, LWidth, XFid);
					if (i>jMaxPerLine) and (((i mod jMaxPerLine) = 1) or (jMaxPerLine=1)) then s2:='</tr><tr>'+s2;
				end;
			end
			else if (LType='Person')	then begin
				if (LFace=1) 					// 1=TextList		 : Name only, 1 entry per line
				or (LFace=2) then begin			// 2=OrderedTextList : Number + Name only, 1 entry per line
					s2:=BuildPersonListItem(LstCode, LFace, jFirstItemNbr+i-1, jFirstItemNbr+MaxCount-1, jLetterWidth, jThumbWidth, LWidth, XFid);
				end
				else if (LFace=3) 				// 3=RichList		 : Thumb + All Text Infos, 1 entry per line
					 or (LFace=4) then begin	// 4=OrderedRichList : Number + Thumb + All Text Infos, 1 entry per line
					s2:=BuildPersonListItem(LstCode, LFace, jFirstItemNbr+i-1, jFirstItemNbr+MaxCount-1, jLetterWidth, jThumbWidth, LWidth, XFid);
				end
				else if (LFace=5)				// 5=ThumbsList	: Thumb + Name in a box, N entries per line
					 or (LFace=6) then begin	// 6=CenteredThumbsList	: Thumb + Name in a box, N entries per line, whole list centered
					s2:=BuildPersonListItem(LstCode, LFace, jFirstItemNbr+i-1, jFirstItemNbr+MaxCount-1, jLetterWidth, jThumbWidth, LWidth, XFid);
					if (i>jMaxPerLine) and (((i mod jMaxPerLine) = 1)  or (jMaxPerLine=1)) then s2:='</tr><tr>'+s2;
				end;
			end;
			s:=s+s2;
			i:=i+1;

		end;
		s:=ReplaceStr(s,'class="..."','');
		if (LFace=2) then s:='<ol start='+IntToStr(jFirstItemNbr)+'>'+s+'</ol>';
		if (LFace=5) then s:='<table><tr>'+s+'</tr></table>';
		if (LFace=6) then s:='<center><table><tr>'+s+'</tr></table></center>';
	
		// Nav Tag
		if (NavTag=1) or (NavTag=3) 
			then s:=jNavBar+'<br>'+s;
		if (NavTag=2) or (NavTag=3) 
			then s:=s+'<br>'+jNavBar;
	end
	else s:='<br><br><br>';
	sl.free;
	slData.free;
	result:=s;
end;

function BuildNavTag(XFid, TargetPageNbr, PageMaxItems, ItemsCount: integer): string;
var
	jPrevPageNbr, jNextPageNbr, jLastPageNbr, i, j: integer;
	f:single;
	jNavTag, jPgList, XFidStr, jIcon: string;
begin
	// Calculate page numbers
	f:=(ItemsCount/PageMaxItems);
	if (f=0) then f:=1;
	if (frac(f)>0) then jLastPageNbr:=trunc(f)+1 else jLastPageNbr:=trunc(f);
	if (jLastPageNbr<1) then jLastPageNbr:=1;
	if (TargetPageNbr>jLastPageNbr) then TargetPageNbr:=jLastPageNbr;
	jPrevPageNbr:=TargetPageNbr-1;
	if (jPrevPageNbr<1) then jPrevPageNbr:=1;
	jNextPageNbr:=TargetPageNbr+1;
	if (jNextPageNbr>jLastPageNbr) then jNextPageNbr:=jLastPageNbr;
	SetIntXFvar(XFid,'LastPageNbr',jLastPageNbr);
	// format nav items : refresh/first/prev/next/last
	if jInCollection then jIcon:='InCollOn.png' else jIcon:='InCollOff.png';
	jNavTag:='<a href="custom101200000:'+IntToStr(XFid)+'"><img src="'+GetRscPath('Refresh.png')+'" border="0" align="absmiddle"></a>'+
			 '&nbsp;&nbsp;'+
			 '<a href="custom101100000:'+IntToStr(XFid)+'"><img src="'+GetRscPath(jIcon)+'" border="0" align="absmiddle"></a>'+
			 '&nbsp;&nbsp;'+
			 '<a href="custom101300000:'+IntToStr(XFid)+'"><img src="'+GetRscPath('First.png')+'" border="0" align="absmiddle"></a>'+
			 '<a href="custom101400000:'+IntToStr(XFid)+'"><img src="'+GetRscPath('Prev.png')+'" border="0" align="absmiddle"></a>'+
			 '<a href="custom101500000:'+IntToStr(XFid)+'"><img src="'+GetRscPath('Next.png')+'" border="0" align="absmiddle"></a>'+
			 '<a href="custom101600000:'+IntToStr(XFid)+'"><img src="'+GetRscPath('Last.png')+'" border="0" align="absmiddle"></a>';
	// format page numbers
	XFidStr:=IntToStr(XFid);
	while (length(XFidStr)<5) do XFidStr:='0'+XFidStr;
	jPgList:='&nbsp;';
	if (TargetPageNbr-10>0) then 
		jPgList:=jPgList+'<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr-10)+'">'+IntToStr(TargetPageNbr-10)+'</a>&nbsp;';
	if (TargetPageNbr-9>0) then 
		jPgList:=jPgList+'<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr-9)+'">'+IntToStr(TargetPageNbr-9)+'</a>...';
	if (TargetPageNbr-2>0) then 
		jPgList:=jPgList+'<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr-2)+'">'+IntToStr(TargetPageNbr-2)+'</a>&nbsp;';
	if (TargetPageNbr-1>0) then 
		jPgList:=jPgList+'<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr-1)+'">'+IntToStr(TargetPageNbr-1)+'</a>&nbsp;';
	jPgList:=jPgList+'<span style="color:#ff0000;"><strong>'+IntToStr(TargetPageNbr)+'</strong></span>';
	if (TargetPageNbr+1<=jLastPageNbr) then 
		jPgList:=jPgList+'&nbsp;<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr+1)+'">'+IntToStr(TargetPageNbr+1)+'</a>';
	if (TargetPageNbr+2<=jLastPageNbr) then 
		jPgList:=jPgList+'&nbsp;<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr+2)+'">'+IntToStr(TargetPageNbr+2)+'</a>';
	if (TargetPageNbr+9<=jLastPageNbr) then 
		jPgList:=jPgList+'...<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr+9)+'">'+IntToStr(TargetPageNbr+9)+'</a>';
	if (TargetPageNbr+10<=jLastPageNbr) then 
		jPgList:=jPgList+'&nbsp;<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr+10)+'">'+IntToStr(TargetPageNbr+10)+'</a>';
	// when not starting by "i j...k", complete with 2 prev page numbers
	if (TargetPageNbr>2) and (TargetPageNbr<=9) then begin
		if (TargetPageNbr-3>0) then 
			jPgList:='&nbsp;<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr-3)+'">'+IntToStr(TargetPageNbr-3)+'</a>'+jPgList;
		if (TargetPageNbr-4>0) then 
			jPgList:='&nbsp;<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr-4)+'">'+IntToStr(TargetPageNbr-4)+'</a>'+jPgList;
	end;
	// when not ending by "k...l m", complete with 2 next page numbers
	if (TargetPageNbr+9>jLastPageNbr) then begin
		if (TargetPageNbr+3<=jLastPageNbr) then 
			jPgList:=jPgList+'&nbsp;<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr+3)+'">'+IntToStr(TargetPageNbr+3)+'</a>';
		if (TargetPageNbr+4<=jLastPageNbr) then 
			jPgList:=jPgList+'&nbsp;<a href="custom1017'+XFidStr+':'+IntToStr(TargetPageNbr+4)+'">'+IntToStr(TargetPageNbr+4)+'</a>';
	end;
	jPgList:=jPgList+'/'+IntToStr(jLastPageNbr)+'&nbsp;('+IntToStr(ItemsCount)+')';
	jNavTag:=jNavTag+jPgList;
	// format list face buttons
	jNavTag:=jNavTag+'&nbsp;&nbsp;'+
			'<a href="custom1018'+XFidStr+':2"><img src="'+GetRscPath('List1.png')+'" border="0" align="absmiddle"></a>&nbsp;'+
			'<a href="custom1018'+XFidStr+':4"><img src="'+GetRscPath('List2.png')+'" border="0" align="absmiddle"></a>&nbsp;'+
			'<a href="custom1018'+XFidStr+':6"><img src="'+GetRscPath('List3.png')+'" border="0" align="absmiddle"></a>';
	// thumbs zoom in/out buttons
	if (GetIntOption('ListFace')>2) then begin
		jNavTag:=jNavTag+'&nbsp;&nbsp;'+
				'<a href="custom1019'+XFidStr+':1"><img src="'+GetRscPath('ZoomIn.png')+'" border="0" align="absmiddle"></a>&nbsp;'+
				'<a href="custom1019'+XFidStr+':2"><img src="'+GetRscPath('ZoomOut.png')+'" border="0" align="absmiddle"></a>';
	end;
	// Year/Alphabet Order Toggle for lists by manuals
	if (XFid=4) then begin
		i:=GetIntOption('ByManualsListOrder');
		if (i=0) then jIcon:=GetRscPath('calendar.png')
		else if (i=1) then jIcon:=GetRscPath('abc.png')
		else jIcon:='';
		jNavTag:=jNavTag+'&nbsp;&nbsp;<a href="custom102000004:1"><img src="'+jIcon
						+'"	border="0" align="absmiddle"></a>';
	end;
	// Global div for Nav bar
	jNavTag:='<div class="navbar">'+jNavTag+'</div>';
	// Rebuild Main Nav Tag according to current Extra Feature call
	BuildMainNavBar(XFid,'111111111111');
	result:=jNavTag;
end;

procedure BuildMainNavBar(XFid: integer; OnOff: string);
var
	TBLink, MBLink, SBLink, FSLink, s, img, altext: string;
begin
	s:=GetStrOption('HomePageCode');
	if (length(s)=18) and (s<>jHomePageCode) then begin
		img:='HomeBlue.png';
		altext:=GetLangStr(1172);
	end
	else begin
		img:='HomeOrange.png';
		altext:=GetLangStr(1173);
	end;
	TBLink:='custom100400000:'+IntToStr(XFid);
	MBLink:='custom100500000:'+IntToStr(XFid);
	SBLink:='custom100600000:'+IntToStr(XFid);
	FSLink:='custom100700000:'+IntToStr(XFid);
	jMainNavBar:='<div class="MainNavBar">';
	if (XFid<>1) and (XFid<>213)
		then jMainNavBar:=jMainNavBar+BlockTag('', 'TB0001-', 'tag-s')
						+'<a href="custom110100010:1"><img src="'+GetRscPath('IconsBarHide.png')
						+'" border="0" align="top" '
						+'alt="'+GetLangStr(1171)+'"</a>';
	if (OnOff[1]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="custom000100000:1"><img src="'
								+GetRscPath(img)+'" border="0" align="absmiddle" '
								+'alt="'+altext+'"></a>&nbsp;';
	if (OnOff[2]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="custom030100000:1"><img src="'
								+GetRscPath('Clap.png')+'" border="0" align="absmiddle" '
								+'alt="'+GetLangStr(1100)+'"></a>&nbsp;';  // Movies Home Page
	if (OnOff[3]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="custom030200000:1"><img src="'
								+GetRscPath('Persons.png')+'" border="0" align="absmiddle" '
								+'alt="'+GetLangStr(1101)+'"></a>&nbsp;';  // Persons Home Page
	if (OnOff[4]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="'+TBLink+'"><img src="'
								+GetRscPath('ToolBar.png')+'" border="0" align="absmiddle" '
								+'alt="'+GetLangStr(1129)+'"></a>&nbsp;';  // ToolBar Visibility
	if (OnOff[5]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="'+MBLink+'"><img src="'
								+GetRscPath('MenuBar.png')+'" border="0" align="absmiddle" '
								+'alt="'+GetLangStr(1128)+'"></a>&nbsp;';  // MenuBar Visibility
	if (OnOff[6]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="'+SBLink+'"><img src="'
								+GetRscPath('SideBar.png')+'" border="0" align="absmiddle" '
								+'alt="'+GetLangStr(1130)+'"></a>&nbsp;';  // SideBar Visibility
	if (OnOff[7]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="'+FSLink+'"><img src="'
								+GetRscPath('FullScreen.png')+'" border="0" align="absmiddle" '
								+'alt="'+GetLangStr(1131)+'"></a>&nbsp;';  // Full Screen Mode
	if (OnOff[8]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="custom020100000:1"><img src="'+GetRscPath('Settings.png')+'" border="0" align="absmiddle" '
				+'alt="'+GetLangStr(1103)+'"></a>&nbsp;';  // Script Settings
	if (OnOff[9]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="custom021000000:1"><img src="'+GetRscPath('GearWheel.png')+'" border="0" align="absmiddle" '
				+'alt="'+GetLangStr(1104)+'"></a>&nbsp;';  // Database ToolBox
	if (OnOff[10]='1') 	and (s<>jHomePageCode) then 
		jMainNavBar:=jMainNavBar+'<a href="custom100300000:1"><img src="'+GetRscPath('HomeChecked.png')+'" border="0" align="absmiddle" '
				+'alt="'+GetLangStr(1137)+'"></a>&nbsp;';  // Set Page as Home Page
	if (OnOff[11]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="command:back"><img src="'+GetRscPath('Backward.png')+'" border="0" align="absmiddle" '
				+'alt="'+GetLangStr(24)+'"></a>&nbsp;';  // Go Back to Previous page
	if (OnOff[12]='1') then 
		jMainNavBar:=jMainNavBar+'<a href="command:forward"><img src="'+GetRscPath('Forward.png')+'" border="0" align="absmiddle" '
				+'alt="'+GetLangStr(26)+'"></a>&nbsp;';  // Go Forward to Next page
	if (XFid<>1) and (XFid<>213)
		then jMainNavBar:=jMainNavBar+BlockTag('', 'TB0001-', 'tag-e');
	jMainNavBar:=jMainNavBar+'</div>';
	if (GetStrOption('NavBarState')='1') 
		then jMainNavBar:=BlockTag(jMainNavBar, 'TB0001-', 'show');
end;

function BlockTag(SrcPage, BlockId, TagMode: string): string;
begin
	result:=SrcPage;
	if (TagMode='show') then begin
		result:=ReplaceStr(result, '<script>/*'+BlockId+'-begin-', '<script>/*'+BlockId+'-begin*/</script>');
		result:=ReplaceStr(result, '-'+BlockId+'-end*/</script>', '<script>/*'+BlockId+'-end*/</script>');
	end
	else if (TagMode='hide') then begin
		result:=ReplaceStr(result, '<script>/*'+BlockId+'-begin*/</script>', '<script>/*'+BlockId+'-begin-');
		result:=ReplaceStr(result, '<script>/*'+BlockId+'-end*/</script>', '-'+BlockId+'-end*/</script>');
	end
	else if (TagMode='tag') then begin
		result:='<script>/*'+BlockId+'-begin-'+result+'-'+BlockId+'-end*/</script>';
	end
	else if (TagMode='tag-s') then begin
		result:='<script>/*'+BlockId+'-begin-'
	end
	else if (TagMode='tag-e') then begin
		result:='-'+BlockId+'-end*/</script>'
	end;
end;

procedure SetTheme(NewThm:string);
var
	jOptLoaded, i, j: integer;
	OldThm, Thm, jOptFile, s: string;
	sl: TStringList;
begin
	sl:=TStringList.Create;
	OldThm:=GetStrOption('Theme');
	SetStrOption('Theme',NewThm);
	Thm:=GetStrOption('Theme');
	jThmPath:=PicturesPath+'Themes\'+Thm+'\';
	jThmPictPath:=PicturesPath+'Themes\'+Thm+'\img\';
	jThmCustomPath:=jThmPath+'custom\';
	// Load Theme
	ThemeActive:=true;
	jThmCssList:='';
	jHomeCard.text:=LoadCard('Home.html');
	jMovieCard.text:=LoadCard('Movie.html');
	jPersonCard.text:=LoadCard('Person.html');
	jListCard.text:=LoadCard('List.html');
	jThumbjMovieCard.text:=LoadCard('Thumb_Movie.html');
	jThumbjMovie3Card.text:=LoadCard('Thumb3_Movie.html');
	jThumbjPersonCard.text:=LoadCard('Thumb_Person.html');
	jThumbjPerson3Card.text:=LoadCard('Thumb3_Person.html');
	if (jThmCssList>'') then begin
		delete(jThmCssList,length(jThmCssList),1);
		sl.CommaText:=jThmCssList;
		for i:=0 to sl.Count - 1 do LoadCard(sl[i]);
	end;
	// Reset Ressources Paths
	jRscPath.Clear;
	// Reset Theme Options
	jThemeOptions.Clear;
	jThemeOptText.Clear;
	// Theme Options : Default Values and Description Text
	jThemeOptions.Add('ABCellMaxWidth=20');
		jThemeOptText.Add('ABCellMaxWidth=Maximum width of a Cell in Alphabet Bar');
	jThemeOptions.Add('GBLetterMaxWidth=20');
		jThemeOptText.Add('GBLetterMaxWidth=Maximum width of a Letter in Genre Bar');
	jThemeOptions.Add('TTLetterMaxWidth=10');
		jThemeOptText.Add('TTLetterMaxWidth=Maximum width of a Letter in Thumb Text (title/name)');
	jThemeOptions.Add('HomeOffWidth=340');
		jThemeOptText.Add('HomeOffWidth=Total Width of Home Page design that is not usable for main content data display');
	jThemeOptions.Add('MovieOffWidth=420');
		jThemeOptText.Add('MovieOffWidth=Total Width of Movie Page design that is not usable for main content data display');
	jThemeOptions.Add('PersonOffWidth=420');
		jThemeOptText.Add('PersonOffWidth=Total Width of Person Page design that is not usable for main content data display');
	jThemeOptions.Add('ListOffWidth=340');
		jThemeOptText.Add('ListOffWidth=Total Width of List Page design that is not usable for main content data display');
	// Theme Options : Load Saved Values
	jOptFile:=jThmPath+'Theme_options.ini';
	if MyFileExists(jOptFile) then begin
		sl:=TStringList.Create;
		sl.LoadFromFile(jOptFile);
		for i:=0 to sl.Count-1 do begin
			j:=pos(';',sl[i]);
			if (j>0) then sl[i]:=ClearExtraBlankCharacters(copy(sl[i],1,j-1));
			j:=pos('//',sl[i]);
			if (j>0) then sl[i]:=ClearExtraBlankCharacters(copy(sl[i],1,j-1));
		end;
		// Current options
		jOptLoaded:=0;
		for i:=0 to sl.Count-1 do begin
			if (jThemeOptions.Values[sl.Names[i]]>'') then begin
				jThemeOptions.Values[sl.Names[i]]:=sl.Values[sl.Names[i]];
				jOptLoaded:=jOptLoaded+1;
			end;
		end;
	end;
	// Save Options to File if not all loaded from file
	if (jOptLoaded<jThemeOptions.Count) then begin
		sl.Text:=jThemeOptions.Text;
		for i:=0 to sl.Count-1 do begin
			while (length(sl[i])<30) do sl[i]:=sl[i]+' ';
			sl[i]:=sl[i]+'  ;// '+jThemeOptText.Values[sl.Names[i]];
		end;
		sl.SaveToFile(jOptFile);
	end;
	sl.free;
end;
	
begin
	jInitialize:=true;
	ScriptName := script_name;
	ScriptVersion := version;
	MultiShowRowHeight := RegReadInteger('ThumbCellHeight', DefaultMultiCellHeight);
	MultiShowImageWidth := RegReadInteger('ThumbCellWidth', DefaultMultiCellWidth);
	MiltiShowDistanceBetweenCovers := 12;
end.