const
	script_name='cinefacts';
	language='German';
	version=10;
	author='Vlad';
	MinProgramBuild=6000;
	PCount = 12;
	//MaxPicturesCount = 3;
var
	DownloadMovieBigCover, DownloadMovieShortCast, DownloadMovieFullCast, 
	DownloadMovieBigDescription, DownloadMovieComments, 
	DownloadMovieStudios,	DownloadMovieAwards, DownloadMovieEarnings, 
	DownloadMovieAdditionalInfo, DownloadMovieSeasonsList: boolean;
	MaxShotsCount, MaxPostersCount, MaxTrailersCount: integer;

	title, MovieName, s, s2, s3, s4, year, director, name, character, BasicURL, country, description, salary, awards: string;
	episodes, movie_code, movie_site_url, title_code, imdb_code: string;
	titles: array of string;
	titles_count: integer;
	i, j: integer;
	director_code, code: string;
	directors, writers, actors, characters, genres, imdb_codes: array of string;
	duration: integer;
	rating, imdb_rating: double;
	front_cover_url, pics_code: string;
	posters_exists, ask_amazon: boolean;
	original_title, mpaa, mpaa_rating: string;
	prefixes: array [1..PCount] of string;
	resolution, barcode, aspect_ratio, features, media_format, video_codec: string;
	PicsURL, TrailerURL : string;
	RequestParameters: TStringList;
	basic_movie_code: String;
	
function GetStr(str: String; s1: String; s2: String): String;
var
  I: Integer;
  J: Integer;
begin
  // Вырезает кусок строки между s1 и s2
	Result := '';
	I := Pos(LowerCase(s1), LowerCase(str));
	if I > 0 then
	begin
		J := MyPos(LowerCase(s2), LowerCase(str), I + Length(s1));
		if J > 0 then
  		Result := Copy(str, I + Length(s1), J - I - Length(s1));
	end;
end;

function MovieSearch: integer;
var
	i, j, k, l: integer;
	title, s, temp, one_item, small_cover, code, description, year: string;
	done_series: Boolean;
begin
	s:='';
	titles_count:=0;
	done_series := False;
	s := GetStr(all, '<h2>Suchergebnisse zu', '<h3>Stars');
	if s <> '' then begin
		temp := GetStr(s, '<h3>Filme', '</section>');
		i := Pos('<article>', temp);
		while i > 0 do begin
			one_item := GetStr(temp, '<article>', '</article>');
			small_cover := GetStr(one_item, ' src="', '"');
			if (Pos('generic_poster', small_cover) > 0) then
				small_cover := '';
			code := GetStr(one_item, ' href="/', '"');
			code := ParseString(code, ',(\d+)$', 1);				
			if (Pos('/Serien/', one_item) > 0) then
				code := 's,' + code
			else
				code := 'f,' + code;
			title := GetStr(one_item, '<h4>', '</h4>');
			title := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(title)));
			description := GetStr(one_item, '<p>', '</p>');
			year := ParseString(description, '(\d+)', 1);
			description := ParseString(description, year + ' - (.*?)$', 1);
			if (title <> '') and (code <> '') then begin
				titles_count := titles_count + 1;
				SetSearchResult2(title, code, year, '', description, small_cover);
			end;
			delete(temp, 1, i);
			i := Pos('<article>', temp);
			if (i = 0) and (not done_series) then begin
				temp := GetStr(s, '<h3>Serien', '</section>');
				i := Pos('<article>', temp);
				done_series := True;
			end;
		end;
	end;
	
	result:=titles_count;
end;

//get  movie name by barcode(UPC-12)
function GetMovieNameByUPC(barcode: string): string;
var
	url, all, s2, s3, res: string;
	i, j: integer;
begin
	res:='';
	url:=format('http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&SubscriptionId=0J0N83PT9M72BYH98YR2&Operation=ItemSearch&Keywords=%s&SearchIndex=Video&ResponseGroup=Request,Images,Tracks,ItemAttributes', [barcode]);	
	url:=ReplaceStr(url, ' ', '+', -1);
	all:=DownloadURL(url);
	//search image by title
	i:=pos('<Item>', all);
	while (i>0) and (res='') do begin
		j:=MyPos('</Item>', all, i+1);
		if j>0 then begin
			s2:=copy(all, i, j-i);
			s3:=ParseString(s2, '<Title>(.*?) \(.*\)</Title>', 1);
			if s3='' then
				s3:=ParseString(s2, '<Title>(.*?)</Title>', 1);
			if s3<>'' then
				res:=s3;
		end;
		i:=MyPos('<Item>', all, i+1);
	end;
	i:=pos('[', res);
	if i>0 then begin
		j:=MyPos(']', res, i+1);
		if j>0 then
			delete(res, i, j-i+1);
	end;
	result:=res;
end;

//Get search URL by movie name
function GetSearchURLbyName(MovieName, AYear, ABarcode: string): string;
var
	url: string;
begin
	MovieName := EncodeURL(MovieName, 'utf-8');
	url:=format('http://www.cinefacts.de/search/site/q/%s', [MovieName]);
	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:=MovieSearch;
end;

function GetMovieURL(code: string; images_only: boolean): string;
begin
	if (Pos('/', code) > 0) then begin
		code := ParseString(code, '^(\d+)', 1);
		result := 'http://www.cinefacts.de/Filme/f,' + code;
	end
	else if (Pos('s,', code) > 0) then
		result := 'http://www.cinefacts.de/Serien/' + code
	else
		result := 'http://www.cinefacts.de/Filme/' + code;
end;

//returned link to front cover
function GetAmazonImages: string;
var
	res, all, url, s, s2, s3, amazon_url: string;
	i, j: integer;
begin
	//discard info in brackets
	s:=title;
	url:=format('http://webservices.amazon.com/onca/xml?Service=AWSECommerceService&SubscriptionId=0J0N83PT9M72BYH98YR2&Operation=ItemSearch&Keywords=%s&SearchIndex=Video&ResponseGroup=Request,Images,Tracks,ItemAttributes', [original_title]);
	url:=ReplaceStr(url, ' ', '+', -1);
	all:=DownloadURL(url);
	//search image by title
	amazon_url:='';
	i:=pos('<Item>', all);
	while (i>0) and (amazon_url='') do begin
		j:=MyPos('</Item>', all, i+1);
		if j>0 then begin
			s2:=copy(all, i, j-i);
			s3:=ParseString(s2, '<Title>(.*?) \(.*\)</Title>', 1);
			if s3='' then
				s3:=ParseString(s2, '<Title>(.*?)</Title>', 1);
			s3:=DecodeHTML(s3);
			if s3<>'' then 
			begin
				//if title=s3 then begin //!!!
				if pos(UpperCase(title), UpperCase(s3))=1 then 
				begin
					amazon_url:=ParseString(s2, '<LargeImage><URL>(.*?)</URL>', 1);
				end;
			end;
		end;
		i:=MyPos('<Item>', all, i+1);
	end;
	if amazon_url<>'' then begin
		SetImageName('', amazon_url, '', 1);
		res:=amazon_url;
	end;
	result:=res;
end;

//save front cover to file
function SaveFrontCover(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 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 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, which delete all symbol key of ASCII < 32, and delete reiteration spaces
function CorrectStr(Str: String): String;
var
	i: Integer;
	IsDoubleSpace: Boolean;
begin
	Result := '';
	for i := 1 to Length(Str) do begin
		IsDoubleSpace := ((Copy(Str, i, 1) = ' ') and (Copy(Str, i-1, 1) = ' '));
		if (Ord(Copy(Str, i, 1)) > 31) and not IsDoubleSpace then Result := Result+Copy(Str, i, 1);
	end;
end;

procedure ExtractPeople(text: string; start, mode: integer);
var
	i, j: integer;
	s, s1, name, code, character, temp, small_photo: string;
begin
	i:=MyPos('</section>', text, start + 1);
	temp := copy(text, start, i - start);
	i := Pos('<article>', temp);
	while i>0 do begin
		s := GetStr(temp, '<article>', '</article>');
		delete(temp, 1, i);
		character:='';
		code := GetStr(s, ' href="/Stars/', '"');
		code := ParseString(code, ',(\d+)', 1);
		small_photo := GetStr(s, ' src="', '"');
		j := Pos('/thumbs/', small_photo);
		if j > 0 then
			delete(small_photo, j, length('/thumbs'));
		if (Pos('generic_person', small_photo) > 0) then
			small_photo := '';
		name := GetStr(s, '<h4>', '</h4>');
		name := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(name)));
		if mode=3 then begin
			character := GetStr(s, '<p>Rolle: ', '</p>');
			character := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(character)));
		end;
		if name<>'' then
			SetPersonName(name, character, mode, code, small_photo);
		i := Pos('<article>', temp);
	end;
end;

function GetInfo(url: string; images_only: boolean): string;
var 
	keyword, s, s2, s3, plot_outline, shot, shot_prefix, shot_ext, temp, desc_url, cast_url: string;
	i, j, k, frames_count: integer;
	actors: boolean;
	SeasonURLs: TStringList;
	EpisodeTitle, EpisodeDescription: String;
begin
	result:='';
	all:=DownloadURL(url);
	if all='-1' then
		result:='-1'
	else
		result:=all;
		
	movie_code := ParseString(url, '/kino/(\d+)', 1);
	basic_movie_code := movie_code;
	if movie_code = '' then begin
		basic_movie_code := ParseString(url, ',(\d+)', 1);
		if Pos('s,', url) > 0 then
			movie_code := 's,' + basic_movie_code
		else
			movie_code := 'f,' + basic_movie_code;
	end;
		
	movie_site_url:=GetMovieSiteURL(movie_code);
	
	//download seasons
	SeasonURLs := TStringList.Create;
	if DownloadMovieSeasonsList and (Pos('Staffeln &amp; Episoden</h3>', all) > 0) then begin
		temp := GetStr(all, 'Staffeln &amp; Episoden</h3>', '</section>');
		i := Pos('/Staffelguide/', temp);
		while i>0 do begin
			s := GetStr(temp, '/Staffelguide/', '</a>');
			s2 := ParseString(s, '^(\d+)', 1);
			if s2 <> '' then begin
				s3 := movie_site_url + '/Staffelguide/' + s2;
				SeasonURLs.Add(s3);
				AddRequestForHTMLPageContent(s3, False);
			end;
			delete(temp, 1, i);
			i := Pos('/Staffelguide/', temp);
		end;
	end;
	
	//download long description, if available
	desc_url := '';
	if DownloadMovieBigDescription and (Pos(basic_movie_code + '/Langinhalt', all) > 0) then begin
		desc_url := movie_site_url + '/Langinhalt';
		AddRequestForHTMLPageContent(desc_url, False);
	end;
	
	//download cast and crew, if available
	cast_url := '';
	if DownloadMovieFullCast and (Pos(basic_movie_code + '/Besetzung-Stab', all) > 0) then begin
		cast_url := movie_site_url + '/Besetzung-Stab';
		AddRequestForHTMLPageContent(cast_url, False);
	end;
	
	//download page with pictures
	PicsURL := '';
	if (Pos(basic_movie_code + '/Bildergalerie', all) > 0) and ((MaxShotsCount > 8) or (MaxPostersCount > 0)) then begin
		PicsURL := movie_site_url + '/Bildergalerie';
		AddRequestForHTMLPageContent(PicsURL, False);
	end;
	
	//download page with trailers
	TrailerURL := '';
	if (Pos(basic_movie_code + '/Videos', all) > 0) and (MaxTrailersCount > 3) then begin
		TrailerURL := movie_site_url + '/Videos';
		AddRequestForHTMLPageContent(TrailerURL, False);
	end;
	
	temp := GetStr(all, '<header>', '</header>');
	title := GetStr(temp, '<h2>', '</');
	title := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(title)));

	if title='' then
		exit;
		
	//original title
	original_title := GetStr(temp, '<p>Originaltitel:', '</p>');
	original_title := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(original_title)));
		
	//genres
	s := GetStr(temp, 'Genre: ', '|');
	while s <> '' do begin
		i := Pos(',', s);
		if i>0 then begin
			s2 := copy(s, 1, i-1);
			delete(s, 1, i);
		end
		else begin
			s2 := s;
			s := '';
		end;
		s2 := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(s2)));
		SetGenre(s2);
	end;
	
	//countries and year
	s := GetStr(temp, 'Genre: ', '<br>');
	if s = '' then
		s := GetStr(temp, 'Genre: ', '</p');
	i := Pos('|', s);
	delete(s, 1, i);
	//year
	year := ParseString(s, '\((\d+)\)', 1);
	if year = '' then
		year := ParseString(s, 'datetime="(\d+)', 1);
	//countries
	i := Pos('(', s);
	delete(s, i, length(s)-i+1);
	while s <> '' do begin
		i := Pos(',', s);
		if i>0 then begin
			s2 := copy(s, 1, i-1);
			delete(s, 1, i);
		end
		else begin
			s2 := s;
			s := '';
		end;
		s2 := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(s2)));
		SetCountry(s2);
	end;
	
	
	//studio
	s := GetStr(temp, 'Verleih: ', '</');
	while s <> '' do begin
		i := Pos(',', s);
		if i>0 then begin
			s2 := copy(s, 1, i-1);
			delete(s, 1, i);
		end
		else begin
			s2 := s;
			s := '';
		end;
		s2 := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(s2)));
		SetStudio(s2);
	end;
	
	//duration
	s2 := ParseString(temp, '\((\d+) Minuten', 1);
	if s2 = '' then
		s2 := ParseString(temp, '(\d+)</time> Minuten', 1);
	try
		duration:=StrToInt(s2)
	except
	end;
	
	//front cover
	temp := GetStr(all, '<figure>', '</figure>');
	front_cover_url := GetStr(temp, ' src="', '"');
	i := Pos('/thumbs/', front_cover_url);
	if i>0 then
		delete(front_cover_url, i, length('/thumbs'));
	if Pos('generic', front_cover_url) > 0 then
		front_cover_url := '';
		
	//long description
	description := '';
	if desc_url <> '' then begin
		temp := GetHTMLPageContentFromRequest(desc_url);
		description := GetStr(temp, '<h3>Langinhalt</h3>', '</div>');
	end
	//short description
	else begin
		description := GetStr(all, '<strong>Inhalt:', '</p>');
	end;
	description := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(description)));
	
	//cast and crew
	if cast_url <> '' then begin
		temp := GetHTMLPageContentFromRequest(cast_url);
		temp := GetStr(temp, ' Stab</h3>', ' id="sidebar">');
		i := Pos('Regie</h3>', temp);
		if i>0 then
			ExtractPeople(temp, i, 1);
		i := Pos('Drehbuch</h3>', temp);
		if i>0 then
			ExtractPeople(temp, i, 2);
		i := Pos('arsteller</h3>', temp);
		if i>0 then
			ExtractPeople(temp, i, 3);
		i := Pos('Nebendarsteller</h3>', temp);
		if i>0 then
			ExtractPeople(temp, i, 3);
	end
	//short cast
	else begin
		temp := GetStr(all, 'Besetzung &amp; Stab</h3>', '<section>');
		if temp = '' then
			temp := GetStr(all, 'Besetzung &amp; Stab</h3>', ' id="sidebar">');
		ExtractPeople(temp, 1, 3);
	end;
	
	//extract seasons
	for i := 0 to SeasonURLs.Count - 1 do begin
		temp := GetHTMLPageContentFromRequest(SeasonURLs[i]);
		temp := GetStr(temp, '<h3>Staffel ', 'id="sidebar">');
		k := Pos('<header>', temp);
		while k > 0 do begin
			s := GetStr(temp, '<header>', '<br><br></p>');
			j := 0;
			EpisodeTitle := GetStr(s, '<h3>', '</h3>');
			EpisodeTitle := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(EpisodeTitle)));
			EpisodeDescription := ParseString(s, '</header>(.*?)$', 1);
			EpisodeDescription := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(EpisodeDescription)));
			s2 := ParseString(s, 'Folge: (\d+)', 1);
			try
				j := StrToInt(s2);
			except
			end;
			if (EpisodeTitle <> '') then
				SetEpisode(i+1, j, EpisodeTitle, EpisodeDescription, '', '');
			delete(temp, 1, k);
			k := Pos('<header>', temp);
		end;
	end;
	SeasonURLs.Free;

end;

//returned images links
procedure GetImages;
var
	temp, s: String;
	i: Integer;
begin
	if front_cover_url<>'' then
		SetImageName('', front_cover_url, '', 1);
	If DownloadMovieBigCover then 
		GetAmazonImages;
	if PicsURL <> '' then begin
		temp := GetHTMLPageContentFromRequest(PicsURL);
		s := GetStr(temp, 'Bildergalerie zum Film</h3>', 'id="sidebar">');
		if s = '' then
			s := GetStr(temp, 'Bildergalerie</h3>', 'id="sidebar">');
		temp := s;
		i := Pos('Poster</h3>', temp);
		if i > 0 then
			ExtractPics(temp, i, 4, MaxPostersCount);
		i := Pos('Szenenbilder</h3>', temp);
		if i > 0 then
			ExtractPics(temp, i, 3, MaxShotsCount);
		i := Pos('Mediencover</h3>', temp);
		if i > 0 then
			ExtractPics(temp, i, 1, 5);
	end
	else begin
		temp := GetStr(all, 'Bilder zum Film</h3>', '</section>');
		if temp <> '' then
			ExtractPics(temp, 1, 3, MaxShotsCount);
	end;
	if TrailerURL <> '' then begin
		temp := GetHTMLPageContentFromRequest(TrailerURL);
		i := Pos('Videos zum Film</h3>', temp);
		if i = 0 then
			i := Pos('Videos</h3>', temp);
		i := MyPos('<section>', temp, i + 1);
		if i > 0 then
			GetTrailers(temp, i);
	end
	else begin
		i := Pos('Videos zum Film</h3>', all);
		if i > 0 then
			GetTrailers(all, i);
	end;
end;

procedure ExtractPics(text: String; start, mode, MaxPicsCount: Integer);
var
	s, img_code, num_code, pic_url, temp: string;
	img_count, i, j: integer;
begin
	img_count := 0;
	i := MyPos('</ul>', text, start + 1);
	temp := copy(text, start, i - start);
	i := Pos('<li>', temp);
	while (i > 0) and (img_count < MaxPicsCount) do begin
		s := GetStr(temp, '<li>', '</li>');
		pic_url := GetStr(s, ' src="', '"');
		j := Pos('/thumbs', pic_url);
		if j > 0 then
			delete(pic_url, j, length('/thumbs'));
		j := Pos('/square', pic_url);
		if j > 0 then
			delete(pic_url, j, length('/square'));
		if (pic_url <> '') then begin
			Inc(img_count);
			SetImageName('', pic_url, '', mode);
		end;
		delete(temp, 1, i);
		i := Pos('<li>', temp);
	end;
end;

procedure GetTrailers(text: string; start: integer);
var
	temp, s, trailer_pic, trailer_link, trailer_name: string;
	i, j, cnt: Integer;
begin
	cnt := 0;
	j := MyPos('</section>', text, start + 1);
	temp := copy(text, start, j - start);
	i := Pos('<article>', temp);
	while (i > 0) and (cnt < MaxTrailersCount) do begin
		s := GetStr(temp, '<article>', '</article>');
		trailer_link := GetStr(s, ' href="', '"');
		if trailer_link <> '' then
			trailer_link := 'http://www.cinefacts.de' + trailer_link;
		trailer_pic := GetStr(s, ' src="', '"');
		trailer_name := ClearExtraBlankCharacters(DecodeHTML(RemoveTags(GetStr(s, '<h4>', '</h4>'))));
		if trailer_link <> '' then begin
			Inc(cnt);
			SetTrailer(trailer_link, trailer_name, trailer_pic);
		end;
		delete(temp, 1, i);
		i := Pos('<article>', temp);
	end;
end;

//get movie site url
function GetMovieSiteURL(code: string): string;
begin
	if code='' then
		result:=''
	else begin
		if (Pos('/', code) > 0) then begin
			code := ParseString(code, '^(\d+)', 1);
			result := 'http://www.cinefacts.de/Filme/f,' + code;
		end
		else if (Pos('s,', code) > 0) then
			result := 'http://www.cinefacts.de/Serien/' + code
		else
			result := 'http://www.cinefacts.de/Filme/' + code;
	end;
end;

//get person site url
function GetPersonSiteURL(code: string): string;
begin
	if code='' then
		result:=''
	else begin
		if (Pos('/', code) > 0) then
			code := ParseString(code, '^(\d+)', 1);
		result := 'http://www.cinefacts.de/Stars/s,' + code;
	end;
end;


begin

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('AcceptLanguage=de');
	RequestParameters.Add('Host=www.cinefacts.de');
	RequestParameters.Add('Connection=Close'); 
	RequestParameters.Add('useragent=Mozilla/5.0');

end.