(***************************************************

Ant Movie Catalog importation script
www.antp.be/software/moviecatalog/

[Infos]
Authors=raulsara
Title=TMDB (ES)
Description=Importa datos de The Movie Database (TMDB) en castellano
Site=
Language=ES
Version=1.0
Requires=4.2.0
Comments=
License=
GetInfo=1
RequiresMovies=1

[Options]
ImportarCaratula=1|1|0=No importar caratula|1=Importar caratula
LimiteActores=15|15|0=Numero maximo de actores
MaxResultados=500|500|Maximo de pelis a cargar en la busqueda (20 por pagina)
RomanizarNombres=1|1|0=Dejar nombres como esten|1=Romanizar nombres no latinos (japones, etc.)

[Parameters]
API_KEY=PON_AQUI_TU_APIKEY|PON_AQUI_TU_APIKEY|API Key (v3) de themoviedb.org > Ajustes de la cuenta > API
Idioma=|es-ES|Idioma de los datos (es-ES, es-MX, en-US...)

***************************************************)



program TMDB_ES;
uses ExternalCurlHandler;

const
  API = 'https://api.themoviedb.org/3';
  IMG = 'https://image.tmdb.org/t/p/w500';

function FixU(s: string): string;
var t: string;
begin
  Result := s;
  t := UTF8Decode(s);
  if t <> '' then Result := t;
end;

function Limpia(s: string): string;
begin
  s := StringReplace(s, '\"', '"');
  s := StringReplace(s, '\/', '/');
  s := StringReplace(s, '\n', ' ');
  s := StringReplace(s, '\r', ' ');
  s := StringReplace(s, '\t', ' ');
  s := StringReplace(s, '\\', '\');
  Result := s;
end;

// valor string SIN decodificar (bytes crudos, para analizar el alfabeto)
function JRaw(bloque, clave: string): string;
var p, i: Integer; sub, ch, prev: string;
begin
  Result := '';
  p := Pos('"' + clave + '":"', bloque);
  if p = 0 then Exit;
  sub := Copy(bloque, p + Length(clave) + 4, Length(bloque));
  i := 1;
  while i <= Length(sub) do
  begin
    ch := Copy(sub, i, 1);
    if i > 1 then prev := Copy(sub, i - 1, 1) else prev := '';
    if (ch = '"') and (prev <> '\') then Break;
    i := i + 1;
  end;
  Result := Limpia(Copy(sub, 1, i - 1));
end;

// valor string de "clave":"valor" (decodificado UTF-8)
function JStr(bloque, clave: string): string;
begin
  Result := FixU(JRaw(bloque, clave));
end;

// True si el texto tiene suficientes letras/digitos latinos para ser legible
function EsLatino(s: string): Boolean;
var i, letras, total: Integer; ch: string;
begin
  letras := 0; total := 0;
  for i := 1 to Length(s) do
  begin
    ch := Copy(s, i, 1);
    if ch <> ' ' then
    begin
      total := total + 1;
      if Pos(ch, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') > 0 then letras := letras + 1;
    end;
  end;
  Result := (total = 0) or (letras >= 3) or (letras * 2 >= total);
end;

// Pone en mayuscula la primera letra
function CapFirst(s: string): string;
var p: Integer;
begin
  Result := s;
  if s = '' then Exit;
  p := Pos(Copy(s, 1, 1), 'abcdefghijklmnopqrstuvwxyz');
  if p > 0 then Result := Copy('ABCDEFGHIJKLMNOPQRSTUVWXYZ', p, 1) + Copy(s, 2, Length(s));
end;

// True si el texto es 100% ASCII imprimible (sin acentos ni caracteres raros)
function EsASCII(s: string): Boolean;
var i: Integer; ch: string;
begin
  Result := True;
  for i := 1 to Length(s) do
  begin
    ch := Copy(s, i, 1);
    if Pos(ch, ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~') = 0 then
    begin Result := False; Exit; end;
  end;
end;

// valor numerico de "clave":NUM
function JNum(bloque, clave: string): string;
var p, i: Integer; sub, ch: string;
begin
  Result := '';
  p := Pos('"' + clave + '":', bloque);
  if p = 0 then Exit;
  sub := Copy(bloque, p + Length(clave) + 3, Length(bloque));
  i := 1;
  while i <= Length(sub) do
  begin
    ch := Copy(sub, i, 1);
    if ((ch < '0') or (ch > '9')) and (ch <> '.') then Break;
    i := i + 1;
  end;
  Result := Copy(sub, 1, i - 1);
end;

function UrlEnc(s: string): string;
begin
  s := StringReplace(s, '%', '%25');
  s := StringReplace(s, ' ', '%20');
  s := StringReplace(s, '&', '%26');
  s := StringReplace(s, '?', '%3F');
  s := StringReplace(s, '#', '%23');
  s := StringReplace(s, '+', '%2B');
  Result := s;
end;

function Fetch(url: string): string;
begin
  Result := GetPage5Advanced(url, '', '', '', '');
end;

function Pais(en: string): string;
var r: string;
begin
  r := '';
  if en = 'United States of America' then r := 'Estados Unidos'
  else if en = 'United Kingdom' then r := 'Reino Unido'
  else if en = 'Spain' then r := 'España'
  else if en = 'France' then r := 'Francia'
  else if en = 'Germany' then r := 'Alemania'
  else if en = 'Italy' then r := 'Italia'
  else if en = 'Canada' then r := 'Canadá'
  else if en = 'Mexico' then r := 'México'
  else if en = 'Argentina' then r := 'Argentina'
  else if en = 'Japan' then r := 'Japón'
  else if en = 'China' then r := 'China'
  else if en = 'South Korea' then r := 'Corea del Sur'
  else if en = 'India' then r := 'India'
  else if en = 'Australia' then r := 'Australia'
  else if en = 'Brazil' then r := 'Brasil'
  else if en = 'Russia' then r := 'Rusia'
  else if en = 'Sweden' then r := 'Suecia'
  else if en = 'Denmark' then r := 'Dinamarca'
  else if en = 'Norway' then r := 'Noruega'
  else if en = 'Netherlands' then r := 'Países Bajos'
  else if en = 'Belgium' then r := 'Bélgica'
  else if en = 'Switzerland' then r := 'Suiza'
  else if en = 'Austria' then r := 'Austria'
  else if en = 'Portugal' then r := 'Portugal'
  else if en = 'Ireland' then r := 'Irlanda'
  else if en = 'Poland' then r := 'Polonia'
  else if en = 'Greece' then r := 'Grecia'
  else if en = 'Turkey' then r := 'Turquía'
  else if en = 'Hong Kong' then r := 'Hong Kong'
  else if en = 'New Zealand' then r := 'Nueva Zelanda'
  else if en = 'Finland' then r := 'Finlandia'
  else if en = 'Soviet Union' then r := 'Unión Soviética';
  // devolvemos el literal SIN decodificar; el FixU se aplica fuera al concatenar
  // (igual que en el genero, que asi funciona). Si no hay traduccion, el original.
  if r <> '' then Result := r else Result := en;
end;

// Busca un nombre romanizado (latino) en la ficha de la persona
function RomajiDePersona(id: string): string;
var json, resto, aka, pname: string; p, q, n: Integer;
begin
  Result := '';
  if id = '' then Exit;
  json := Fetch(API + '/person/' + id + '?api_key=' + GetParam('API_KEY'));
  // 1) el "name" de la persona suele ser el nombre romanizado (lo que usa la web)
  pname := JRaw(json, 'name');
  if EsLatino(pname) then begin Result := FixU(pname); Exit; end;
  // 2) si no, buscar en also_known_as
  p := Pos('"also_known_as":[', json);
  if p = 0 then Exit;
  resto := Copy(json, p + 17, Length(json));
  q := Pos(']', resto);
  if q > 0 then resto := Copy(resto, 1, q - 1);
  n := 0;
  while (Pos('"', resto) > 0) and (n < 40) do
  begin
    aka := TextBetween(resto, '"', '"');
    if aka = '' then Break;
    if EsLatino(aka) then begin Result := FixU(aka); Exit; end;
    resto := TextAfter(resto, '"' + aka + '"');
    n := n + 1;
  end;
end;

// Sinopsis en ingles (fallback cuando no hay en el idioma pedido)
function OverviewEN(id: string): string;
var json: string;
begin
  json := Fetch(API + '/movie/' + id + '?api_key=' + GetParam('API_KEY') + '&language=en-US');
  Result := JStr(json, 'overview');
end;

// Idioma original -> pais con ese alfabeto (donde suele estar la romanizacion)
function LangToCountry(lang: string): string;
begin
  if lang = 'ja' then Result := 'JP'
  else if lang = 'ko' then Result := 'KR'
  else if lang = 'zh' then Result := 'CN'
  else if lang = 'cn' then Result := 'CN'
  else if lang = 'th' then Result := 'TH'
  else if lang = 'vi' then Result := 'VN'
  else if lang = 'hi' then Result := 'IN'
  else if lang = 'ta' then Result := 'IN'
  else if lang = 'te' then Result := 'IN'
  else if lang = 'ru' then Result := 'RU'
  else if lang = 'uk' then Result := 'UA'
  else if lang = 'el' then Result := 'GR'
  else if lang = 'he' then Result := 'IL'
  else if lang = 'fa' then Result := 'IR'
  else if lang = 'bn' then Result := 'BD'
  else Result := '';
end;

// Devuelve  romanizacion + TAB + titulo internacional (US/GB)  desde alternative_titles
function TitulosAlt(id, paisIso: string): string;
var json, resto, obj, tipo, titulo, iso, v1, v2, v3, us, gb, romaji, intl: string; p, n: Integer;
    esRoman, esTranslit, esOrigen, ascii, vacio: Boolean;
begin
  json := Fetch(API + '/movie/' + id + '/alternative_titles?api_key=' + GetParam('API_KEY'));
  v1 := ''; v2 := ''; v3 := ''; us := ''; gb := '';
  p := Pos('"titles":[', json);
  if p > 0 then
  begin
    resto := Copy(json, p + 10, Length(json));
    n := 0;
    while (Length(resto) > 5) and (n < 150) do
    begin
      p := Pos('},{', resto);
      if p > 0 then begin obj := Copy(resto, 1, p - 1); resto := Copy(resto, p + 2, Length(resto)); end
      else begin obj := resto; resto := ''; end;
      tipo := JRaw(obj, 'type');
      titulo := JRaw(obj, 'title');
      iso := JRaw(obj, 'iso_3166_1');
      if EsLatino(titulo) then
      begin
        esRoman := (Pos('oman', tipo) > 0) or (Pos('omaji', tipo) > 0);   // romaji/romanized/romanization
        esTranslit := esRoman or (Pos('ranslit', tipo) > 0);             // + transliterated/transliteration
        esOrigen := (paisIso <> '') and (iso = paisIso);
        ascii := EsASCII(titulo);
        vacio := Trim(tipo) = '';
        // ROMANIZACION
        if esOrigen and esTranslit then if (v1 = '') or ascii then v1 := titulo;  // via1
        if esRoman then if (v2 = '') or ascii then v2 := titulo;                  // via2
        if esOrigen and vacio then if (v3 = '') or ascii then v3 := titulo;       // via3
        // TITULO INTERNACIONAL: US o GB con tipo vacio (el principal)
        if (iso = 'US') and vacio and (us = '') then us := titulo;
        if (iso = 'GB') and vacio and (gb = '') then gb := titulo;
      end;
      n := n + 1;
    end;
  end;
  if v1 <> '' then romaji := FixU(CapFirst(v1))
  else if v2 <> '' then romaji := FixU(CapFirst(v2))
  else if v3 <> '' then romaji := FixU(CapFirst(v3))
  else romaji := '';
  if us <> '' then intl := FixU(us)
  else if gb <> '' then intl := FixU(gb)
  else intl := '';
  Result := romaji + #9 + intl;
end;

// Nombre "legible" de un objeto persona (crew o cast): prefiere latino
function NombreObj(obj: string): string;
var nm, orig, romaji: string;
begin
  nm := JRaw(obj, 'name');
  orig := JRaw(obj, 'original_name');
  if EsLatino(nm) then begin Result := FixU(nm); Exit; end;
  if EsLatino(orig) then begin Result := FixU(orig); Exit; end;
  // ninguno es latino: intentar romanizar (llamada extra a la API)
  if GetOption('RomanizarNombres') = 1 then
  begin
    romaji := RomajiDePersona(JNum(obj, 'id'));
    if romaji <> '' then begin Result := romaji; Exit; end;
  end;
  Result := '';  // sin version latina: dejar en blanco (mejor que ?????)
end;

// Nombres del crew cuyo "job" coincide exactamente (asociado a SU propio objeto)
function CrewByJob(crew, job: string): string;
var resto, obj, nombre, res: string; p, n: Integer;
begin
  res := ''; resto := crew; n := 0;
  while (Length(resto) > 2) and (n < 100) do
  begin
    p := Pos('},{', resto);
    if p > 0 then begin obj := Copy(resto, 1, p - 1); resto := Copy(resto, p + 2, Length(resto)); end
    else begin obj := resto; resto := ''; end;
    if Pos('"job":"' + job + '"', obj) > 0 then
    begin
      nombre := NombreObj(obj);
      if nombre <> '' then
        if Pos(nombre, res) = 0 then
        begin
          if res <> '' then res := res + ', ';
          res := res + nombre;
        end;
    end;
    n := n + 1;
  end;
  Result := res;
end;

procedure Detalles(id: string);
var json, apik, idi, anio, generos, paises, dir, prod, guion, musica, act, crew, resto, raw, obj, nombre, sinopsis, otro, paisIso, dos, romaji, intl, poster: string;
    p, q, n, lim: Integer;
begin
  apik := GetParam('API_KEY'); idi := GetParam('Idioma');
  json := Fetch(API + '/movie/' + id + '?api_key=' + apik + '&language=' + idi + '&append_to_response=credits');
  if Pos('"original_title":', json) = 0 then
  begin
    ShowMessage('No se pudo obtener la ficha de TMDB (id ' + id + ').');
    Exit;
  end;

  raw := JRaw(json, 'original_title');   // titulo original crudo
  nombre := JStr(json, 'title');         // titulo traducido (decodificado)
  if CanSetField(fieldTranslatedTitle) then SetField(fieldTranslatedTitle, nombre);
  if CanSetField(fieldOriginalTitle) then
  begin
    paisIso := LangToCountry(JRaw(json, 'original_language'));
    otro := '';
    // idioma de alfabeto no latino (chino, japones...): romanizacion + titulo internacional
    if paisIso <> '' then
    begin
      dos := TitulosAlt(id, paisIso);
      romaji := Copy(dos, 1, Pos(#9, dos) - 1);
      intl := Copy(dos, Pos(#9, dos) + 1, Length(dos));
      if EsLatino(raw) then intl := FixU(raw);  // el original_title ya es el internacional
      if (romaji <> '') and (intl <> '') and (romaji <> intl) then otro := romaji + ' (' + intl + ')'
      else if romaji <> '' then otro := romaji
      else otro := intl;
    end;
    if otro <> '' then SetField(fieldOriginalTitle, otro)
    else if EsLatino(raw) then SetField(fieldOriginalTitle, FixU(raw))
    else SetField(fieldOriginalTitle, nombre);
  end;
  if CanSetField(fieldYear) then begin anio := JStr(json, 'release_date'); SetField(fieldYear, Copy(anio, 1, 4)); end;
  if CanSetField(fieldDescription) then
  begin
    sinopsis := JStr(json, 'overview');
    if Trim(sinopsis) = '' then sinopsis := OverviewEN(id);  // fallback a ingles
    SetField(fieldDescription, sinopsis);
  end;
  if CanSetField(fieldLength) then SetField(fieldLength, JNum(json, 'runtime'));
  if CanSetField(fieldRating) then SetField(fieldRating, Copy(JNum(json, 'vote_average'), 1, 3));
  if CanSetField(fieldURL) then SetField(fieldURL, 'https://www.themoviedb.org/movie/' + id);

  // Generos (Categoria)
  if CanSetField(fieldCategory) then
  begin
    generos := '';
    resto := TextBetween(json, '"genres":[', ']');
    while Pos('"name":"', resto) > 0 do
    begin
      raw := TextBetween(resto, '"name":"', '"');
      if generos <> '' then generos := generos + ', ';
      generos := generos + FixU(raw);
      resto := TextAfter(resto, '"name":"' + raw + '"');
    end;
    SetField(fieldCategory, generos);
  end;

  // Paises
  if CanSetField(fieldCountry) then
  begin
    paises := '';
    resto := TextBetween(json, '"production_countries":[', ']');
    while Pos('"name":"', resto) > 0 do
    begin
      raw := TextBetween(resto, '"name":"', '"');
      if paises <> '' then paises := paises + ', ';
      paises := paises + FixU(Pais(raw));
      resto := TextAfter(resto, '"name":"' + raw + '"');
    end;
    SetField(fieldCountry, paises);
  end;

  // Equipo (crew): director, productor, guion, compositor
  crew := TextAfter(json, '"crew":[');

  if CanSetField(fieldDirector) then
    SetField(fieldDirector, CrewByJob(crew, 'Director'));

  if CanSetField(fieldProducer) then
  begin
    prod := CrewByJob(crew, 'Producer');
    if prod = '' then prod := CrewByJob(crew, 'Executive Producer');
    SetField(fieldProducer, prod);
  end;

  if CanSetField(fieldWriter) then
  begin
    guion := CrewByJob(crew, 'Screenplay');
    if guion = '' then guion := CrewByJob(crew, 'Writer');
    if guion = '' then guion := CrewByJob(crew, 'Story');
    SetField(fieldWriter, guion);
  end;

  if CanSetField(fieldComposer) then
  begin
    musica := CrewByJob(crew, 'Original Music Composer');
    if musica = '' then musica := CrewByJob(crew, 'Music');
    if musica = '' then musica := CrewByJob(crew, 'Composer');
    SetField(fieldComposer, musica);
  end;

  // Actores (cast)
  if CanSetField(fieldActors) then
  begin
    act := '';
    p := Pos('"cast":[', json);
    if p > 0 then
    begin
      resto := Copy(json, p + 8, Length(json));
      q := Pos('],"crew"', resto);
      if q > 0 then resto := Copy(resto, 1, q - 1);
      lim := GetOption('LimiteActores'); n := 0;
      while (Length(resto) > 2) and (n < lim) do
      begin
        p := Pos('},{', resto);
        if p > 0 then begin obj := Copy(resto, 1, p - 1); resto := Copy(resto, p + 2, Length(resto)); end
        else begin obj := resto; resto := ''; end;
        nombre := NombreObj(obj);
        if nombre <> '' then
        begin
          if act <> '' then act := act + #13#10;
          act := act + nombre;
          n := n + 1;
        end;
      end;
    end;
    SetField(fieldActors, act);
  end;

  // Caratula
  if GetOption('ImportarCaratula') = 1 then
  begin
    poster := JStr(json, 'poster_path');
    if poster <> '' then GetPictureAdvanced(IMG + poster);
  end;
end;

// Clave para ordenar por año descendente (complemento a 9 de cada digito)
function ClaveDesc(anio: string): string;
var i: Integer; ch, res: string;
begin
  res := '';
  for i := 1 to Length(anio) do
  begin
    ch := Copy(anio, i, 1);
    case ch of
      '0': res := res + '9';
      '1': res := res + '8';
      '2': res := res + '7';
      '3': res := res + '6';
      '4': res := res + '5';
      '5': res := res + '4';
      '6': res := res + '3';
      '7': res := res + '2';
      '8': res := res + '1';
      '9': res := res + '0';
    else res := res + ch;
    end;
  end;
  Result := res;
end;

// Entero -> texto (sin StrToInt/IntToStr, que dan problemas en este AMC)
function NumStr(num: Integer): string;
var res: string; d, k: Integer;
begin
  k := num;
  if k <= 0 then begin Result := '0'; Exit; end;
  res := '';
  while k > 0 do
  begin
    d := k mod 10;
    res := Copy('0123456789', d + 1, 1) + res;
    k := k div 10;
  end;
  Result := res;
end;

// Texto -> entero
function StrNum(s: string): Integer;
var i, r: Integer; ch: string;
begin
  r := 0;
  for i := 1 to Length(s) do
  begin
    ch := Copy(s, i, 1);
    if (ch >= '0') and (ch <= '9') then r := r * 10 + (Pos(ch, '0123456789') - 1)
    else Break;
  end;
  Result := r;
end;

procedure Buscar(nombre: string);
var apik, idi, base, url, json, resto, obj, id, ot, tt, rd, anio, clave, etiq, linea, todo, elegido: string;
    p, q, n, pagina, totalPag, maxPag, maxRes: Integer;
    lista: TStringList;
begin
  apik := GetParam('API_KEY'); idi := GetParam('Idioma');
  base := API + '/search/movie?api_key=' + apik + '&language=' + idi + '&include_adult=true&query=' + UrlEnc(nombre);

  maxRes := GetOption('MaxResultados');
  if maxRes < 20 then maxRes := 20;
  maxPag := maxRes div 20;
  if maxPag < 1 then maxPag := 1;
  if maxPag > 500 then maxPag := 500;  // limite duro de la API de TMDB

  lista := TStringList.Create;
  n := 0; pagina := 1; totalPag := 1;
  repeat
    url := base + '&page=' + NumStr(pagina);
    json := Fetch(url);
    if Pos('"results":', json) = 0 then
    begin
      if pagina = 1 then
      begin
        lista.Free;
        ShowMessage('Sin respuesta de TMDB. Revisa la API Key y la conexion.');
        Exit;
      end;
      Break;  // fallo en una pagina posterior: nos quedamos con lo que haya
    end;
    if pagina = 1 then
    begin
      totalPag := StrNum(JNum(json, 'total_pages'));
      if totalPag < 1 then totalPag := 1;
    end;
    p := Pos('"results":[', json);
    resto := Copy(json, p + 11, Length(json));
    q := Pos('],"total', resto);
    if q > 0 then resto := Copy(resto, 1, q - 1);
    while Length(resto) > 5 do
    begin
      p := Pos('},{', resto);
      if p > 0 then begin obj := Copy(resto, 1, p - 1); resto := Copy(resto, p + 2, Length(resto)); end
      else begin obj := resto; resto := ''; end;
      id := JNum(obj, 'id');
      if id <> '' then
      begin
        ot := JRaw(obj, 'original_title');
        tt := JRaw(obj, 'title');
        // descartar pelis cuyo titulo esta en alfabeto no latino (se ven como ?????)
        if EsLatino(tt) or EsLatino(ot) then
        begin
          rd := JStr(obj, 'release_date');
          anio := Copy(rd, 1, 4);
          if Length(anio) < 4 then anio := '0000';
          // titulo principal = el que sea legible (el filtro garantiza al menos uno)
          if EsLatino(tt) then etiq := FixU(tt) else etiq := FixU(ot);
          etiq := etiq + ' (' + anio + ')';
          // corchete con el otro titulo solo si tambien es latino y distinto
          if EsLatino(tt) and EsLatino(ot) and (ot <> tt) then etiq := etiq + '   [' + FixU(ot) + ']';
          clave := ClaveDesc(anio);  // orden ascendente = mas nuevo primero
          lista.Add(clave + #9 + etiq + #9 + id);
          n := n + 1;
        end;
      end;
    end;
    pagina := pagina + 1;
  until (pagina > totalPag) or (pagina > maxPag);

  if n = 0 then begin lista.Free; ShowMessage('No hay resultados en TMDB para: ' + nombre); Exit; end;

  lista.Sort;
  PickTreeClear;
  todo := lista.Text;
  lista.Free;
  while Trim(todo) <> '' do
  begin
    p := Pos(#10, todo);
    if p > 0 then begin linea := Copy(todo, 1, p - 1); todo := Copy(todo, p + 1, Length(todo)); end
    else begin linea := todo; todo := ''; end;
    linea := StringReplace(linea, #13, '');
    if Trim(linea) <> '' then
    begin
      p := Pos(#9, linea);
      resto := Copy(linea, p + 1, Length(linea));
      q := Pos(#9, resto);
      etiq := Copy(resto, 1, q - 1);
      id := Copy(resto, q + 1, Length(resto));
      PickTreeAdd(etiq, id);
    end;
  end;

  if PickTreeExec(elegido) then
    if elegido <> '' then Detalles(elegido);
end;

var
  apik, nombre: string;
begin
  apik := GetParam('API_KEY');
  if (Trim(apik) = '') or (apik = 'PON_AQUI_TU_APIKEY') then
  begin
    ShowMessage('Falta la API Key de TMDB.' + #13#10 + 'Ponla en Propiedades del script > pestaña de parametros (API_KEY).');
    Exit;
  end;
  nombre := Trim(GetField(fieldTranslatedTitle));
  if nombre = '' then nombre := Trim(GetField(fieldOriginalTitle));
  if not Input('TMDB (ES)', 'Buscar pelicula en TMDB:', nombre) then Exit;
  if Trim(nombre) = '' then Exit;
  Buscar(nombre);
end.