//Some useful constants
Const
 //Script types
 stMovies = 0;
 stPeople = 1;
 stPoster = 2;

 //Script modes
 smSearch = 0;
 smNormal = 1;

 //Custom modes
 smDetail = 2;
 smLinks = 3;
 smAward = 4;
 smPoster = 5;
 smFinished = 6;

 //Parse results
 prError = 0;
 prFinished = 1;
 prList = 2;
 prListImage = 3;
 prDownload = 4;

 //Movie fields
 mfURL = 0;
 mfTitle = 1;
 mfOrigTitle = 2;
 mfAka = 3;
 mfYear = 4;
 mfGenre = 5;
 mfCategory = 6;
 mfCountry = 7;
 mfStudio = 8;
 mfMPAA = 9;
 mfRating = 10;
 mfTags = 11;
 mfTagline = 12;
 mfDescription = 13;
 mfDuration = 14;
 mfFeatures = 15;

 //People fields
 pfURL = 0;
 pfName = 1;
 pfTransName = 2;
 pfAltNames = 3;
 pfBirthday = 4;
 pfBirthplace = 5;
 pfGenre = 6;
 pfBio = 7;
 pfDeathDate = 8;

 //Credits types
 ctActors = 0;
 ctDirectors = 1;
 ctWriters = 2;
 ctComposers = 3;
 ctProducers = 4;

 //Script data
 SCRIPT_VERSION = '0.1.0.6';
 SCRIPT_NAME = 'Zelluloid [DE]';
 SCRIPT_DESC = '[DE] hole Film-Information von Zelluloid.de';
 SCRIPT_LANG = $07; //German
 SCRIPT_TYPE = stMovies;
 BASE_URL = 'http://www.zelluloid.de';
 RATING_NAME = 'ZELLU';
 SEARCH_STR = 'http://www.zelluloid.de/suche/index.php3?qstring=%s';
 CODE_PAGE = 0; //Use 0 for Autodetect

 //OPTIONS
 DOWNLOAD_DETAIL = True;      //Set to False if you do not want Persons being parsed from zelluloid.de
 DOWNLOAD_LINKS = True;       //Set to False if you do not want Links being parsed from zelluloid.de
 DOWNLOAD_AWARDS = True;      //Set to False if you do not want Awards being parsed from zelluloid.de
 DOWNLOAD_POSTER = True;      //Set to False if you do not want Posters being loaded from zelluloid.de
 PERFORM_CUSTOMFIELDS = True; //Set to False if you do not want custom-fields being filled
                              //requiered fields look at: coustom field names
 ADD_OFFICIAL_URLS = True;
 ADD_EXTRA_CREDITS = True; //Set to False if you do not want extra-Credits being loaded from zelluloid.de 
 ADD_FOLLOWINGS = True;    //Set to False if you do not want Followings being loaded from zelluloid.de
 //extra Credit Markers
 JOB_PREFIX = '___';  // what ever you like   

 JOB_SUFIX = '___';   // what ever you like  
 // additional persns will be added under actors there jobs will be marked as
 // JOB_PREFIX + JOB + JOB_SUFIX 
 // and show up under Role as (example "___cinematographer___"
 
 JOB_LANGUAGE = 'de'; // curently only  'de' or 'en'

 //coustom field names      setup here the names for requierd custom-fields
 cf_FSK = 'FSK';

 cf_BUDGET = 'Budget';

 cf_idIMDB = 'ID IMDb';

 cf_idZELLU = 'ID Zelluloid';

 cf_KStartDE = 'Kinostart Deutschland';

 POS_MARK = 100;

 CREW_MARK = 50;

//Global variables
var
 ELI : Integer;

 Mode : Byte;

 ExtraLinks : array [ smDetail..smPoster ] of String;

 zelluID : AnsiString;

 mXInit : Boolean;

 mX : array [ 1..POS_MARK ] of String;

 //Functions
 function GetScriptVersion : String;
 begin
  Result := SCRIPT_VERSION;
 end;

 function GetScriptName : String;
 begin
  Result := SCRIPT_NAME;
 end;

 function GetScriptDesc : String;
 begin
  Result := SCRIPT_DESC;
 end;

 function GetRatingName : String;
 begin
  Result := RATING_NAME;
 end;

 function GetScriptLang : Cardinal;
 begin
  Result := SCRIPT_LANG;
 end;

 function GetCodePage : Cardinal;
 begin
  Result := CODE_PAGE;
 end;

 function GetBaseURL : AnsiString;
 begin
  Result := BASE_URL;
 end;

 function GetDownloadURL : AnsiString;
 begin
  if ( Mode = smSearch ) then
   Result := SEARCH_STR
  else
   Result := ExtraLinks[ Mode ];
 end;

 function GetScriptType : Byte;
 begin
  Result := SCRIPT_TYPE;
 end;

 function GetCurrentMode : Byte;
 begin
  Result := Mode;
 end;

 function getCrewMember( inTT : Integer ) : Byte;
 begin
  case inTT of
   0 : Result := ctActors;
   1 : Result := ctDirectors;
   2 : Result := ctWriters;
   3 : Result := ctComposers;
   4 : Result := ctProducers;
   ( inTT > 4 ) : Result := ctActors;
  end;
 end; // getCrewMember

 function getCrewMarker( inTT : Integer ) : String;
 var
  jobMarkerX : String;

  CM : array [ 1..CREW_MARK ] of String;

 begin
  jobMarkerX := 'xxxxxxxxxxxxxxxxxx';

  if inTT > 0 then
   Begin
    // marker                                
    CM[  1 ] := 'Regie';
    CM[  2 ] := 'Drehbuch';
    CM[  3 ] := 'Musik';
    CM[  4 ] := 'Produktion';
    CM[  5 ] := 'Kamera';
    CM[  6 ] := 'Schnitt';
    CM[  7 ] := 'Buch';
    CM[  8 ] := 'Kostüme';
    CM[  9 ] := 'Regieassistenz';
    CM[ 10 ] := 'Stunts';
    CM[ 11 ] := 'Visuelle Effekte';
    CM[ 12 ] := 'Spezial-Effekte';
    CM[ 13 ] := '2nd Unit Regie';
    CM[ 14 ] := 'Produktionsassistenz';
    CM[ 15 ] := 'Stunt-Koordinator';
    CM[ 16 ] := 'Tonschnitt';
    CM[ 17 ] := 'Sound-Design';
    CM[ 18 ] := 'Bühnenbild';
    CM[ 19 ] := 'Make-Up';
    CM[ 20 ] := '';
    CM[ 21 ] := '';
    CM[ 22 ] := '';
    jobMarkerX := CM[ inTT ];
   end;

  Result := jobMarkerX;
 end; // getCrewMarker

 function getCrewJOB( inTT : Integer ) : String;
 var
  jobX : String;

  CJ_de,
  CJ_en : array [ 1..CREW_MARK ] of String;

 begin
  jobX := 'xxxxxxxxxxxxxxxxxx';

  if inTT > 0 then
   Begin
    
		// Job (german)                        // Job (englisch)
    CJ_de[  1 ] := 'Regisseur';              CJ_en[  1 ] := 'director';
    CJ_de[  2 ] := 'Drehbuch-Autor';         CJ_en[  2 ] := 'writer';
    CJ_de[  3 ] := 'Film-Komponist';         CJ_en[  3 ] := 'composer';
    CJ_de[  4 ] := 'Produzent';              CJ_en[  4 ] := 'producer';
    CJ_de[  5 ] := 'Kamera';                 CJ_en[  5 ] := 'cinematographer';
    CJ_de[  6 ] := 'Schnitt';                CJ_en[  6 ] := 'cutter';
    CJ_de[  7 ] := 'Buch';                   CJ_en[  7 ] := 'book author';
    CJ_de[  8 ] := 'Kostüme';                CJ_en[  8 ] := 'costume designer';
    CJ_de[  9 ] := 'Regieassistenz';         CJ_en[  9 ] := 'assistant director';
    CJ_de[ 10 ] := 'Stunts';                 CJ_en[ 10 ] := 'stunts';
    CJ_de[ 11 ] := 'Visuelle Effekte';       CJ_en[ 11 ] := 'visual effects';
    CJ_de[ 12 ] := 'Spezial-Effekte';        CJ_en[ 12 ] := 'special effects';
    CJ_de[ 13 ] := '2nd Unit Regisseur';     CJ_en[ 13 ] := 'second unit director';
    CJ_de[ 14 ] := 'Produktionsassistent';   CJ_en[ 14 ] := 'miscellaneous crew';
    CJ_de[ 15 ] := 'Stunt-Koordinator';      CJ_en[ 15 ] := 'stunt coordinator';
    CJ_de[ 16 ] := 'Tonschnitt';             CJ_en[ 16 ] := 'sound editor';
    CJ_de[ 17 ] := 'Sound-Design';           CJ_en[ 17 ] := 'sound-design';
    CJ_de[ 18 ] := 'Bühnenbild';             CJ_en[ 18 ] := 'set decorator';
    CJ_de[ 19 ] := 'Make-Up';                CJ_en[ 19 ] := 'Make-Up';
    CJ_de[ 20 ] := '';                       CJ_en[ 20 ] := '';
    CJ_de[ 21 ] := '';                       CJ_en[ 21 ] := '';
    CJ_de[ 22 ] := '';                       CJ_en[ 22 ] := '';
    
    CJ_de[ 40 ] := 'Serien-Teile';           CJ_en[ 40 ] := 'Series-Parts';
    CJ_de[ 41 ] := 'Fortsetzung von';        CJ_en[ 41 ] := 'Continuation of';
    CJ_de[ 42 ] := 'gefolgt von';            CJ_en[ 42 ] := 'Followed by';

    case JOB_LANGUAGE of
     'de' : jobX := CJ_de[ inTT ];
     'en' : jobX := CJ_en[ inTT ];
    end;
   end;

  Result := jobX;
 end; // getCrewJOB
 // end funcs
 ///////////////////////////////////////////

 procedure initMX( );
 begin
  mX[  1 ] := '/filme/';
  mX[  2 ] := '/person/';
  mX[  3 ] := 'index.php3?id=';
  mX[  4 ] := 'details.php3?id=';
  mX[  5 ] := 'links.php3?id=';
  mX[  6 ] := 'preise.php3?id=';
  mX[  7 ] := 'bilder.php3?id=';
  mX[  8 ] := 'hit.php3?hit=';
  mX[  9 ] := 'az.php3?j=';
  mX[ 10 ] := 'az.php3?g=';
  mX[ 11 ] := 'az.php3?l=';
  mX[ 12 ] := '<B>Der Suchbegriff erzielte';
  mX[ 13 ] := 'icoMovie.gif';
  mX[ 14 ] := 'movie-';
  mX[ 15 ] := '-';
  mX[ 16 ] := '<title>';
  mX[ 17 ] := '|';
  mX[ 18 ] := 'SRC="/gfx/headers/dyn_bottom.gif"';
  mX[ 19 ] := '-';
  mX[ 20 ] := 'STYLE="color:#AAAAAA;"';
  mX[ 21 ] := '<TABLE';
  mX[ 22 ] := '<BR>';
  mX[ 23 ] := 'Originaltitel:';
  mX[ 24 ] := 'Übersicht';
  mX[ 25 ] := 'FSK: ';
  mX[ 30 ] := '<TABLE WIDTH="100%" CELLSPACING=0 CELLPADDING=10 BORDER=0 HEIGHT=300 BGCOLOR="#444444">';
  mX[ 31 ] := '<td align="right">';
  mX[ 32 ] := '<td>';
  mX[ 33 ] := '</td>';
  mX[ 34 ] := '<tr><td align="center" colspan="2">';
  mX[ 35 ] := 'alt="Besetzung"';
  mX[ 36 ] := 'alt="Crew"';
  mX[ 37 ] := 'alt="Produktion"';
  mX[ 38 ] := 'alt="Verleih"';
  mX[ 39 ] := '</TR>';
  mX[ 40 ] := '>';
  mX[ 41 ] := '"';
  mX[ 42 ] := '</A>';
  mX[ 43 ] := '</TABLE>';
  mX[ 44 ] := '</TD></TR>';
  mX[ 45 ] := '</NOBR>';
  mX[ 46 ] := '<A HREF="';
  mX[ 47 ] := '<DIV CLASS="bigtext">';
  mX[ 48 ] := '</DIV>';
  mX[ 49 ] := 'User-Wertung:';
  mX[ 50 ] := '<TR><TD WIDTH=';
  mX[ 51 ] := '</A></DIV></TD></TR></TABLE></TD></TR></TABLE></TD></TR>';
  mX[ 52 ] := '<A HREF="/addlink.php3?t=m&id=';
  mX[ 53 ] := '<A HREF="http://german.imdb.com/title/tt';
  mX[ 55 ] := '<A HREF="http://german.imdb.com/Title?';
  mX[ 56 ] := '<B>Offizielle Seite';
  mX[ 57 ] := '</B></DIV><DIV CLASS=smallBlur>';
  mX[ 58 ] := '<';
  mX[ 59 ] := '<B>Teil der Serie';
  mX[ 60 ] := '</B>';
  mX[ 61 ] := 'ALT="Teil der Serie ';
  mX[ 62 ] := '</TABLE><DIV CLASS="smallLight" STYLE="line-height:16px;text-align:center;">';
  mX[ 63 ] := '</TD>';
  mX[ 64 ] := '<div style="padding: 5px; margin-bottom: 3px; font: normal 12px Arial; color: #CCCCCC;">';
  mX[ 65 ] := '<div class="normLight" style="border-top: 1px dotted #666666;padding: 5px;margin-bottom: 3px;line-height:18px;';
  mX[ 66 ] := '</div>';
  mX[ 67 ] := '<img src="';
  mX[ 68 ] := '<a href="';
  mX[ 69 ] := '</a>';
  mX[ 70 ] := '<b>';
  mX[ 71 ] := '</b>';
  mX[ 72 ] := '</a>Gewinn';
  mX[ 73 ] := '</a>Nomini';
  mX[ 74 ] := '<br />f&uuml;r';
  mX[ 75 ] := 'anzeigen...">';
  mX[ 76 ] := 'Kinostart Deutschland';
 end;

 procedure ParseGenres( HTML, startstr, endstr : String );
 var
  P : Integer;

 begin
  P := 1;
  //Genre
  AddFieldValue( mfGenre, HTMLValues2( HTML, startSTR, endstr, mX[ 10 ], mX[ 42 ], ', ', P ) );
 end;

 procedure ParseCountries( HTML, startstr, endstr : String );
 var
  P : Integer;

 begin
  P := 1;
  //Country
  AddFieldValue( mfCountry, HTMLValues2( HTML, startSTR, endstr, mX[ 11 ], mX[ 42 ], ', ', P ) );
 end;

 procedure ParseOurLinks( MovieURL : String; HTML : String );
 var
  curPos, startPos, lastPos, endPos, P : Integer;

 begin
  P := 0;
  startPos := Pos( '<DIV CLASS=smallDark', HTML );
  lastPos := PosFrom( 'schreiben</A>', HTML, startPos );

  //DETAILs
  if DOWNLOAD_DETAIL then
   Begin
    curPos := PosFrom( mX[  4 ] + zelluID, HTML, startPos );

    if curPos > 0 then
     Begin
      ExtraLinks[ smDetail ] := BASE_URL + mX[  1 ] + mX[  4 ] + zelluID;
     end;
   end;

  //Links
  if DOWNLOAD_LINKS then
   Begin
    curPos := PosFrom( mX[  5 ] + zelluID, HTML, startPos );

    if curPos > 0 then
     Begin
      ExtraLinks[ smLinks ] := BASE_URL + mX[  1 ] + mX[  5 ] + zelluID;
     end;
   end;

  //Awards
  if DOWNLOAD_AWARDS then
   Begin
    curPos := PosFrom( mX[  6 ] + zelluID, HTML, startPos );

    if curPos > 0 then
     Begin
      ExtraLinks[ smAward ] := BASE_URL + mX[  1 ] + mX[  6 ] + zelluID;
     end;
   end;

  //Poster URL
  if DOWNLOAD_POSTER then
   Begin
    endPos := 0;

    if ( Pos( 'pic="/images/poster/', HTML ) > 0 ) AND ( Pos( 'title="Poster zu', HTML ) > 0 ) then
     Begin
      curPos := Pos( 'pic="/', HTML );

      if curPos > 0 then
       Begin
        curPos := curPos + Length( 'pic="' );
        endPos := PosFrom( '"', HTML, curPos );
        ExtraLinks[ smPoster ] := BASE_URL + Trim( Copy( HTML, curPos, endPos - curPos ) );
       end;
     end;
   end;
 end;

 procedure ParseMovie( MovieURL : String; HTML : String );
 var
  curPos, endPos,    nextPos, startPos, lastPos, tB, P : Integer;

  tmp,    tmpstring, startSTR : String;

 begin
  P := 0;
  tmpstring := '';
  tmp := '';
  AddFieldValue( mfURL, Trim( MovieURL ) );

  zelluID := StringReplace( MovieURL, BASE_URL + mX[  1 ] + mX[  3 ], '', false, false, false );

  ParseOurLinks( MovieURL, HTML );

  //Title
  curPos := Pos( mX[ 16 ], HTML ) + Length( mX[ 16 ] );
  endPos := PosFrom( mX[ 17 ], HTML, curPos );
  tmpstring := Trim( Copy( HTML, curPos, endPos - curPos ) );

  if Length( tmpstring ) > 0 then
   Begin
    AddFieldValue( mfTitle, RemoveTags( tmpstring, false ) );
   end;

  tmpstring := '';
  startSTR := mX[ 18 ];
  startPos := Pos( startSTR, HTML );
  nextPos := PosFrom( mX[ 21 ], HTML, startPos );
  lastPos := PosFrom( mX[ 43 ], HTML, startPos );

  curPos := 0;
  //original Title
  curPos := Pos( mX[ 23 ], HTML ) + Length( mX[ 23 ] );

  if curPos > Length( mX[ 23 ] )then
   Begin
    endPos := PosFrom( mX[ 22 ], HTML, curPos );
    tmpstring := Trim( Copy( HTML, curPos, endPos - curPos ) );
    AddFieldValue( mfOrigTitle, tmpstring );
   end;

  //Country
  ParseCountries( HTML, startstr, mX[ 24 ] );

  //Genre
  ParseGenres( HTML, startstr, mX[ 24 ] );

  tmpstring := '';
  //Year
  curPos := PosFrom( mX[  9 ], HTML, startPos ) + Length( mX[  9 ] );
  endPos := PosFrom( mX[ 42 ], HTML, curPos );
  curPos := endPos - 4;
  tmpstring := Trim( Copy( HTML, curPos, endPos - curPos ) );

  if length( tmpstring ) > 0 then
   Begin
    AddFieldValue( mfYear, RemoveTags( tmpstring, false ) );
   end;

  if PERFORM_CUSTOMFIELDS then
   Begin
    AddCustomFieldValueByName( cf_idZELLU, zelluID );

    tmpstring := '';
    tmp := '';
    curPos := 0;
    P := 1;
    //FSK
    curPos := PosFrom( mX[ 25 ], HTML, startPos ) + Length( mX[ 25 ] );

    if curPos > Length( mX[ 25 ] )then
     Begin
      endPos := curPos + 5;
      tmpstring := Trim( Copy( HTML, curPos, endPos - curPos ) );

      if length( tmpstring ) > 0 then
       Begin
        if PosFrom( 'ohne', tmpstring, P ) > 0 then
         Begin
          tmp := 'ohne'
         end;

        if PosFrom( 'ab 6', tmpstring, P ) > 0 then
         Begin
          tmp := 'ab 6'
         end;

        if PosFrom( 'ab 12', tmpstring, P ) > 0 then
         Begin
          tmp := 'ab 12'
         end;

        if PosFrom( 'ab 16', tmpstring, P ) > 0 then
         Begin
          tmp := 'ab 16'
         end;

        if PosFrom( 'ab 18', tmpstring, P ) > 0 then
         Begin
          tmp := 'ab 18'
         end;

        AddCustomFieldValueByName( cf_FSK, RemoveTags( tmp, false ) );
       end;
     end;

    tmpstring := '';
    // Kinostart Deutschland
    curPos := Pos( mX[ 75 ] + mX[ 76 ] + mX[ 42 ], HTML );

    if curPos > 0 then
     Begin
      tB := PrevPos( mX[ 75 ], HTML, curPos ) + Length( mX[ 75 ] );
      endPos := PosFrom( mX[ 42 ], HTML, tB );
      tmpstring := Trim( Copy( HTML, tB, endPos - tB ) );
      AddCustomFieldValueByName( cf_KStartDE, tmpstring );
     end;
   end;

  tmpstring := '';
  tmp := '';
  //Budget
  curPos := PosFrom( '$', HTML, startPos );
  endPos := PosFrom( ' Budget', HTML, curPos );
  tmpstring := Trim( Copy( HTML, curPos, endPos - curPos ) );

  if length( tmpstring ) > 0 then
   Begin
    tmpstring := RemoveTags( tmpstring, false );

    if PERFORM_CUSTOMFIELDS then
     Begin
      AddCustomFieldValueByName( cf_BUDGET, tmpstring );
     end;

    tmp := StringReplace( tmpstring, '$', '', true, false, false );
    tB := Pos( 'Mio', tmp );

    if tB > 0 then
     Begin
      tB := 0;
      tmp := StringReplace( tmp, 'Mio', '', true, false, false );
      tmp := tmp + '000000';
     end;

    tmp := StringReplace( tmp, '.', '', true, false, false );
    tmp := Trim( StringReplace( tmp, ' ', '', true, false, false ) );

    if length( tmp ) > 0 then
     Begin
      AddFieldValueXML( 'BUDGET', tmp );
     end;
   end;

  tmpstring := '';
  //Duration
  curPos := PosFrom( 'ca.&nbsp;', HTML, startPos ) + Length( 'ca.&nbsp;' );
  endPos := PosFrom( '&nbsp;min', HTML, curPos );
  tmpstring := Trim( Copy( HTML, curPos, endPos - curPos ) );

  if length( tmpstring ) > 0 then
   Begin
    tmpstring := RemoveTags( tmpstring, false );
    tmpstring := IntToStr( StrToInt( tmpstring ) );
    AddFieldValue( mfDuration, tmpstring );
   end;

  tmpstring := '';
  //Rating
  startPos := Pos( mX[ 49 ], HTML );

  if startPos > 0 then
   Begin
    curPos := PosFrom( mX[ 50 ], HTML, startPos ) + Length( mX[ 50 ] );

    if curPos > 0 then
     Begin
      endPos := PosFrom( mX[ 40 ], HTML, curPos );
      tmpstring := Trim( HTMLToText( Copy( HTML, curPos, endPos - curPos ) ) );
      P := Pos( '.', tmpstring );

      if P > 0 then
       Begin
        tmpstring := Copy( tmpstring, 0, P );
       end;

      tmpstring := FloatToStr( StrToFloat( tmpstring ) / 10 );
     end;
   end;

  if length( tmpstring ) > 0 then
   Begin
    AddFieldValue( mfRating, tmpstring );
   end;

  tmpstring := '';
  //Description
  startPos := Pos( mX[ 47 ], HTML );
  curPos := startPos;
  tmpstring := TextBetween( HTML, mX[ 47 ], mX[ 48 ], true, startPos );

  if length( tmpstring ) > 0 then
   Begin
    AddFieldValue( mfDescription, tmpstring );
   end;
 end;

 procedure addCREWs( pI : Integer; HTML : String );
 var
  curPos, endPos,    urlendPos, startPos, itemStart, itemEnd, crewPos, pID, P : Integer;

  Person, jobMarker, JobX,      URL : String;

 begin
  P := 0;
  startPos := Pos( mX[ 30 ], HTML );

  if startPos < 1 then
   Exit;

  pID := getCrewMember( pI );
  JobX := getCrewJOB( pI );
  jobMarker := getCrewMarker( pI );
  crewPos := PosFrom( mX[ 36 ], HTML, startPos );
  itemStart := PosFrom( mX[ 31 ] + jobMarker, HTML, crewPos );

  if itemStart > 0 then
   Begin
    itemEnd := PosFrom( mX[ 39 ], HTML, itemStart );
    curPos := PosFrom( mX[  2 ] + mX[  3 ], HTML, itemStart );

    while( curPos > 0 ) AND ( curPos < itemEnd ) do
     Begin
      urlendPos := PosFrom( mX[ 41 ], HTML, curPos );
      URL := BASE_URL + Copy( HTML, curPos, urlendPos - curPos );
      curPos := PosFrom( mX[ 40 ], HTML, urlendPos ) + Length( mX[ 40 ] );
      endPos := PosFrom( mX[ 42 ], HTML, curPos );
      Person := Trim( RemoveTags( Copy( HTML, curPos, endPos - curPos ), false ) );
      AddMoviePerson( Person, '', ( JOB_PREFIX + JobX + JOB_SUFIX ), URL, pID );
      curPos := PosFrom( mX[  2 ] + mX[  3 ], HTML, endPos );
     end;
   end;
 end;

 procedure ParseDetail( MovieURL : String; HTML : String );
 var
  curPos, endPos, urlPos, urlendPos, startPos,  nextPos, chkPos, itemStart, actorPos, crewPos, studioPos, distriPos, lastPos, P : Integer;

  Person, Role,   Studio, partOF,    partTitle, partY,   URL : String;

 begin
  P := 0;
  startPos := Pos( mX[ 30 ], HTML );

  Studio := '';

  if startPos < 1 then
   Exit;

  actorPos := PosFrom( mX[ 35 ], HTML, startPos );
  crewPos := PosFrom( mX[ 36 ], HTML, startPos );
  studioPos := PosFrom( mX[ 37 ], HTML, startPos );
  distriPos := PosFrom( mX[ 28 ], HTML, startPos );
  lastPos := PosFrom( mX[ 43 ], HTML, startPos );
  P := 0;

  // Actors
  if ( actorPos > 0 ) AND ( crewPos > 0 ) then
   Begin
    curPos := PosFrom( mX[ 31 ], HTML, actorPos ) + Length( mX[ 31 ] );
    endPos := PosFrom( mX[ 39 ], HTML, actorPos );

    while( curPos > 0 ) AND ( curPos < crewPos ) do
     Begin
      endPos := PosFrom( mX[ 33 ], HTML, curPos );
      Role := Trim( RemoveTags( Copy( HTML, curPos, endPos - curPos ), false ) );
      curPos := PosFrom( mX[ 32 ], HTML, endPos ) + Length( mX[ 32 ] );
      endPos := PosFrom( mX[ 42 ], HTML, curPos );
      urlPos := PosFrom( mX[  2 ] + mX[  3 ], HTML, curPos );
      urlendPos := PosFrom( mX[ 41 ], HTML, urlPos );
      URL := BASE_URL + Copy( HTML, urlPos, urlendPos - urlPos );
      curPos := PosFrom( mX[ 40 ], HTML, urlendPos ) + Length( mX[ 40 ] );
      endPos := PosFrom( mX[ 42 ], HTML, curPos );
      Person := Trim( RemoveTags( Copy( HTML, curPos, endPos - curPos ), false ) );
      AddMoviePerson( Person, '', Role, URL, ctActors );
      curPos := PosFrom( mX[ 31 ], HTML, endPos ) + Length( mX[ 31 ] );
     end;
   end; // Actors

  addCREWs( 1, HTML ); //Directors  
  addCREWs( 2, HTML ); //Writers 
  addCREWs( 3, HTML ); //Composers  
  addCREWs( 4, HTML ); //Producers

  if ADD_EXTRA_CREDITS then
   Begin
    addCREWs( 5, HTML );  //Cinematographer  
    addCREWs( 6, HTML );  //Cutter  
    addCREWs( 7, HTML );  //Book Author  
    addCREWs( 8, HTML );  //Costume Designer
    addCREWs( 9, HTML );  //assistant director  
    addCREWs( 10, HTML ); //stunts              
    addCREWs( 11, HTML ); //visual effects      
    addCREWs( 12, HTML ); //special effects     
    addCREWs( 13, HTML ); //second unit director
    addCREWs( 14, HTML ); //miscellaneous crew  
    addCREWs( 15, HTML ); //stunt coordinator   
    addCREWs( 16, HTML ); //sound editor        
    addCREWs( 17, HTML ); //sound-design        
    addCREWs( 18, HTML ); //set decorator       
    addCREWs( 19, HTML ); //Make-Up
   end; // ADD_EXTRA_CREDITS

  //Studios
  itemStart := PosFrom( mX[ 30 ], HTML, studioPos );

  if ( itemStart > 0 ) AND ( itemStart < distriPos ) then
   Begin
    curPos := itemStart + Length( mX[ 34 ] );

    while( curPos > 0 ) AND ( curPos < distriPos ) do
     Begin
      endPos := PosFrom( mX[ 44 ], HTML, curPos );
      Studio := Trim( RemoveTags( Copy( HTML, curPos, endPos - curPos ), false ) );
      AddFieldValue( mfStudio, Studio );
      curPos := PosFrom( mX[ 34 ], HTML, endPos ) + Length( mX[ 34 ] );
     end;
   end; //Studios

  //continued of, followed by
  if ADD_FOLLOWINGS then
   Begin
    itemStart := 0;

    if ( Pos( mX[ 59 ], HTML ) > 0 ) then
     Begin
      itemStart := Pos( mX[ 59 ], HTML );
      endPos := PosFrom( mX[ 60 ], HTML, itemStart );
     end;

    if ( Pos( mX[ 61 ], HTML ) > 0 ) then
     Begin
      itemStart := Pos( mX[ 61 ], HTML );
      endPos := PosFrom( mX[ 41 ], HTML, itemStart );
     end;

    if itemStart > 0 then
     Begin
      partOF := getCrewJOB( 40 );
      itemStart := PosFrom( mX[ 62 ], HTML, endPos ) + Length( mX[ 62 ] );
      lastPos := PosFrom( mX[ 48 ], HTML, itemStart );
      urlPos := PosFrom( mX[ 46 ], HTML, itemStart ) + Length( mX[ 46 ] );
      urlendPos := PosFrom( mX[ 41 ], HTML, urlPos );

      while( urlPos > 0 ) AND ( urlPos < lastPos ) do
       Begin
        partY := '';
        URL := BASE_URL + Copy( HTML, urlPos, urlendPos - urlPos );
        curPos := PosFrom( mX[ 40 ], HTML, urlendPos ) + Length( mX[ 40 ] );
        endPos := PosFrom( mX[ 42 ], HTML, curPos );
        partTitle := Trim( Copy( HTML, curPos, endPos - curPos ) );
        nextPos := PosFrom( mX[ 58 ], HTML, endPos + Length( mX[ 42 ] ) );
        chkPos := PosFrom( mX[ 46 ], HTML, urlendPos );
        curPos := PosFrom( ')', HTML, urlendPos ) - 4;
        endPos := PosFrom( ')', HTML, curPos );

        if ( nextPos < lastPos ) AND ( nextPos < chkPos ) AND ( curPos < nextPos ) then
         Begin
          partY := Trim( Copy( HTML, curPos, endPos - curPos ) );
          P := StrToInt( partY );

          if ( P < 1900 ) OR ( P > 2100 ) then
           partY := '';
         end;

        AddConnection( partTitle, '', partOF, URL, partY );
        urlPos := PosFrom( mX[ 46 ], HTML, urlendPos ) + Length( mX[ 46 ] );
        urlendPos := PosFrom( mX[ 41 ], HTML, urlPos );
       end;
     end;
   end; //continued of, followed by 
 end; // procedure ParseDetail

 procedure ParseLinks( MovieURL : String; HTML : String );
 var
  curPos,    endPos, urlPos, startPos, lastPos : Integer;

  tmpstring, IMDbID, IMDbPage : String;

 begin
  tmpstring := '';
  startPos := Pos( mX[ 51 ], HTML );
  lastPos := Pos( mX[ 52 ], HTML );
  curPos := PosFrom( mX[ 21 ], HTML, startPos );
  endPos := PosFrom( mX[ 40 ], HTML, curPos ) + 1;
  curPos := endPos;

  // IMDB LINK
  urlPos := PosFrom( mX[ 53 ], HTML, curPos );

  if urlPos > 0 then
   Begin
    urlPos := urlPos + Length( mX[ 53 ] );
    endPos := PosFrom( mX[ 41 ], HTML, urlPos );
    tmpstring := Trim( Copy( HTML, urlPos, endPos - urlPos ) );
    IMDbID := StringReplace( tmpstring, '/', '', true, false, false );
   end;

  // or alternate IMDB LINK
  urlPos := PosFrom( mX[ 54 ], HTML, curPos );

  if urlPos > 0 then
   Begin
    urlPos := urlPos + Length( mX[ 54 ] );
    endPos := PosFrom( mX[ 41 ], HTML, urlPos );
    tmpstring := Trim( Copy( HTML, urlPos, endPos - urlPos ) );
    IMDbID := StringReplace( tmpstring, '/', '', true, false, false );
   end;

  if ( Length( IMDbID ) > 3 ) AND ( Length( IMDbID ) < 10 ) then
   Begin
    if PERFORM_CUSTOMFIELDS then
     Begin
      AddCustomFieldValueByName( cf_idIMDB, IMDbID );
     end;

    IMDbPage := 'http://www.imdb.com/title/tt' + IMDbID;
    AddFieldValue( mfURL, Trim( IMDbPage ) );
   end;

  if ADD_OFFICIAL_URLS then
   Begin
    urlPos := PosFrom( mX[ 56 ], HTML, curPos );

    if urlPos > 0 then
     Begin
      while( urlPos > 0 ) AND ( urlPos < lastPos ) do
       Begin
        urlPos := PosFrom( mX[ 57 ], HTML, urlPos ) + Length( mX[ 57 ] );
        endPos := PosFrom( '</DIV>', HTML, urlPos );
        tmpstring := Trim( Copy( HTML, urlPos, endPos - urlPos ) );

        if Length( tmpstring ) > 0 then
         Begin
          AddFieldValue( mfURL, 'http://' + RemoveTags( tmpstring, false ) );
         end;

        urlPos := PosFrom( mX[ 56 ], HTML, endPos );
       end;
     end;
   end;
 end; // procedure ParseLinks

 function getPreisEvent( preis : String ) : String;
 var
  eventX : String;

 begin
  eventX := preis;

  case preis of
   'Oscar' : eventX := 'Academy Awards, USA';
   'Golden Globe' : eventX := 'Golden Globe Awards, USA';
   'Goldener Bär' : eventX := 'Internationale Filmfestspiele Berlin';
   'Deutsche Filmpreis' : eventX := 'Deutsche Filmpreis (Berlin)';
   'Razzies' : eventX := 'Goldene Himbeere - Razzie Award';
  end;

  Result := eventX;
 end;

 procedure ParsePreise( MovieURL : String; HTML : String );
 var
  curPos,  endPos, urlPos,  urlendPos, startPos, lastPos, nextStart, nextEnd : Integer;

  tmpstring, pURL,  awEvent, pName, awName,  awCat,  awYear,  awHTML : String;

  awWon : Boolean;

 begin
  if Pos( 'keine Informationen über Auszeichnungen', HTML ) > 0 then
   Exit;

  if not Pos( '/directory/awards.php3?id=', HTML ) > 0 then
   Exit;

  startPos := Pos( mX[ 64 ], HTML );

  if startPos < 1 then
   Exit;

  lastPos := PosFrom( mX[ 43 ], HTML, startPos );
  nextStart := PosFrom( mX[ 65 ], HTML, startPos );
  nextStart := PosFrom( mX[ 40 ], HTML, nextStart ) + Length( mX[ 40 ] );
  nextEnd := PosFrom( mX[ 66 ], HTML, nextStart );

  while( nextStart > startPos ) AND ( nextStart < lastPos ) do
   Begin
    awWon := false;
    awHTML := '';
    tmpstring := '';
    awName := '';
    awYear := '';
    pURL := '';
    pName := '';
    awCat := '';
    awHTML := Copy( HTML, nextStart, nextEnd - nextStart );
    curPos := 1;

    if Pos( mX[ 67 ], awHTML ) > 0 then
     Begin
      curPos := PosFrom( mX[ 67 ], awHTML, curPos );
      curPos := PosFrom( mX[ 40 ], awHTML, curPos ) + Length( mX[ 40 ] );
     end;

    curPos := PosFrom( mX[ 68 ], awHTML, curPos );
    curPos := PosFrom( mX[ 40 ], awHTML, curPos ) + Length( mX[ 40 ] );
    endPos := PosFrom( ':' + mX[ 69 ], awHTML, curPos );
    tmpstring := Copy( awHTML, curPos, endPos - curPos );
    awName := Trim( Copy( tmpstring, 0, ( Length( tmpstring ) - 4 ) ) );
    awYear := Trim( StringReplace( tmpstring, awName, '', true, false, false ) );
    curPos := PosFrom( mX[ 70 ], awHTML, endPos ) + Length( mX[ 70 ] );
    endPos := PosFrom( mX[ 71 ], awHTML, curPos );
    awCat := Trim( Copy( awHTML, curPos, endPos - curPos ) );
    awEvent := getPreisEvent( awName );

    if Pos( mX[ 72 ], awHTML ) > 0 then
     awWon := true;

    if Pos( mX[ 73 ], awHTML ) > 0 then
     awWon := false;

    if Pos( mX[ 74 ], awHTML ) > 0 then
     Begin
      curPos := PosFrom( mX[ 74 ], awHTML, endPos ) + Length( mX[ 74 ] );
      urlPos := PosFrom( mX[ 68 ], awHTML, curPos );
      urlendPos := PosFrom( mX[ 69 ], awHTML, urlPos );

      while( urlPos > 0 ) do
       Begin
        endPos := PosFrom( mX[ 40 ], awHTML, urlPos ) + Length( mX[ 40 ] );
        pName := Trim( Copy( awHTML, endPos, urlendPos - endPos ) );
        AddAward( awEvent, awName, awCat, pName, awYear, awWon );
        urlPos := PosFrom( mX[ 68 ], awHTML, urlendPos );
        urlendPos := PosFrom( mX[ 69 ], awHTML, urlPos );
       end;
     end
    else
     Begin
      AddAward( awEvent, awName, awCat, '', awYear, awWon );
     end;

    nextStart := PosFrom( mX[ 65 ], HTML, nextEnd ) + Length( mX[ 65 ] );
    nextStart := PosFrom( mX[ 40 ], HTML, nextStart ) + Length( mX[ 40 ] );
    nextEnd := PosFrom( mX[ 66 ], HTML, nextStart );
   end;
 end;

 procedure ParseSearchResults( HTML : String );
 var
  curPos,    iconPos,    endPos, nextPos, isPos : Integer;

  tmpstring, tmpstringa, Title,  Year,    URL,
  strID,     orgTitle : String;

 begin
  curPos := Pos( mX[ 12 ], HTML );

  if curPos < 1 then
   Exit;

  endPos := PosFrom( mX[ 44 ], HTML, curPos );
  iconPos := PosFrom( mX[ 13 ], HTML, curPos );
  nextPos := PosFrom( mX[ 39 ], HTML, iconPos );
  curPos := PosFrom( mX[  8 ], HTML, iconPos );

  while iconPos > 0 do
   Begin
    isPos := PosFrom( mX[ 14 ], HTML, curPos ) + Length( mX[ 14 ] );
    endPos := PosFrom( mX[ 15 ], HTML, isPos );
    strID := Copy( HTML, isPos, endPos - isPos );
    URL := BASE_URL + mX[  1 ] + mX[  3 ] + strID;
    curPos := PosFrom( mX[ 40 ], HTML, endPos ) + Length( mX[ 40 ] );
    endPos := PosFrom( mX[ 44 ], HTML, curPos );
    isPos := PosFrom( mX[ 20 ], HTML, curPos ) + Length( mX[ 20 ] );
    tmpstring := Copy( HTML, curPos, endPos - curPos ) + mX[ 44 ];
    endPos := PosFrom( mX[ 39 ], HTML, curPos );
    tmpstringa := Copy( HTML, isPos, endPos - isPos );

    if ( isPos > curPos ) AND ( isPos < endPos ) then
     Title := Trim( RemoveTags( tmpstring, false ) ) + ' Orig: ' + Trim( RemoveTags( tmpstringa, false ) );

    if ( isPos < curPos ) OR ( isPos > endPos ) then
     Title := Trim( RemoveTags( tmpstring, false ) );

    AddSearchResult( Title, orgTitle, Year, URL, '' );
    iconPos := PosFrom( mX[ 13 ], HTML, nextPos );
    nextPos := PosFrom( mX[ 39 ], HTML, iconPos );
    curPos := PosFrom( mX[  8 ], HTML, iconPos );
   end;
 end;

 function NextMode( curMode : Integer ) : Integer;
 var
  I : Integer;

 begin
  Result := smFinished;

  if curMode < Low( ExtraLinks ) - 1 then
   curMode := Low( ExtraLinks ) - 1;

  for I := curMode + 1 to High( ExtraLinks )do
   if ExtraLinks[ I ] <> '' then
    Begin
     Result := I;
     Break;
    end;
 end;

 function ParsePage( HTML : String; URL : AnsiString ) : Cardinal;
 begin
  if not mXInit then
   Begin
    initMX( );
    mXInit := true;
   end;

  if Pos( '<title>Suche nach', HTML ) > 0 then
   Begin
    ParseSearchResults( HTML );
    Result := prList;
    Exit;
   end
  else
   if Pos( '<B>Zu diesem Suchbegriff wurde leider nichts gefunden.</B>', HTML ) > 0 then
    Begin
     Result := prError;
     Exit;
    end
   else
    if Pos( 'User-Wertung:', HTML ) > 0 then
     ParseMovie( URL, HTML )
    else
     if Pos( 'alt="Besetzung"', HTML ) > 0 then //
      ParseDetail( URL, HTML )
     else
      if Pos( ': Links  | zelluloid.de</title>', HTML ) > 0 then
       ParseLinks( URL, HTML )
      else
       if Pos( ': Auszeichnungen  | zelluloid.de</title>', HTML ) > 0 then
        ParsePreise( URL, HTML )
       else
        if Pos( '<title>zelluloid.de - Das Kinoportal (Kinomagazin', HTML ) > 0 then
         Begin
          Mode := Mode + 1;
         end;

  Mode := NextMode( Mode );

  if Mode <> smFinished then
   Result := prDownload
  else
   Result := prFinished;
 end;

begin
 Mode := smSearch;

 for ELI := Low( ExtraLinks )to High( ExtraLinks )do ExtraLinks[ ELI ] := '';
end
.
