const
	script_name='kinopoisk';
	language='Russian';
	version=110; // Delphi XE
	author='Alex';
	MinProgramBuild=6200;
	PCount = 12;
	//MaxPicturesCount = 3;
	
	REMOVE_ROLE_DESC = True; //удаление "ролей" типа озвучка, короткометражка и т.п.
  EMPTY_PERSON_IMAGE_URL = 'http://st.kinopoisk.ru/images/no-poster.gif';
	
var
	DownloadPersonBiography, DownloadPersonAdditionalInfo, DownloadPersonAwards: boolean;
	MaxPhotosCount: integer;

	photos_count: Integer;
	persons_count: integer;
	persons: array of string;
	imdb_codes, photo_index: array of string;
	imdb_code, person_code: string;
	name, code, year, description, awards: string;
	person, BasicURL, biography, trivia, character, birth_date, death_date, birthplace, birth_name, salary, height, original_name, person_site_url: string;
	photo_url, awards_url: string;
	monthes: array [1..12] of string;
	prefixes: array [1..PCount] of string;
	person_height: integer;
	is_photos_present: boolean;
	f: TForm;
	b: TButton;
	edUserName, edPassword, edURL: TEdit;
	labCaption, labCaption2, labUserName, labPassword: TLabel;

  RequestParameters: TStringList;
  
function GetStr(str: String; s1: String; s2: String): String;
var
  I: Integer;
  J: Integer;
begin
  // Вырезает кусок строки между s1 и s2
	Result := '';
	I := Pos(s1, str);
	if I > 0 then
	begin
		J := MyPos(s2, str, I + Length(s1));
		if J > 0 then
  		Result := Copy(str, I + Length(s1), J - I - Length(s1));
	end;
end;

function GetPersonImageURL(ACode: string): string;
begin
  Result := '';
  if (Trim(ACode) <> '') then begin
	if RegReadInteger('KinopoiskDlBiggerPhoto', 1) = 1 then
		Result := Format('http://st3.kinopoisk.ru/images/actor_iphone/iphone360_%s.jpg', [ACode])
	else
		Result := Format('http://st3.kinopoisk.ru/images/actor/%s.jpg', [ACode]);
  end;
end;

function GetSearchURLbyName(PersonName: string): string;
var
	url: string;
begin
	if PersonName = 'setup' then begin
		ShowScriptOptions;
		result := 'setup';
	end
	else begin
		PersonName := EncodeURL(PersonName, 'WINDOWS-1251');
		url:=format('http://www.kinopoisk.ru/index.php?level=7&from=forma&result=adv&m_act%%5Bfrom%%5D=forma&m_act%%5Bwhat%%5D=actor&m_act%%5Bfind%%5D=%s&m_act%%5Bbirthday%%5D%%5Byear%%5D=&m_act%%5Bfilm%%5D=&m_act%%5Bsex%%5D=&m_act%%5Bwork%%5D=&m_act%%5Bcontent_find%%5D=', [PersonName]);
		url:=ReplaceStr(url, ' ', '+', -1);
		result:=url;
	end;
end;

//Download search results from URL
function DownloadSearchURL(url: string): integer;
begin
	if url = 'setup' then 
		result := -1
	else begin
		//all:=DownloadURL(url);
		//all:=DownloadURLWithReferer(url, 'http://s.kinopoisk.ru');
		all:=DownloadURLWithReferer(url, 'http://s.kinopoisk.ru/index.php', true, RequestParameters);

		if pos('Если вы видите эту страницу', all)>0 then
			all:=DownloadURL(url, true, RequestParameters);

		//если требуется авторизация
		if GetResponseCode=403 then begin
			SiteLogin;
			all:=DownloadURL(url, true, RequestParameters);
		end;

		if all='-1' then
			result:=-1
		else
			result:=PersonSearch;
	end;
end;

function RemoveAllBadChars(text: String): String;
var
	i: Integer;
begin
	i := 0;
	while i<=Length(text) do begin
		if ord(text[i]) in [1..20] then
			delete(text, i, 1)
		else
			i := i + 1;
	end;
	result := text;
end;

function PersonSearch: integer;
var
	i, j, k, l: integer;
	url, person, code, year, original_name, small_photo, s, s2: string;
begin
	persons_count:=0;
	
	i:=pos('К сожалению, по вашему запросу ничего не найдено', all);

	if (all='') or (i>0) then
		// Фильм не найден!
	else 
	begin
		i:=pos('<title>Результаты поиска',all);
		if i>0 then
		begin
		
			s:='';
			i:=pos('<p class="pic"><a href="', all);
			while (i>0) do begin
				j := MyPos('</div>', all, i+1);
				s := copy(all, i, j-i);
				code:=ParseString(s, '<p class="pic"><a href="/level/4/people/(\d+)/', 1);
				if code = '' then
					code:=ParseString(s, '<p class="pic"><a href="http://www.kinopoisk.ru/level/4/people/(\d+)/', 1);
				person:=ParseString(s, '<p class="name">(.*?)</a> <span', 1);
				if person='' then
					person:=ParseString(s, '<p class="name">(.*?)</a></p>', 1);
				person:=RemoveTags(person);
				person:=DecodeHTML(person);
				person:=ClearExtraSpaces(person);
				
				year := ParseString(s, '<span class="year">(\d+)</span></p>', 1);
				if year = '' then begin
					year := ParseString(s, '<span class="year">(.*?)</span></p>', 1);
					year := DecodeHTML(year);
				end;

				small_photo := ParseString(s, '<img src="(.*?)" alt="', 1);
				
				original_name := '';
				k := Pos('<span class="gray">', s);
				if k>0 then begin
					l := MyPos('</span>', s, k+1);
					s2 := copy(s, k, l-k);
					original_name := RemoveTags(s2);
					original_name := DecodeHTML(original_name);
				end;
				
				description := '';
				if l>0 then begin
					delete(s, 1, l-1);
					description := RemoveTags(s);
					description := DecodeHTML(description);
					description:=ReplaceStr(description, #10, ' ', -1);
					description := ClearExtraSpaces(description);
					description := RemoveAllBadChars(description);
					//удаление пробелов перед возрастом
					if (Pos(' год', description)>0) or (Pos(' лет', description)>0) then begin
						k := Pos('  ', description);
						description[k] := ';';
						k := Pos('  ', description);
						while k>0 do begin
							delete(description, k, 1);
							k := Pos('  ', description);
						end;
					end;
				end;

				if (person <> '') and (code <> '') then begin
					persons_count:=persons_count+1;
					SetLength(persons, persons_count);
					SetSearchResult2(person, code, year, original_name, description, small_photo);
				end;
				delete(all, 1, j);
				i:=pos('<p class="pic"><a href="', all);	

			end;
		end
		else
		begin
			i:=pos('<title>',all);
			j:=pos('</title>',all);
			if (i>0)and(j>0) then
			begin
				i:=i+7;
				person := copy(all,i,j-i);
				person := DecodeHTML(person);
				person := RemoveTags(person);
				person := ClearExtraSpaces(person);
				i := Pos('<td class="type">карьера</td><td><a href="/level/4/people/',all);
				if i>0 then
				begin
					i := i + 58;
					j := MyPos('/',all,i+1);
					code := copy(all,i,j-i);
				end
				else begin
					code := GetStr(all, '<link rel="canonical" href="http://www.kinopoisk.ru/name/', '/');
				end;
				if (person <> '') and (code <> '') then begin
					persons_count := persons_count + 1;
					SetLength(persons, persons_count);
					persons[persons_count-1]:=code;
					SetSearchResult(person, code);
				end;
			end;
		end;
	end;
	result:=persons_count;
end;

function GetPersonURL(code: string; images_only: boolean): string;
begin
	if images_only then
		result:=format('http://www.kinopoisk.ru/level/4/people/%s/', [code])
	else
		result:=format('http://www.kinopoisk.ru/level/4/people/%s/', [code])
end;

procedure Shuffle;
var
  randomIndex, len: integer;
  cnt: integer;
  tmp : String;
begin
  Randomize;
  randomIndex := 0;
  len := length(photo_index);
  for cnt := 0 to len-1 do
  begin
    randomIndex := Trunc((len-cnt) * Random);
    tmp := photo_index[cnt];
    photo_index[cnt] := photo_index[cnt + randomIndex];
    photo_index[cnt +  randomIndex] := tmp;
  end;
end;

// get person photos
procedure GetPhotos(photos_loaded: Integer);
var
	url, s, s2, s3, photo_url, img_code, latin_name, next_page: string;
	i, j, k, page, my_index, il: Integer;
	ShuffleAllPhotos: Boolean;
begin
	url := 'http://www.kinopoisk.ru/level/13/people/'+person_code+'/';

  s := GetHTMLPageContentFromRequest(url);
	if (s <> '')and(s <> '-1') then
	begin
		photos_count := 0;
		i := pos('href="/picture/', s);
		if i>0 then
    begin
			i := MyPos('"', s, i+1);
			j := MyPos('"', s, i+1);
			s2 := copy(s, i+1, j-i-1);
			img_code := ParseString(s2, '\/picture\/(\d+)\/', 1);
			//download a page showing a big photo to get the filename pattern
			if s2<>'' then
        s2 := GetHTMLPageContentFromRequest('http://www.kinopoisk.ru' + s2);
		end;
	end;
	k := photos_loaded;
	for i := 0 to Length(photo_index) - 1 do begin
		if (k < MaxPhotosCount) and (Pos('/js/', photo_index[i]) = 0) then begin
			SetImageName('', photo_index[i], '', 6);
			//ShowMessage(photo_index[i]);
			k := k + 1;
		end;
	end;
end;

//returned images links
procedure GetImages;
var
	i : Integer;
begin
	i := 0;
	if (photo_url<>'') then begin
		SetImageName('', photo_url, '', 6);
		i := 1;
	end;
	if is_photos_present and (MaxPhotosCount>0) then
		GetPhotos(i);
end;

function SavePhoto(url, FileName: string): boolean;
var
	fs: TFileStream;
	s, referer: string;
	i: integer;
begin
	i := length(url);
	repeat
		dec(i)
	until (i=0) or (url[i] = '/');
	if i=0 then 
		exit;
	referer := copy(url, 1, i);
	s := DownloadURLWithReferer(url, referer, false, RequestParameters);
	//i := pos('?',FileName);
	//if i>1 then
	//	FileName := copy(FileName,1,i-1);
	if (length(s)>100) and (s<>'-1') then begin
		try
			fs:=TFileStream.Create(FileName, fmCreate);
			fs.Write(s, Length(s));
			fs.Free;
			result:=true;
		except
			result:=false;
		end;
	end
	else
		result:=false;
end;

function MovePrefixLeft(name: string): string;
var
	i, j: integer;
begin
	// replace "The", "A", "An"... to the left
	for j:=1 to PCount do
	begin
		i:=pos(', '+Prefixes[j], name);
		if i>0 then
			if (i = length(name)-length(Prefixes[j])-1) or
			(length(name) >= i+2+length(Prefixes[j])) and (name[i+2+length(Prefixes[j])]=':') then
			begin
				if Prefixes[j][length(Prefixes[j])] = '''' then
					name := Prefixes[j] + copy(name, 1, i-1) + copy(name, i+length(Prefixes[j])+2, length(name)-i-length(Prefixes[j])-2+1)
				else
					name := Prefixes[j]+' ' + copy(name, 1, i-1) + copy(name, i+length(Prefixes[j])+2, length(name)-i-length(Prefixes[j])-2+1);
				break;
			end;
	end;
	Result := name;
end;

function ClearBrackets(name: string): string;
var
	i: integer;
begin
	// clear word in brackets at the end of name
	i := pos(' (', name);
	if i>0 then
		name := copy(name, 1, i-1);
	Result := name;
end;

function ClearExtraQuotes(name: string): string;
begin
// Clears extra quotes «"»
	if length(name)>0 then
		if (name[1]='"') and (name[length(name)]='"') then
			name := copy(name,2,length(name)-2);
	{if (name[1]='''') and (name[length(name)]='''') then
		name := copy(name,2,length(name)-2);}
	Result := name;
end;

function ClearExtraBlankCharacters(text: string): string;
begin
	// Clear all extra blank charackters
	while (length(text) > 0) and (ord(text[1]) in [1..20, 32]) do
		delete(text, 1, 1);
	while (length(text) > 0) and (ord(text[length(text)]) in [1..20, 32]) do
		delete(text, length(text), 1);
	Result := text;
end;

procedure ExtractSpouses();
const
  SEPARATOR_SPOUSE = '<br />';
var
  I: Integer;
  K: Integer;
  NextBRPos: Integer;
  Spouses: string;
  SingleSpouse: string;
  ChildrenText: string;

  PersonURL: string;
  PersonName: string;
  PersonCode: string;
  PersonStatus: Integer;
  PersonStatusStr: string;
  ChildrenCount: integer;
  WasLastPersonParsed: Boolean;
begin
  WasLastPersonParsed := False;
  I := Pos('<td class="type">супруг', all);
  if (I > 0) then
  begin
    I := MyPos('<td ', all, I + 1);
    K := MyPos('</td>', all, I);
    if ((I > 0) and
        (K > 0)) then
    begin
      //I := I + 4;
      Spouses := Copy(all, I, K - I);
      I := Pos(SEPARATOR_SPOUSE, Spouses);
      repeat
        if ((I > 0) and (not WasLastPersonParsed)) then
          I := I + Length(SEPARATOR_SPOUSE);
        ChildrenCount := 0;
        NextBRPos := MyPos(SEPARATOR_SPOUSE, Spouses, I);
        if (NextBRPos = 0) then
          NextBRPos := Length(Spouses) + 1;
        if (NextBRPos > 0) then
        begin
          ChildrenText := Copy(Spouses, I, NextBRPos - I);
          if (Pos('ребенок', ChildrenText) > 0) then
          begin
            ChildrenCount := 1;
            I := NextBRPos + Length(SEPARATOR_SPOUSE);
          end
          else if (Pos('детей', ChildrenText) > 0) then
          begin
            if Pos('двое', ChildrenText) > 0 then
              ChildrenCount := 2
            else if Pos('трое', ChildrenText) > 0 then
              ChildrenCount := 3
            else if Pos('четверо', ChildrenText) > 0 then
              ChildrenCount := 4
            else if Pos('пятеро', ChildrenText) > 0 then
              ChildrenCount := 5
            else if Pos('шестеро', ChildrenText) > 0 then
              ChildrenCount := 6
            else
              ChildrenCount := 7;
            I := NextBRPos + Length(SEPARATOR_SPOUSE);
          end;
        end;
        SingleSpouse := Copy(Spouses, 1, I - 1);
        Delete(Spouses, 1, I - 1);
        PersonName := '';
        PersonCode := '';
        PersonStatusStr := '';
        PersonStatus := 1;
        // parse spouse parameters
        I := Pos('name/', SingleSpouse);
        if (I > 0) then
        begin
          I := I + Length('name/');
          PersonCode := Copy(SingleSpouse, I, MyPos('/', SingleSpouse, I) - I);
          I := Pos('>', SingleSpouse);
          if (I > 0) then
            Delete(SingleSpouse, 1, I);
        end;
        I := Pos('</a>', SingleSpouse);
        if (I > 0) then
          SingleSpouse := Copy(SingleSpouse, 1, I - 1)
        else
        begin
          I := Pos(SEPARATOR_SPOUSE, SingleSpouse);
          if (I > 0) then
            SingleSpouse := Copy(SingleSpouse, 1, I - 1);
        end;
        PersonName := SingleSpouse;
        if (Pos('(', PersonName) > 0) then
        begin
          PersonStatusStr := Trim(Copy(PersonName, Pos('(', PersonName) + 1, Length(PersonName)));
          if (Pos(')', PersonStatusStr) > 0) then
            PersonStatusStr := Trim(Copy(PersonStatusStr, 1, Pos(')', PersonStatusStr) - 1));
          PersonName := Copy(PersonName, 1, Pos('(', PersonName) - 1);
          if (Pos('развод', PersonStatusStr) > 0) then
            PersonStatus := 2
          else if (Pos('умер', PersonStatusStr) > 0) then
            PersonStatus := 3
          else if (Pos('аннулирован', PersonStatusStr) > 0) then
            PersonStatus := 5;
        end;
        if (PersonName <> '') then
        begin
          PersonURL := '';
          if (Trim(PersonCode) <> '') then
            PersonURL := GetPersonURL(PersonCode, False);
		  PersonName := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(PersonName)));
          SetPersonSpouse(PersonName, PersonCode, '', '', ChildrenCount, PersonStatus,
            PersonURL, GetPersonImageURL(PersonCode));
        end;
        I := Pos(SEPARATOR_SPOUSE, Spouses);
        // will be paranoic - check WasLastPersonParsed to avoid infinite loop on kinopoisk format changing
        if ((I = 0) and
            (not WasLastPersonParsed)) then
        begin
          I := Length(Spouses) + 1;
          WasLastPersonParsed := True;
        end;
      until (I = 0);
    end;
  end;
end;

procedure ExtractMovies(start, mode: Integer);
const
	no_character=['короткометражка', 'озвучка'];
var
	i, j, k, l: Integer;
	s, s2, s3, code, name, character, original_title: String;
begin
	i:=MyPos('class="personPageItems"', all, start+1);
	j:=MyPos('<spacer type="block"', all, i+1);
	if j=0 then
		j := Length(all);
	s2:=copy(all, i, j-i);
	//i:=pos('<div class="item">', s2);
	i:=pos('<table><tr><td>', s2);
	while i>0 do begin
		l := MyPos('</table>', s2, i+1);
		s3:=copy(s2, i, l-i);
		//ShowMessage(s3);

		code:=ParseString(s3, '<a href="/film/(\d+)/"', 1);
		if code = '' then
			code:=ParseString(s3, '<a href="http://www.kinopoisk.ru/film/(\d+)/"', 1);
		if code = '' then
			code := ParseString(s3, 'href="/level/1/film/(\d+)/"', 1);


		name:=ParseString(s3, '/film/\d+/">(.*?)</a>', 1);

		//4.06.13
		//if name = '' then
			//name := GetStr(s3, '<span class="name">', '</a>');

		if name = '' then
			name:=ParseString(s3, '/film/\d+/".*?>(.*?)</a>', 1);

		year := ParseString(name, 'nbsp;\((\d+)\)$', 1);

		if year='' then
			year := ParseString(name, ' \((\d+)\)$', 1);
		if year='' then
			year := ParseString(name, ' \(сериал, (\d+)', 1);
		if year='' then
			year := ParseString(name, ' \(ТВ, (\d+)', 1);
		if year='' then
			year := ParseString(name, ' \(мини-сериал, (\d+)', 1);
		if year='' then
			year := ParseString(name, ' \(видео, (\d+)', 1);

		//year:=ParseString(s3, '/level/10/m_act%5Byear%5D/(\d+)/">', 1);
		if year = '' then begin
			s:=ParseString(s3, '/level/1/film/(.*?)</a>', 1);
			if s='' then
				s := ParseString(s3, '<a href="/film/(.*?)</a>', 1);
			if s='' then
				s:=ParseString(s3, '/level/1/film/(.*?) -', 1);
			j := Pos('nbsp;', s);
			delete(s, 1, j-1);
			year := ParseString(s, 'nbsp;\((\d+)\)$', 1);
			if year='' then
				year := ParseString(s, 'nbsp;\((\d+)-', 1);
		end;
		if name<>'' then begin
			name := RemoveTags(name);
			i := Pos('(', name);
			if i>0 then
				delete(name, i, length(name)-i+1);
			name := DecodeHTML(name);
			name := ClearBrackets(name);
			name := ClearExtraSpaces(name);
			name := MovePrefixLeft(name);
			i:=Pos('(', s3);
			delete(s3, 1, i);
			//character
			character:='';
			if mode = 3 then begin
				j:=pos('&nbsp;...&nbsp;', s3);
				if j>0 then begin
					k:=MyPos('</td>', s3, j+1);
					if k>0 then begin
						character:=copy(s3, j+9, k-j-9);
					end
				end;
				character:=RemoveTags(character);
				character:=ClearExtraBlankCharacters(DecodeHTML(character));
				if REMOVE_ROLE_DESC then begin
					for i:=0 to length(no_character)-1 do begin
						if character = no_character[i] then
							character := '';
						j := Pos(Format('; %s', [no_character[i]]), character);
						if j>0 then
							delete(character, j, length(character)-j+1);
						j := Pos(Format(', %s', [no_character[i]]), character);
						if j>0 then
							delete(character, j, length(character)-j+1);
					end;
				end;
			end;
			//original_title
			original_title:=ParseString(s3, '<font color="#aaaaaa">(.*?)</font>', 1);
			if original_title <> '&nbsp;&nbsp;' then
				begin
					original_title := DecodeHTML(original_title);
					original_title := RemoveTags(original_title);
					original_title := ClearExtraSpaces(original_title);
					original_title := ClearExtraQuotes(original_title);
					original_title := ClearBrackets(original_title);
					original_title := MovePrefixLeft(original_title);
				end
				else
					original_title := '';

				SetMovieName(name, character, mode, code, year); // ВКЛЮЧИТЬ original_title !!!!!!
		end;
		delete(s2, 1, l);
		//i:=pos('<div class="item">', s2);
		i:=pos('<table><tr><td>', s2);
	end;
end;

procedure OnPhotosPageLoaded(AContent: string);
var
	i, j: Integer;
	s, s2: string;
begin
  s := AContent;
	if (s <> '')and(s <> '-1') then
	begin
		i := pos('href="/picture/', s);
		if i>0 then
    begin
			i := MyPos('"', s, i+1);
			j := MyPos('"', s, i+1);
			s2 := copy(s, i+1, j-i-1);
			//download a page showing a big photo to get the filename pattern
			if s2<>'' then
      begin
        AddRequestForHTMLPageContent('http://www.kinopoisk.ru' + s2, True,
          'http://www.kinopoisk.ru/level/4/people/'+person_code+'/', 'OnMainImagePageLoaded');
			end;
		end;
  end;
end;

procedure OnMainImagePageLoaded(AContent: string);
var
	url, s, s2, s3, photo_url, img_code, latin_name, next_page: string;
	i, j, k, page, my_index, il: Integer;
	ShuffleAllPhotos: Boolean;
  NewPhotoURL: string;
  LatinName: string;
begin
	if RegReadInteger('KinopoiskShuffleAllPhotos', 0) = 1 then
		ShuffleAllPhotos := True
	else
		ShuffleAllPhotos := False;
	my_index := 0;
	page := 1;
	
	url := 'http://www.kinopoisk.ru/level/13/people/'+person_code+'/';

  NewPhotoURL := '';

  s := GetHTMLPageContentFromRequest(url);
	if (s <> '')and(s <> '-1') then
	begin
		photos_count := 0;

		//29.12.12
		//<td class="news">Liza Minnelli</td>
		LatinName := '';
		s2 := '<td class="news">';
		i := MyPos(s2, s, i+1);
		if i > 0 then begin
			j := MyPos('</td>', s, i+1);
			if j > 0 then
				LatinName := copy(s, i+length(s2), j-i-length(s2));
		end;
		if LatinName = '' then begin
			s2 := GetStr(s, '<meta name="keywords" content="', '"');
			LatinName := GetStr(s2, '(', ')');
		end;
		LatinName := ReplaceStr(LatinName, ' ', '-', -1);
		LatinName := EncodeURL(LatinName, 'WINDOWS-1251');
		LatinName := ReplaceStr(LatinName, '%', '_', -1);
		LatinName := ReplaceStr(LatinName, '''', '_27', -1);
		//ShowMessage(LatinName);

		s2 := s;
      // FAde: parse images from downloaded page
      Il := Pos('<table class="fotos">', s2);
      i := MyPos('<a href="/picture', s2, il);
      while (I > 0) do begin
        J := MyPos('</td>', s2, I + Length('<a href="/picture'));
        if (J > 0) then
        begin
          s3 := Copy(s2, I, J - I + 1);
          img_code := ParseString(s3, '\/picture\/(\d+)\/', 1);
        end;
				if img_code <> '' then
				begin
					//29.12.12
          //NewPhotoURL := 'http://st3.kinopoisk.ru/im/kadr/'+ copy(img_code, 1, 1) + '/' + copy(img_code, 2, 1) + '/' + copy(img_code, 3, 1) + '/kinopoisk.ru-' + latin_name + '-' + img_code + '.jpg';
          NewPhotoURL := 'http://st3.kinopoisk.ru/im/kadr/'+ copy(img_code, 1, 1) + '/' + copy(img_code, 2, 1) + '/' + copy(img_code, 3, 1) + '/kinopoisk.ru-' + LatinName + '-' + img_code + '.jpg';
          //ShowMessage(NewPhotoURL);
					
					my_index := my_index + 1;
					SetLength(photo_index, my_index);
					photo_index[my_index - 1] := NewPhotoURL;
					photos_count := photos_count + 1;
				end;
		delete(s2, 1, j);
        I := Pos('<a href="/picture', s2);
      end;
	end;
	if (RegReadInteger('KinopoiskShufflePhotos', 1) = 1) then
		Shuffle;
end;

procedure GetAwards(text, name, year: String; status: Integer);
var
	j: Integer;
	s, subject, movie_code, movie_title: String;
begin
	if (name <> '') and (Pos(name + ', ' + year, awards) = 0) then begin
		if awards <> '' then
			awards := awards + '<br>';
		awards := awards + name;
		if year <> '' then
			awards := awards + ', ' + year;
		awards := awards + '<br>';
	end;
	if text <> '' then begin
		if status = 1 then
			awards := awards + 'Победитель:<br>'
		else
			awards := awards + 'Номинации:<br>';
		j := Pos('<li', text);
		while j > 0 do begin
			subject := GetStr(text, '<li', '</li>');
			movie_code := GetStr(subject, ' href=''/film/', '/');
			movie_title := DecodeHTML(GetStr(subject, '&laquo;', '&raquo;'));
			s := GetStr(subject, '>', ' (');
			if s = '' then
				s := ParseString(subject, '>(.*?)$', 1);
			subject := ClearExtraBlankCharacters(RemoveSpacesInText(DecodeHTML(RemoveTags(s))));
			if movie_title <> '' then
				movie_title := ' ("' + movie_title + '")';
			awards := awards + subject + movie_title + '<br>';
			delete(text, 1, j);
			j := Pos('<li', text);
		end;
	end;
end;

function RemoveSpacesInText(text: String): String;
var
	i: Integer;
begin
	i := Pos('  ', text);
	while i>0 do begin
		delete(text, i, 1);
		i := Pos('  ', text);
	end;
	result := text;
end;

procedure OnAwardsPageLoaded(AContent: String);
//status 0 = nominated, 1 = won
var
	s, s2, nominated, winner, temp, name, year, subject, movie_title, movie_code: String;
	i, j, k, status : Integer;
begin
	temp := GetStr(AContent, 'Награды</a></h1>', '<br /><br /><br /><br /><br /><br />');
	i := Pos('<br /><br />', temp);
	while i>0 do begin
		delete(temp, 1, i);
		//extract year
		year := GetStr(temp, 'br /><br /><h1 ', '</h1>');
		year := ParseString(year, '>(\d+) ', 1);
		j := Pos('<br /><br />', temp);
		if j = 0 then
			j := length(temp);
		//copy all awards for this year
		s := copy(temp, 1, j);
		if year <> '' then begin
			//extract individual awards
			k := Pos('<table ', s);
			while k>0 do begin
				s2 := GetStr(s, '<table ', '</table>');
				name := GetStr(s2, '<b><a href="/awards/', '</a></b>');
				name := ClearExtraBlankCharacters(DecodeHTML(GetStr(name, '>', ',')));
				winner := GetStr(s2, '<b>Победитель', ' </td></tr>');
				GetAwards(winner, name, year, 1);
				nominated := GetStr(s2, '<b>Номинации', ' </td></tr>');
				GetAwards(nominated, name, year, 0);
				delete(s, 1, k);
				k := Pos('<table ', s);
			end;
		end;
		i := Pos('<br /><br />', temp);
	end;
end;

function GetInfo(url: string; images_only: boolean): string;
var
	day, month, year, original_title, s, s2, s3, PersonURL, RefURL: string;
	i, j, k, l: integer;
  ImageURL: string;
begin
	result:='';
	BasicURL:=url;
	awards := '';

	imdb_code:='';
	person_code:=ParseString(url, 'http://www.kinopoisk.ru/level/4/people/(\d+)/', 1);;
	person_site_url:=GetPersonSiteURL(person_code);

	ImageURL := 'http://www.kinopoisk.ru/level/13/people/'+person_code+'/';
	AddRequestForHTMLPageContent(ImageURL, True, RefURL, 'OnPhotosPageLoaded');
	// s := DownloadURLWithReferer(url, 'http://www.kinopoisk.ru/level/4/people/'+person_code+'/', false, RequestParameters);

	all:=DownloadURLWithReferer(url+'sr/1/', 'http://www.kinopoisk.ru/index.php', true, RequestParameters);
	//all:=DownloadURLWithReferer(url+'sr/1/', 'http://www.kinopoisk.ru/', true);
	//SaveLog(all);

	if pos('Если вы видите эту страницу', all)>0 then begin
		// SiteLogin;
		//all:=DownloadURL(url, true);
		all:=DownloadURLWithReferer(url+'sr/1/', 'http://www.kinopoisk.ru/index.php', true, RequestParameters);
		if pos('Если вы видите эту страницу', all)>0 then
			all:=DownloadURLWithReferer(url+'sr/1/', 'http://www.kinopoisk.ru/index.php', true, RequestParameters);
		//exit;
	end;


	//если требуется авторизация
	if GetResponseCode=403 then begin
		SiteLogin;
		all:=DownloadURL(url, true, RequestParameters);
	end;
	if all='-1' then
		result:='-1'
	else
		result:=all;

	is_photos_present := false;
	if (pos('level/13/people/' + person_code, all) > 0) or (Pos('name/' + person_code + '/photos/', all)>0) then
		is_photos_present := true;
		
	awards_url := '';
	if DownloadPersonAwards and (Pos('name/' + person_code + '/awards/', all) > 0) then begin
		awards_url := 'http://www.kinopoisk.ru/name/' + person_code + '/awards/';
		AddRequestForHTMLPageContent(awards_url, True, '', 'OnAwardsPageLoaded');		
	end;
		
	s2:=ParseString(all, '<title>(.*)</title>', 1);
	person:=s2;
	i:=pos(' (', person);
	if i>0 then
		person:=copy(person, 1, i-1);
	person:=DecodeHTML(person);
	person:=ClearExtraSpaces(person);

	if pos('КиноПоиск.ru', person)>0 then begin
		person:='';
		exit;
	end;

	//latin name
	i:=pos('>имя (лат.)</', all);
	if i>0 then begin
		i := i + 12;
		j := MyPos('</li>', all, i);
		if j>0 then begin
			s2 := copy(all, i, j-i);
			s2 := DecodeHTML(s2);
			s2 := RemoveTags(s2);
			original_name := s2;
		end;
	end;
	if original_name='' then begin
		original_name:=ParseString(all, '<span style="font-size:13px;color:#666">(.*?)</span>', 1);
		original_name:=DecodeHTML(original_name);
	end;
	if original_name = '' then begin
		original_name := GetStr(all, '<span itemprop="alternativeHeadline">', '</');
		original_name := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(original_name)));
	end;
	if (original_name='') or (original_name=' ') then 
		original_name := person;

	//person photo
	photo_url:=GetPersonImageURL(person_code);
	if pos(person_code+'.jpg', all)=0 then
		photo_url:='';

	//date of birth
  month := '';
  day := '';
  year := '';
	i:=pos('>дата рождения</', all);
	if i>0 then
  begin
		i:=i+14;
		j:=MyPos('<span', all, i+1);
		s2:=copy(all, i, j-i-1);
		s2:=Trim(RemoveTags(s2));
		i:=Pos(' ', s2);
    // Fade: Birthdate can consist only year - add check for that situation
    if (I > 0) then
    begin
      day:=Trim(copy(s2, 1, i-1));
      delete(s2, 1, i);
      if (Length(day) > 2) then
      begin
        month := day;
        day := '';
        i:=Pos(',', month);
        if (I > 0) then
          month:=copy(s2, 1, i-1);
      end
      else
      begin
        i:=Pos(',', s2);
        month:=copy(s2, 1, i-1);
        delete(s2, 1, i+1);
      end;
    end;
    year:=s2;
    // Fade - check year length
    if (length(year) > 4) then
		year := Copy(year, 1, 4);
		i:=1;
		while (i<=12) and (monthes[i]<>month) do begin
			i:=i+1;
		end;
		if (i<=12) and (month<>'') and (day <> '') then begin
			birth_date:=IntToStr(i)+format('/%s/%s', [day, year]);
		end
    else begin
		i := 0;
		try
			i := StrToInt(year);
		except
		end;
		if i = 0 then
			year := '';
		birth_date:= year;
	end;
	end;

	//date of death
	death_date:='';
  month := '';
  day := '';
  year := '';
	i:=pos('>дата смерти</', all);
	if i>0 then
  begin
		s := GetStr(all, '>дата смерти</', '</tr>');
		j:=Pos('|', s);
		if ((j=0) or (Pos('&bull;', s) < j)) then
			j := Pos('&bull;', s);
		if j > 0 then
			s2:= copy(s, 1, j-1)
		else
			s2 := s;
		s2 := '<' + s2;
		s2:=ClearExtraBlankCharacters(RemoveTags(s2));
		i:=pos(',', s2);
		if i>0 then
    begin
			s3:=copy(s2, 1, i-1);
			if s3<>'' then
      begin
				i:=pos(' ', s3);
				if i>0 then
        begin
					day:=copy(s3, 1, i-1);
					delete(s3, 1, i);
					month:=s3;

					i:=pos(',', s2);
					if i>0 then
          begin
						s3:=copy(s2, i+2, length(s2)-i-1);
						if s3<>'' then
            begin
							i:=pos('&', s3);
							if i>0 then
								s3:=copy(s3, 1, i-1);
							year:=s3;

							i:=1;
							while (i<=12) and (monthes[i]<>month) do begin
								i:=i+1;
							end;
							if (i<=12) and (month<>'') then begin
								death_date:=IntToStr(i)+format('/%s/%s', [day, year]);
							end;
						end;
					end;
				end;
			end;
		end
    else
      year := s2;
	end;
  // Fade: date can consist only year - add check for that situation
  if (death_date = '') then
    death_date := year;
	//birthplace
	i:=pos('>место рождения</', all);
	if i>0 then begin
		//i := MyPos('<td class="desc-data">', all, i+1);
		i := i + 15;
		k := MyPos('</td>', all, i+1);
		j := MyPos('</li>', all, i);
		if (k>0) and (k<j) then
			j:=k;
		if j>0 then begin
			s2 := copy(all, i, j-i);
			s2 := DecodeHTML(s2);
			s2 := RemoveTags(s2);
			if s2<>'-' then
				birthplace := s2
			else
				birthplace := '';
		end;
	end;

  // extract spouses
  ExtractSpouses();
	
	if RegReadInteger('KinopoiskDlFilmography', 1) = 1 then begin
		//Actor - filmography
		i:=pos('id="actor">Актер<', all);

		if i=0 then
			i:=pos('id="actor">Актриса<', all);
		if i>0 then begin
			ExtractMovies(i, 3);
		end;
		
		
		//Director - filmography 
		i:=pos('id="director">Режиcсер<', all);
		if i>0 then begin
			ExtractMovies(i, 1);
		end
		else begin
			i := Pos('id="director">Режиссер<', all);
			if i>0 then
				ExtractMovies(i,1);
		end;

		//Writer - filmography 
		i:=pos('id="writer">Сценарист<', all);
		
		if i>0 then begin
			ExtractMovies(i, 2);
		end;

		//Composer - filmography
		i:=pos('id="composer">Композитор<', all);
		
		if i>0 then begin
			ExtractMovies(i, 4);
		end;
	end;

	//person height
	i:=pos('>рост</b>', all);
	if i=0 then
		i:=pos('>рост</td>', all);
	if i>0 then begin
		i := i + 5;
		k := MyPos('</td>', all, i+1);
		j := MyPos('</li>', all, i);
		if (k>0) and (k<j) then
			j:=k;
		if j>0 then begin
			s2 := copy(all, i, j-i);
			s2 := DecodeHTML(s2);
			s2 := RemoveTags(s2);
			i := pos(' ', s2);
			s2 := copy(s2, 1, i-1);
			s2 := ClearExtraSpaces(s2);
			i := pos('.', s2);
			delete(s2, i, 1);
			try
				person_height := StrToInt(s2);
			except
			end;
		end;
	end;

	// biography
	//i := pos('<H2 class="chapter">Знаете ли вы, что...</H2>', all);
	i:=pos('Знаете ли вы, что...', all);
	if i>0 then 
	begin
		i := MyPos('<ul class="trivia">', all, i);
		j := MyPos('<div class="loader"></div>', all, i);
		s := copy(all, i, j-i);

		if pos('(...читать&nbsp;всё)', s) > 0 then
		begin
			if DownloadPersonAdditionalInfo then begin
				s := '';

				PersonURL := GetPersonURL(person_code, false) + 'view_info/ok/';

				all := DownloadURL(PersonURL, True, RequestParameters);

				if (Pos('<title>КиноПоиск.ru - Все фильмы планеты', all)>0) then
				begin
					//RefURL := 'http://www.kinopoisk.ru/level/4/people/'+person_code+'/';
					RefURL := 'http://s.kinopoisk.ru/index.php';
					all := DownloadURLWithReferer(PersonURL, RefURL, True, RequestParameters);
          // all := GetHTMLPageContentFromRequest(PersonURL);
				end;
				
				//SaveLog(all+#13#10+'http://www.kinopoisk.ru/level/4/people/'+person_code+'/');

				i:=pos('Знаете ли вы, что...', all);
				if i>0 then 
				begin
					i := MyPos('<ul class="trivia">', all, i);
					j := MyPos('</ul>', all, i);
					s := copy(all, i, j-i);
					
					//4.06.13
					i := pos('<li', s);
					if i > 0 then begin
						j := MyPos('<li', s, i+1);
						s2 := copy(s, i, j-i);
						i := pos('</li>', s2);
						if i > 0 then begin
							s2 := copy(s2, 1, i+4);

							if MyPos(s2, s, j) > 0 then
								delete(s, 1, j-1);
						end;
					end;
					//end 4.06.13
				end;
			end
			else begin
				i:=pos('(...читать&nbsp;всё)', s);
				s:=copy(s, 1, i-1);
			end;
		end;
		//s:=ReplaceStr(s, '<li class="trivia">', '', -1);
		s:=DecodeHTML(s);
		s:=ReplaceStr(s, '</p>', #10, -1);
		s:=ReplaceStr(s, '</P>', #10, -1);
		s:=ReplaceStr(s, '</div>', #10, -1);
		s:=ReplaceStr(s, '</DIV>', #10, -1);
		s:=ReplaceStr(s, '<BR>', #10, -1);
		s:=ReplaceStr(s, '<br>', #10, -1);
		s:=ReplaceStr(s, '<br/>', #10, -1);
		s:=ReplaceStr(s, '<br />', #10, -1);
		s:=ReplaceStr(s, '</li>', #10, -1);
		s:=RemoveTags(s);
		s:=ClearExtraBlankCharacters(s);
		s:=ReplaceStr(s, '  ', ' ', -2);
		s:=ReplaceStr(s, #10' ', #10, -1);
		s:=ReplaceStr(s, #10#10, #10, -2);
		s:=ReplaceStr(s, #10, '<br>', -1);
		biography := s;
	end;
	
	GetHTMLPageContentFromRequest(awards_url);
	
end;

	
//get movie site url
function GetMovieSiteURL(code: string): string;
begin
	if code='' then
		result:=''
	else
		result:=format('http://www.kinopoisk.ru/level/1/film/%s/', [code]);
end;

//get person site url
function GetPersonSiteURL(code: string): string;
begin
	if code='' then
		result:=''
	else
		result:=format('http://www.kinopoisk.ru/level/4/people/%s/', [code])
end;

//иногда требуется логин на сайт
procedure SiteLogin;
var
	url, all: string;
begin
	if UserName='' then begin
		ShowLoginForm;
	end;
	url:=format('http://www.kinopoisk.ru/level/30/?shop_user[login]=%s&shop_user[pass]=%s&shop_user[mem]=on', [UserName, UserPassword]);	
	url:=ReplaceStr(url, ' ', '+', -1);
	all:=DownloadURLWithReferer(url, 'post', true, RequestParameters);
	if (GetResponseCode=403) then begin
		ShowLoginForm;
	end;
end;


procedure ButtonClick(Sender: TButton);
begin
	UserName:=edUserName.Text;
	UserPassword:=edPassword.Text;
	SaveLoginInfo(UserName, UserPassword, script_name);

	f.ModalResult := mrOk;
end;

procedure ShowLoginForm;
begin
	f := TForm.Create(nil);
	f.Caption := 'Требуется авторизация';
	f.BorderStyle := bsDialog;
	f.Position := poScreenCenter;
	f.Width:=400;


	labCaption := TLabel.Create(f);
	labCaption.Name := 'labCaption';
	labCaption.Parent := f;
	labCaption.SetBounds(10, 10, 380, 25);
	labCaption.Caption := 'Для получении информации с этого сайта необходима авторизация.';

	labUserName := TLabel.Create(f);
	labUserName.Name := 'labUserName';
	labUserName.Parent := f;
	labUserName.SetBounds(10, 40, 100, 25);
	labUserName.Caption := 'Имя пользователя:';

	edUserName := TEdit.Create(f);
	edUserName.Name := 'Name';
	edUserName.Parent := f;
	edUserName.SetBounds(120, 40, 175, 25);
	edUserName.Text := UserName;

	labPassword := TLabel.Create(f);
	labPassword.Name := 'labPassword';
	labPassword.Parent := f;
	labPassword.SetBounds(10, 70, 380, 25);
	labPassword.Caption := 'Пароль:';

  edPassword := TEdit.Create(f);
	edPassword.Name := 'edPassword';
	edPassword.Parent := f;
	edPassword.SetBounds(120, 70, 175, 25);
	edPassword.Text := UserPassword;

	b := TButton.Create(f);
	b.Name := 'btnOK';
	b.Parent := f;
	b.SetBounds(300, 70, 75, 25);
	b.Caption := '&Вход';
	b.OnClick := @ButtonClick;


	labCaption2 := TLabel.Create(f);
	labCaption2.Name := 'labCaption2';
	labCaption2.Parent := f;
	labCaption2.SetBounds(10, 100, 275, 25);
	labCaption2.Caption := 'Если у вас нет имени и пароля, получите их по этому адресу:';

	edURL := TEdit.Create(f);
	edURL.Name := 'URL';
	edURL.Parent := f;
	edURL.SetBounds(10, 125, 370, 25);
	edURL.Text := 'http://www.kinopoisk.ru/level/30/#new';

	f.ShowModal;
	f.Free;
end;

//show available settings for the script
function ShowScriptOptions: integer;
var
	s: string;
	f: TForm;
	b: TButton;
	cbShuffleAllPhotos, cbShuffle, cbDlFilmography, cbDlBiggerPhoto: TCheckBox;
	my_value: integer;
	
procedure ShuffleClick(Sender: TCheckBox);
begin
	if TCheckBox(Sender).Checked then
		cbShuffleAllPhotos.Enabled := True
	else begin
		cbShuffleAllPhotos.Enabled := False;
		cbShuffleAllPhotos.Checked := False;
	end;
end;

procedure ButtonClick(Sender: TButton);
var
	zn: integer;
begin
	try
		if cbShuffleAllPhotos.Checked then
			zn := 1
		else
			zn := 0;
		RegWriteInteger('KinopoiskShuffleAllPhotos', zn);	
		if cbShuffle.Checked then
			zn := 1
		else
			zn := 0;
		RegWriteInteger('KinopoiskShufflePhotos', zn);
		if cbDlFilmography.Checked then
			zn := 1
		else
			zn := 0;
		RegWriteInteger('KinopoiskDlFilmography', zn);
		if cbDlBiggerPhoto.Checked then
			zn := 1
		else
			zn := 0;
		RegWriteInteger('KinopoiskDlBiggerPhoto', zn);
	except
	end;

	f.ModalResult := mrOk;
end;

begin
	result:=0;
	f := TForm.Create(nil);
	f.Caption := GetLangStr(1924);
	f.BorderStyle := bsDialog;
	f.Position := poScreenCenter;
	f.Width:=400;
	f.Height:=210;
	f.AutoSize:=false;

	
	cbShuffleAllPhotos := TCheckBox.Create(f);
	cbShuffleAllPhotos.Name := 'cbShuffleAllPhotos';
	cbShuffleAllPhotos.Parent := f;
	cbShuffleAllPhotos.SetBounds(10, 10, 350, 20);
	cbShuffleAllPhotos.Caption := 'Выбирать фотографии со всех страниц';
	my_value := RegReadInteger('KinopoiskShuffleAllPhotos', 0);
	if my_value=1 then
		cbShuffleAllPhotos.Checked := True;
		
	cbShuffle := TCheckBox.Create(f);
	cbShuffle.Name := 'cbShuffle';
	cbShuffle.Parent := f;
	cbShuffle.SetBounds(10, 30, 350, 20);
	cbShuffle.Caption := 'Смешивать фотографии';
	cbShuffle.Onclick := @ShuffleClick;
	my_value := RegReadInteger('KinopoiskShufflePhotos', 1);
	if my_value=1 then
		cbShuffle.Checked := True;
		
	cbDlFilmography := TCheckBox.Create(f);
	cbDlFilmography.Name := 'cbDlFilmography';
	cbDlFilmography.Parent := f;
	cbDlFilmography.SetBounds(10, 50, 350, 20);
	cbDlFilmography.Caption := 'Загружать фильмографию';
	my_value := RegReadInteger('KinopoiskDlFilmography', 1);
	if my_value=1 then
		cbDlFilmography.Checked := True;
		
	cbDlBiggerPhoto := TCheckBox.Create(f);
	cbDlBiggerPhoto.Name := 'cbDlBiggerPhoto';
	cbDlBiggerPhoto.Parent := f;
	cbDlBiggerPhoto.SetBounds(10, 70, 380, 20);
	cbDlBiggerPhoto.Caption := 'Загружать большие фотографии';
	my_value := RegReadInteger('KinopoiskDlBiggerPhoto', 1);
	if my_value = 1 then
		cbDlBiggerPhoto.Checked := True;
		

	b := TButton.Create(f);
	b.Name := 'btnOK';
	b.Parent := f;
	b.SetBounds(160, 150, 80, 25);
	b.Caption := '&OK';
	b.OnClick := @ButtonClick;

	f.ShowModal;
	f.Free;
end;

procedure SaveLog(s: string);
var
	fs: TFileStream;
begin
		try
			fs:=TFileStream.Create('c:\data.htm', fmCreate);
			fs.Write(s, Length(s));
			fs.Free;
		except
		end;
end;

begin
	DownloadPersonBiography:=true;
	DownloadPersonAdditionalInfo:=true;
	MaxPhotosCount:=4;

	photos_count:=0;

  monthes[1]:='января';
  monthes[2]:='февраля';
  monthes[3]:='марта';
  monthes[4]:='апреля';
  monthes[5]:='мая';
  monthes[6]:='июня';
  monthes[7]:='июля';
  monthes[8]:='августа';
  monthes[9]:='сентября';
  monthes[10]:='октября';
  monthes[11]:='ноября';
  monthes[12]:='декабря';

  prefixes[1]:='The';
  prefixes[2]:='A';
  prefixes[3]:='An';
  prefixes[4]:='La';
  prefixes[5]:='Les';
  prefixes[6]:='Des';
  prefixes[7]:='L''';
  prefixes[8]:='Un';
  prefixes[9]:='El';
  prefixes[10]:='Il';
  prefixes[11]:='Le';
  prefixes[12]:='Uno';

  RequestParameters := TStringList.Create();
  RequestParameters.Add('Host=www.kinopoisk.ru');
  RequestParameters.Add('AcceptLanguage=ru-RU');
  RequestParameters.Add('Connection=Keep-Alive');
end.