﻿// =====================================================================
// Câmera por cena (recriação @subzmotion "On My Way")
// Cria o null "CAM" numa comp 1080x1080 com 4 controles e liga o transform a eles:
//   Zoom (log2)  -> Escala = 100 * 2^zoom   (0 = tamanho do quadro de referência; 1 = 2x; -1 = metade)
//   Mira X/Y     -> Ponto de ancoragem: o ponto do MUNDO que fica no centro da tela
//   Giro         -> Rotação
// Tudo que é "mundo" (interface, textos, fotos, encaixes) vira filho do CAM, com posição em coordenadas do
// mundo (px do quadro de referência do original). Assim o mesmo mundo serve para qualquer câmera.
// Uso (ES3, dentro de um eval.run):  $.evalFile(".../ae/camera.jsx");  var cam = CAMERA_criar(comp, ".../camera/cena-A-agenda.json");
// O JSON traz chaves por quadro (câmera medida no original). Para editar à mão, mexa nos keyframes dos controles.
// =====================================================================
function CAMERA_lerJSON(caminho) {
  var f = new File(caminho); f.encoding = "UTF-8"; f.open("r"); var s = f.read(); f.close();
  return eval("(" + s + ")");
}
function CAMERA_slider(lay, nome, valor) {
  var fx = lay.property("ADBE Effect Parade").addProperty("ADBE Slider Control");
  fx.name = nome; fx.property(1).setValue(valor);
}
function CAMERA_chaves(prop, lista, deMundo) {
  // lista = [[t, v], ...] ; chaves lineares quadro a quadro (a curva já vem medida)
  var ts = [], vs = [], i;
  for (i = 0; i < lista.length; i++) { ts.push(lista[i][0]); vs.push(lista[i][1]); }
  prop.setValuesAtTimes(ts, vs);
  for (i = 1; i <= prop.numKeys; i++) prop.setInterpolationTypeAtKey(i, KeyframeInterpolationType.LINEAR, KeyframeInterpolationType.LINEAR);
}
function CAMERA_criar(comp, caminhoJSON) {
  var d = CAMERA_lerJSON(caminhoJSON);
  var cam = comp.layers.addNull(comp.duration);
  cam.name = "CAM"; cam.label = 1; cam.enabled = false; // null invisível; só transforma os filhos
  // adicionar efeito invalida referências antigas: cria os 4 controles primeiro, depois busca cada um pelo nome
  CAMERA_slider(cam, "Zoom (log2)", 0); CAMERA_slider(cam, "Mira X", 540); CAMERA_slider(cam, "Mira Y", 540); CAMERA_slider(cam, "Giro", 0);
  var fxs = cam.property("ADBE Effect Parade");
  CAMERA_chaves(fxs.property("Zoom (log2)").property(1), d.chaves.zoom);
  CAMERA_chaves(fxs.property("Mira X").property(1), d.chaves.mx);
  CAMERA_chaves(fxs.property("Mira Y").property(1), d.chaves.my);
  CAMERA_chaves(fxs.property("Giro").property(1), d.chaves.giro);
  var tr = cam.property("ADBE Transform Group");
  tr.property("ADBE Anchor Point").expression = '[effect("Mira X")(1), effect("Mira Y")(1)]';
  tr.property("ADBE Position").expression = '[thisComp.width/2, thisComp.height/2]';
  tr.property("ADBE Scale").expression = 'var s = 100*Math.pow(2, effect("Zoom (log2)")(1)); [s, s]';
  tr.property("ADBE Rotate Z").expression = 'effect("Giro")(1)';
  cam.inPoint = 0; cam.outPoint = comp.duration;
  return cam;
}
// Encaixe: coloca uma comp (cena vizinha, 1080x1080) dentro do mundo, com centro/lado/giro do encaixes.json.
// "lado" = largura no mundo que a cena encaixada ocupa no instante da troca (preenche a tela exatamente).
function CAMERA_encaixe(comp, cam, itemCena, centro, lado, giro, nome) {
  var L = comp.layers.add(itemCena); L.name = nome || ("ENCAIXE " + itemCena.name);
  L.parent = cam; L.startTime = 0;
  var tr = L.property("ADBE Transform Group");
  tr.property("ADBE Anchor Point").setValue([itemCena.width / 2, itemCena.height / 2]);
  tr.property("ADBE Position").setValue(centro);
  var e = 100 * lado / itemCena.width; tr.property("ADBE Scale").setValue([e, e]);
  tr.property("ADBE Rotate Z").setValue(giro || 0);
  return L;
}
