html5ks.imachine = (function () { "use strict"; return { seen_scene: function (scene) { return !!html5ks.store.seen_scenes[scene]; }, scene_register: function (scene) { html5ks.store.seen_scenes[scene] = true; }, start: function () { return this.run("imachine"); }, run: function (label) { var deferred = when.defer(), ilabel = typeof label === "string" ? html5ks.data.imachine[label] || label : label, i = 0, runInst = function () { var inst = ilabel[i++]; console.log(inst); switch (typeof inst) { case "undefined": deferred.resolve(); break; case "string": // jump_out if (!html5ks.data.imachine[inst]) { throw new Error("label does not exist"); } this.run(inst); break; case "object": var cmd = inst[0]; var args = inst.slice(1); switch (inst[0]) { case "iscene": this.scene_register(inst[1]); case "act_op": switch (inst[1]) { case "op_vid1": html5ks.api.movie_cutscene("op_1").then(runInst); break; default: html5ks.api[cmd].apply(html5ks.api, args).then(function () { runInst(); }); } break; case "imenu": html5ks.api.menu(args[0]).then(function (choice) { var next = args[1][choice] || args[1].else; return html5ks.imachine.run(typeof next[0] === "string" ? [next] : next).then(runInst); }); break; case "seen_scene": var next; if (this.seen_scene(inst[1])) { next = inst[2]; } else { next = inst[3]; } // TODO: there's probably an easier way to do this this.run(typeof next[0] === "string" ? [next] : next).then(runInst); break; case "attraction": if (typeof inst[2] === "number") { if (html5ks.store.attraction[inst[1]] > inst[2]) { runInst(inst[3]); } else { runInst(inst[4]); } } else { html5ks.store.attraction[inst[1]]++; runInst(); } break; case "path_end": // TODO: disp vid deferred.resolve(); break; default: console.error("unknown imachine inst"); console.log(inst); } } }.bind(this); runInst(); return deferred.promise; } }; }());