var imloadindex = 0;
var imphaseindex = 0;
var fadeopacity = 0;
var movestate = 0;
var bkg1, bkg2, bkg1img, bkg2img;
var imloadorder = [];
var imtick_timeout = null;
var im_inited = false;
var im_history = [];
function imloadnext() {
  var image = new Image();
  image.onload = function() {
    im[imloadorder[imloadindex]].ready = true;
    if (imloadindex < imloadorder.length-1) {
      imloadindex++;
      imloadnext();
    }
  };
  image.src = im[imloadorder[imloadindex]].src;
  im[imloadorder[imloadindex]].img = image;
}
function im_forcenext() {
  if (!im_inited) return;
  if (imtick_timeout) clearTimeout(imtick_timeout);
  imtick();
}
function im_forceprev() {


  // broken!!


  if (!im_inited) return;
  if (imphases[imphaseindex-1].action != "delay") return;
  if (imtick_timeout) clearTimeout(imtick_timeout);
  if (im_history.length > 1) { // need at least one before this to jump
    im_history.pop(); // discard current
    imphaseindex = im_history.pop()+1; // jump just after the last delay
  } else {
    im_history = [];
    for (var i=imphases.length-1; i>0; i--) {
      if (imphases[i].action = "delay") {
        imphaseindex = i+1;
        break;
      }
    }
  }
  imtick();
}
function imtick() {
  var tickdelay = 100;
  im_inited = true;

  while(imphases[imphaseindex].once==2) {imphaseindex++;}
  var phase = imphases[imphaseindex];

  if ("label" in phase) {
    var details = document.getElementById("ss_details");
    var label = document.getElementById("ss_details_label");
    if (phase.label.length) {
      details.style.display = "";
      label.innerHTML = phase.label;
    } else {
      details.style.display = "none";
    }
  }

  if (phase.action == "appear") {
    if (im[phase.im].ready) {
      add(bkg1, "img", {src:im[phase.im].src});
      setopacity(bkg1, 1);
      setopacity(bkg2, 0);
      if (phase.once) {imphases[imphaseindex].once=2;}
      imphaseindex++;
    }
  } else if (phase.action == "fade") {
    if (im[phase.im].ready) {
      if (phase.frame) {
        //fade specific frame
        setopacity(getobj(phase.frame), fadeopacity);
        if (fadeopacity == 0) {
          removecontents(getobj(phase.frame));
          var image = new Image();
          image.src = im[phase.im].src;
          getobj(phase.frame).appendChild(image);
        }
      } else {
        //fade background with swap
        if (fadeopacity == 0) {
          setopacity(bkg1, 1);
          //if (bkg2.childNodes.length) {removecontents(bkg1);bkg1.appendChild(bkg2.firstChild);};
          if (bkg2.childNodes.length) {bkg1.firstChild.src = bkg2.firstChild.src;};
          setopacity(bkg2, 0);
          removecontents(bkg2);
          setTimeout(function(){add(bkg2, "img", {src:im[phase.im].src});}, 0); //give some browsers a chance to resolve the opacity first
        }
        setopacity(bkg2, fadeopacity);
      }
      if (fadeopacity >= 1) {
        fadeopacity = 0;
        if (phase.once) {imphases[imphaseindex].once=2;}
        imphaseindex++;
      } else {
        fadeopacity += phase.rate;
      }
    }
  } else if (phase.action == "move") {
    if (im[phase.im].ready) {
      if (movestate == 0) {
        removecontents(getobj(phase.frame));
        var img = add(getobj(phase.frame), "img");
        img.style.position = "absolute";
        img.style.left = phase.start[0] + "px";
        img.style.top = phase.start[1] + "px";
        img.src = im[phase.im].src;
        movestate = 1;
      }
      var img = getobj(phase.frame).firstChild;
      var cx = parseInt(img.style.left);
      var cy = parseInt(img.style.top);
      if (Math.abs(cx) <= Math.abs(phase.delta[0]) && Math.abs(cy) <= Math.abs(phase.delta[1])) {
        img.style.position = "static";
        movestate = 0;
        if (phase.once) {imphases[imphaseindex].once=2;}
        imphaseindex++;
      } else {
        img.style.left = (cx + phase.delta[0]) + "px";
        img.style.top = (cy + phase.delta[1]) + "px";
        tickdelay = 0;
      }
    }
  } else if (phase.action == "delay") {
    if (phase.once) {imphases[imphaseindex].once=2;}
    im_history.push(imphaseindex);
    while (im_history.length > 100) im_history.shift();
    imphaseindex++;
    tickdelay = phase.time*1000;
  } else if (phase.action == "goto") {
    if (phase.once) {imphases[imphaseindex].once=2;}
    imphaseindex = phase.phase;
  }

  imtick_timeout = setTimeout(imtick, tickdelay);
}

