const
	script_name='allmovie';
	language='English';
	version=7;
	author='Vlad';
	MinProgramBuild=5500;
	PCount = 12;
	//MAX_PHOTOS_COUNT = 3;
var
	DownloadPersonBiography, DownloadPersonAdditionalInfo: boolean;
	MaxPhotosCount: integer;
	persons_count: integer;
	persons: array of string;
	imdb_codes: array of string;
	imdb_code, person_code: string;
	name, code, year, description: string;
	person, BasicURL, biography, trivia, character, birth_date, birthplace, birth_name, salary, height, original_name, death_date, person_site_url: string;
	photo_url: string;
	monthes: array [1..12] of string;
	prefixes: array [1..PCount] of string;
	movie_html: string;
	person_height: integer;

function DeleteBadChars(text: String): String;
var
	i: Integer;
	s : String;
begin
	s := '';
	for i := 1 to Length(text) do begin
		if not (ord(text[i]) in [1..20]) then
			s := s + text[i];
	end;
	Result := s;
end;

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 ClearExtraBlankCharacters(text: string): string;
begin
	// Clear all extra blank charackters
	while (length(text) > 0) and (ord(text[1]) in [1..32]) do
		delete(text, 1, 1);
	while (length(text) > 0) and (ord(text[length(text)]) in [1..32]) do
		delete(text, length(text), 1);
	Result := text;
end;
	

function GetSearchURLbyName(PersonName: string): string;
var
	url: string;
begin
	url:=format('http://www.allmovie.com/search/artists/%s', [PersonName]);
	url:=ReplaceStr(url, ' ', '+', -1);
	result:=url;
end;

//Download search results from URL
function DownloadSearchURL(url: string): integer;
begin
	all:=DownloadURL(url);
	if all='-1' then
		result:=-1
	else
		result:=PersonSearch;
end;

function PersonSearch: integer;
var
	url, s, s2, tempCode, small_photo, code, name, description: string;
	i, j, k: integer;
begin
	persons_count:=0;
	s:='';
	//redirect to the person's page
	s := ParseString(all, '<title>(.*?)</title>', 1);
	if (Pos('movies, photos,', s)>0) then begin
		i := Pos('<link rel="canonical" href="http://www.allmovie.com/artist/', all);
		if i>0 then begin
			j := MyPos('/', all, i+60);
			s := copy(all, i+60, j-i-60);
			s2 := ParseString(s, '-(\d+)$', 1);
			SetSearchResult('name', s2);
		end;
		persons_count := 1;	
	end
	//usual search result
	else begin
		i:=pos('<ul class="results">', all);
		if i>0 then begin
			j:=MyPos('</ul>', all, i+1);
			if j>0 then
				s:=copy(all, i, j-i);
		end;
		if (s='') or (pos('<h1>Oops! No results', all)>0) then
			//Person not found
		else begin
			i := pos('<li',s);
			while i>0 do begin
				tempCode := GetStr(s, '<li', '</li>');
				name := GetStr(s, '<a href="http://www.allmovie.com/artist/', '/a>');
				code := ParseString(name, '^.*?p(\d+)"', 1);
				name := GetStr(name, '>', '<');
				name := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(name)));
				small_photo := GetStr(tempCode, '<img src="', '?partner');
				description := GetStr(tempCode, '<dd class="years-active">', '</dd>');
				description := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(description)));
				if (name <> '') and (code <> '') then begin
					SetSearchResult2(name, code, '', '', description, small_photo);
					persons_count := persons_count + 1;
				end;
				delete(s, 1, i);
				i := pos('<li',s);
			end;
		end;
	end;
	result:=persons_count;
end;

function GetPersonURL(code: string; images_only: boolean): string;
begin
		result:=format('http://www.allmovie.com/artist/p%s', [code])
end;

procedure GetPhotos(img_cnt: Integer);
var
	s, temp, img_url: String;
	i, j: Integer;
begin
	s := GetStr(all, '<div class="media-gallery-content photos">', '<div class="media-gallery-controls">');
	//skip first photo - it's the main photo
	i := Pos('<div class="cropped-image"', s);
	delete(s, 1, i);
	while (img_cnt < MaxPhotosCount) and (Pos('<div class="cropped-image"', s)>0) do begin
		temp := GetStr(s, '<div class="cropped-image"', '</div>');
		img_url := GetStr(temp, ' src="', '?partner');
		if (RegReadInteger('AllMovieFullSizePhotos', 0) = 1) then begin
			i := Pos('/_derived', img_url);
			if i>0 then begin
				j := MyPos('/', img_url, i+1);
				delete(img_url, i, j-i);
			end;
		end
		else begin
			img_url := ReplaceStr(img_url, '250x250', '410x410', -1);
		end;
		if (img_url<>'') then begin
			img_cnt := img_cnt + 1;
			SetImageName('', img_url, '', 6);
		end;
		delete(s, 1, Pos('<div class="cropped-image"', s));
	end;
end;


//returnes images links
procedure GetImages;
var
	img_cnt: Integer;
begin
	img_cnt := 0;
	if photo_url<>'' then begin
		SetImageName('', photo_url, '', 6);
		img_cnt := 1;
	end;
	if (MaxPhotosCount > img_cnt) then
		GetPhotos(img_cnt);
	//GetGoogleImage;
end;

function GetGoogleImage: boolean;
var
	all, url: string;
	i, j: integer;
begin
	url:=format('http://images.google.com/images?svnum=20&hl=en&lr=&safe=on&c2coff=1&q=%%22%s%%22', [person]);
	url:=ReplaceStr(url, ' ', '+', -1);
	all:=DownloadURL(url);
	i:=pos('dyn.Img(', all);
	if i>0 then begin
		i:=MyPos('","', all, i+1);
		i:=MyPos('","', all, i+1);
		i:=MyPos('","', all, i+1) + 3;
		j:=MyPos('","', all, i+1);
		if j>0 then begin
			url:=copy(all, i, j-i);
			SetImageName('', url, '', 6);
		end;
	end;
end;

function SavePhoto(url, FileName: string): boolean;
var
	fs: TFileStream;
	s: string;
begin
	s:=DownloadURL(url);
	if (length(s)>0) 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);
	Result := name;
end;


function GetInfo(url: string; images_only: boolean): string;
var
	s, s2, s3, s4, day, month, year, side_details: string;
	i, j, k, l, mode: integer;
	to_actor: boolean;
begin
	result:='';
	BasicURL:=url;
	person_code:=ParseString(url, '(\d+)$', 1);
	person_site_url:=GetPersonSiteURL(person_code);
	all:=DownloadURL(url);
	if all='-1' then
		result:='-1'
	else
		result:=all;
	//name
	person := GetStr(all, '<h1', '</h1>');
	person := RemoveTags('<' + person);
	person := ParseString(person, '^(.*?) on ', 1);
	person := ClearExtraBlankCharacters(DecodeHTML(person));
	
	//get side details
	side_details := GetStr(all, '<div class="side-details">', '</div>');

	//original_name
	s := GetStr(side_details, '<dt>Aliases</dt>', '</dd>');
	original_name := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(GetStr(s, '<li>', '</li>'))));
	
	//birth details
	s := GetStr(side_details, 'Born', '</dd>');
	s := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(s)));
	//birth place
	birthplace := '';
	i := Pos('   in', s);
	if i>0 then begin
		birthplace := copy(s, i+6, length(s)-i-5);
		delete(s, i, length(s)-i+1);
		s := ClearExtraBlankCharacters(s);
	end;
	//birth date
	birth_date := '';
	month := ParseString(s, '^(.*?) \d+,', 1);
	day := ParseString(s, '.*? (\d+),', 1);
	year := ParseString(s, ', (\d+)$', 1);
	i := 12;
	while (i>0) and (month <> monthes[i]) do
		i := i - 1;
	if (i>0) and (day <> '') and (year <> '') then
		birth_date := IntToStr(i) + '/' + day + '/' + year;
		
	//death
	death_date := '';
	s := GetStr(side_details, 'Died', '</dd>');
	s := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(s)));
	month := ParseString(s, '^(.*?) \d+,', 1);
	day := ParseString(s, '.*? (\d+),', 1);
	year := ParseString(s, ', (\d+)$', 1);
	i := 12;
	while (i>0) and (month <> monthes[i]) do
		i := i - 1;
	if (i>0) and (day <> '') and (year <> '') then
		death_date := IntToStr(i) + '/' + day + '/' + year;
	
	//biography
	s := GetStr(all, '<strong>biography</strong>', '<div class="toggle fade"></div>');
	s := RemoveTags(s);
	s := ReplaceStr(s, #10, #13#10, -1);
	biography := ClearExtraBlankCharacters(DecodeHTML(s));
	
	//filmography
	s := GetStr(all, 'filmography</h2>', '</table>');
	while (Pos('<div class="info">', s)>0) do begin
		s2 := GetStr(s, '<div class="info">', '</tr>');
		name := GetStr(s2, '<a ', '/a>');
		code := ParseString(name, ' href="/movie/.*?v(\d+)"', 1);
		name := GetStr(name, '>', '<');
		name := ClearExtraBlankCharacters(DecodeHTML(name));
		year := GetStr(s2, '<td class="year"', '</td>');
		year := ParseString(RemoveTags('<' + year), '(\d+)', 1);
		s3 := LowerCase(GetStr(s2, '<p>', '</p>'));
		if (name <> '') and (code <> '') then begin
			if (Pos('actor', s3)>0) or (Pos('actress', s3)>0) or (Pos('voice', s3)>0) then
				SetMovieName(name, '', 3, code, year);
			if (Pos('director', s3)>0) then
				SetMovieName(name, '', 1, code, year);
			if (Pos('screenwriter', s3)>0) then
				SetMovieName(name, '', 2, code, year);
			if (Pos('composer', s3)>0) or (pos('Music', s3)>0) or (pos('Songwriter', s3)>0)  then
				SetMovieName(name, '', 4, code, year);
		end;
		delete(s, 1, Pos('<div class="info">', s));
	end;
	
	//photo
	s := GetStr(all, '<meta property="og:image" content="', '?partner');
	if RegReadInteger('AllMovieFullSizePhotos', 0) = 1 then begin
		i := Pos('/_derived', photo_url);
		if i>0 then begin
			j := MyPos('/', photo_url, i+1);
			delete(photo_url, i, j-i);
		end;
	end;
	if (s <> '') and (Pos('no_photo', s)=0) then
		photo_url := s;
	
end;

	
//get movie site url
function GetMovieSiteURL(code: string): string;
begin
	if code='' then
		result:=''
	else
		result:='http://www.allmovie.com/movie/v'+code;
end;

//get person site url
function GetPersonSiteURL(code: string): string;
begin
	if code='' then
		result:=''
	else	
		result:=format('http://www.allmovie.com/artist/p%s', [code]);
end;

//show available settings for the script
function ShowScriptOptions: integer;
var
	s: string;
	f: TForm;
	b: TButton;
	cbFullSizePhotos: TCheckBox;
	my_value: integer;

procedure ButtonClick(Sender: TButton);
var
	zn: integer;
begin
	try
		if cbFullSizePhotos.Checked then
			zn := 1
		else
			zn := 0;
		RegWriteInteger('AllMovieFullSizePhotos', 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:=190;
	f.AutoSize:=false;

	
	cbFullSizePhotos := TCheckBox.Create(f);
	cbFullSizePhotos.Name := 'cbFullSizePhotos';
	cbFullSizePhotos.Parent := f;
	cbFullSizePhotos.SetBounds(10, 10, 350, 20);
	cbFullSizePhotos.Caption := 'Download full-size (huge) photos';
	my_value := RegReadInteger('AllMovieFullSizePhotos', 0);
	if my_value=1 then
		cbFullSizePhotos.Checked := True;
		

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

	f.ShowModal;
	f.Free;
end;

begin

	monthes[1]:='January';
	monthes[2]:='February';
	monthes[3]:='March';
	monthes[4]:='April';
	monthes[5]:='May';
	monthes[6]:='June';
	monthes[7]:='July';
	monthes[8]:='August';
	monthes[9]:='September';
	monthes[10]:='October';
	monthes[11]:='November';
	monthes[12]:='December';

	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';

end.