
/*!
 * Web Cabin Play - Node based visual scripting tool.
 *
 * Dependancies:
 *  JQuery 1.11.1
 *  font-awesome 4.2.0
 *  wcMenu
 * Optional Dependencies:
 *  FileSaver.js
 *  wcUndoManager
 *
 * Author: Jeff Houde (lochemage@webcabin.org)
 * Web: http://play.webcabin.org/
 * API: http://play.api.webcabin.org/
 *
 * Licensed under
 *   MIT License http://www.opensource.org/licenses/mit-license
 *
 */
wcPlayNodes.wcNodeEntry.extend("wcNodeEntryStart","Start","Automatic",{init:function(e,t){this._super(e,t),this.description("When the script starts, this will activate immediately and only once.")},onStart:function(){this._super(),this.onActivated()}}),wcPlayNodes.wcNodeEntry.extend("wcNodeEntryUpdate","Update","Automatic",{init:function(e,t){this._super(e,t),this.description("Once the script starts, this will activate continuously any time attached nodes have finished.")},onActivated:function(e){this._super(e),this.resetThreads(),this.activateExit("out",function(){this.onActivated()})},onStart:function(){this._super(),this.onActivated()},onPropertyChanged:function(e,t,n){this._super(e,t,n),e==="milliseconds"&&(this.resetThreads(),this.onActivated())}}),wcPlayNodes.wcNodeEntry.extend("wcNodeEntryInterval","Interval","Automatic",{init:function(e,t){this._super(e,t),this.description("Once the script starts, this will activate continuously on a time interval defined by the milliseconds property."),this.createProperty("milliseconds",wcPlay.PROPERTY.NUMBER,1e3,{description:"The time, in milliseconds, per update.",input:!0})},onActivated:function(e){this._super(e),this.resetThreads();var t=this.property("milliseconds");this.setInterval(function(){this.activateExit("out")},t)},onStart:function(){this._super(),this.onActivated()},onPropertyChanged:function(e,t,n){this._super(e,t,n),e==="milliseconds"&&this.onActivated()}}),wcPlayNodes.wcNodeEntry.extend("wcNodeEntryRemote","Remote Event","Flow Control",{init:function(e,t){this._super(e,t),this.description("An entry node that fires when a Call Remote Event Node of the same name is activated."),this.details("This node uses it's Title Name value as an identifier that links it with any Call Remote Event Nodes of the same name. Whenever any Call Remote Event Node of the same name is activated, this Node will become active as well. If multiple Remote Nodes exist with the same name, they will all be called in parallel.")}}),wcPlayNodes.wcNodeEntry.extend("wcNodeEntryCallRemote","Call Remote Event","Flow Control",{init:function(e,t){this._super(e,t),this.description("An entry node that activates all Remote Event Nodes of the same name."),this.details("This node uses it's Title Name value as an identifier that links it with any Remote Event Nodes of the same name. Whenever this Node is activated, All Remote Event Nodes of the same name will also become active as well."),this.createEntry("in"),this.removeExit("out"),this.createProperty("local",wcPlay.PROPERTY.TOGGLE,!0,{description:"If true, only matching Remote Event Nodes that are within, or nested within, the same Composite Node or scope will be activated."})},onActivated:function(e){this._super(e);var t=this.engine(),n=t;this.property("local")&&(n=this._parent);var r=n.nodesByClassName("wcNodeEntryRemote");for(var i=0;i<r.length;++i)r[i].name===this.name&&t.queueNodeEntry(r[i],"in",this,"out",!1,t.beginFlowTracker(this,this._activeTracker))}}),wcPlayNodes.wcNodeProcess.extend("wcNodeProcessDelay","Delay","Flow Control",{init:function(e,t){this._super(e,t),this.description("Waits for a specified amount of time before continuing the flow chain."),this.createProperty("milliseconds",wcPlay.PROPERTY.NUMBER,1e3,{description:'The time delay, in milliseconds, to wait before firing the "out" Exit link.',input:!0})},onActivated:function(e){this._super(e);var t=this.property("milliseconds");this.setTimeout(function(){this.activateExit("out")},t)}}),wcPlayNodes.wcNodeProcess.extend("wcNodeProcessOperation","Operation","Data Manipulation",{init:function(e,t){this._super(e,t),this.description("Performs a simple math operation on two values."),this.details("Activate the entry link of the operation you want to perform, either an addition, subtraction, multiplication, or division. The operation will then be performed using valueA and valueB, the result will be output to the result property."),this.removeEntry("in"),this.createEntry("add","valueA + valueB = result"),this.createEntry("sub","valueA - valueB = result"),this.createEntry("mul","valueA * valueB = result"),this.createEntry("div","valueA / valueB = result"),this.createProperty("valueA",wcPlay.PROPERTY.NUMBER,0,{description:"Left hand value for the operation.",input:!0}),this.createProperty("valueB",wcPlay.PROPERTY.NUMBER,0,{description:"Right hand value for the operation.",input:!0}),this.createProperty("result",wcPlay.PROPERTY.NUMBER,0,{description:"The result of the operation.",output:!0})},onActivated:function(e){this._super(e);var t=parseFloat(this.property("valueA")),n=parseFloat(this.property("valueB")),r;switch(e){case"add":r=t+n;break;case"sub":r=t-n;break;case"mul":r=t*n;break;case"div":r=t/n}this.property("result",r,!0),this.activateExit("out")}}),wcPlayNodes.wcNodeProcess.extend("wcNodeProcessStrCat","String Concat","Data Manipulation",{init:function(e,t){this._super(e,t),this.description("Concatenates two string values."),this.details("This takes the string of valueA and appends valueB to it, the result is stored in the result property."),this.createProperty("valueA",wcPlay.PROPERTY.STRING,"",{description:"The left side string to join.",input:!0}),this.createProperty("valueB",wcPlay.PROPERTY.STRING,"",{description:"The right side string to join.",input:!0}),this.createProperty("result",wcPlay.PROPERTY.STRING,"",{description:"The concatenated result.",output:!0})},onActivated:function(e){this._super(e),this.property("result",this.property("valueA").toString()+this.property("valueB")),this.activateExit("out")}}),wcPlayNodes.wcNodeProcess.extend("wcNodeProcessAJAX","AJAX","Data Retrieval",{init:function(e,t){this._super(e,t),this.description("Performs an AJAX request."),this.details("Once activated, a request will be sent to the given URL.  Either the success or failure exit links will activate once the operation is completed and the result will be assigned to the result property."),this.removeExit("out"),this.createExit("success"),this.createExit("failure"),this.createProperty("type",wcPlay.PROPERTY.SELECT,"GET",{items:["GET","POST","PUT","DELETE","HEAD"],description:"The AJAX method to perform.",input:!0,allowNone:!1}),this.createProperty("url",wcPlay.PROPERTY.STRING,"example.com",{description:"The URL to send the request.",input:!0}),this.createProperty("data",wcPlay.PROPERTY.STRING,"foo=bar&bar=foo",{description:"The data to send with the request. This can be in query string form, or any object that $.ajax supports as the data parameter.",input:!0}),this.createProperty("result",wcPlay.PROPERTY.STRING,"",{description:"The result of the ajax request, if successful.",output:!0})},onActivated:function(e){this._super(e);var t=this.property("type"),n=this.property("url"),r=this.property("data");if(!n){this.activateExit("failure");return}this.ajax({type:t,url:n,data:r,success:function(e){this.property("result",e),this.activateExit("success")},error:function(e,t,n){this.property("result",n),this.activateExit("failure")}})}}),wcPlayNodes.wcNodeProcess.extend("wcNodeProcessFetch","Fetch Request","Data Retrieval",{init:function(e,t){this._super(e,t),this.description("Performs a fetch request."),this.details("Once activated, a request will be sent to the given URL. Either the success or failure exit links will activate once the operation is completed and the result will be assigned to the result property."),this.removeExit("out"),this.createExit("success"),this.createExit("failure"),this.createProperty("type",wcPlay.PROPERTY.SELECT,"GET",{items:["GET","POST","PUT","DELETE","HEAD"],description:"The request method to perform.",allowNone:!1}),this.createProperty("url",wcPlay.PROPERTY.STRING,"http://www.example.com",{description:"The URL to send the request.",input:!0}),this.createProperty("headers",wcPlay.PROPERTY.SELECT,"text/plain",{items:["text/plain"],description:"The expected response data type (for now, only support text/plain).",allowNone:!1}),this.createProperty("mode",wcPlay.PROPERTY.SELECT,"cors",{items:["cors","no-cors","same-origin"],description:"The mode.",allowNone:!1}),this.createProperty("credentials",wcPlay.PROPERTY.SELECT,"omit",{items:["omit","same-origins"],description:"Should cookies go with the request?",allowNone:!1}),this.createProperty("redirect",wcPlay.PROPERTY.SELECT,"follow",{items:["follow","error","manual"],description:"What happens if the request redirects you?",allowNone:!1}),this.createProperty("integrity",wcPlay.PROPERTY.STRING,"",{description:"Subresource integrity value."}),this.createProperty("cache",wcPlay.PROPERTY.SELECT,"default",{items:["default","reload","no-cache"],description:"Cache mode.",allowNone:!1}),this.createProperty("data",wcPlay.PROPERTY.STRING,"{}",{description:"The data to send with the request. This should be in the form of an object or JSON string.",input:!0,multiline:!0}),this.createProperty("result",wcPlay.PROPERTY.STRING,"",{description:"The result of the fetch request.",output:!0,readonly:!0,multiline:!0})},onActivated:function(e){this._super(e);var t=this.property("type"),n=this.property("url"),r=this.property("headers"),i=this.property("mode"),s=this.property("credentials"),o=this.property("redirect"),u=this.property("integrity"),a=this.property("cache"),f=this.property("data");if(!n){this.activateExit("failure");return}var l=this,c=this.fetch(n,{method:t,headers:{"Content-Type":r},mode:i,credentials:s,redirect:o,integrity:u,cache:a,data:JSON.stringify(f)});c.then(function(e){l.property("result",e),l.activateExit("success")}).catch(function(e){l.property("result",e.message),l.activateExit("failure")})}}),wcPlayNodes.wcNodeProcess.extend("wcNodeProcessConsoleLog","Console Log","Debugging",{init:function(e,t){this._super(e,t),this.description("For debugging purposes, will print out a message into the console log when activated (only if silent mode is not on)."),this.createProperty("message",wcPlay.PROPERTY.STRING,"msg",{description:"The message that will appear in the console log.",input:!0})},onActivated:function(e){this._super(e),this.activateExit("out");var t=this.engine();if(!t||t.silent())return;var n=this.property("message");console.log(n)}}),wcPlayNodes.wcNodeProcess.extend("wcNodeProcessAlert","Alert","Debugging",{init:function(e,t){this._super(e,t),this.description("For debugging purposes, will popup an alert box with a message when activated (only if silent mode is not on)."),this.createProperty("message",wcPlay.PROPERTY.STRING,"Alert message.",{multiline:!0,description:"The message that will appear in the alert box.",input:!0})},onActivated:function(e){this._super(e),this.activateExit("out");var t=this.engine();if(!t||t.silent())return;var n=this.property("message");alert(n)}}),wcPlayNodes.wcNodeStorage.extend("wcNodeStorageGlobal","Global Value","Global",{init:function(e,t){this._super(e,t),this.color="#77CC77",this.description("References a global property on the script."),this.details("The title name for this node becomes the name of the global property it references. Duplicate Global Nodes with the same name will all reference the same value."),this.createProperty("value",wcPlay.PROPERTY.STRING,"",{description:"The current value of the global property (Use the title to identify the property).",input:!0,output:!0})},onNameEditSuggestion:function(){this._super();var e=this.engine();if(e){var t=e.listProperties(),n=[];for(var r=0;r<t.length;++r)n.push(t[r].name);return n}},onNameChanged:function(e,t,n){this._super(e,t,n);var r=this.engine();if(r){r.createProperty(t,wcPlay.PROPERTY.STRING,"");var i=r.listProperties(),s=0,o=r.nodesByClassName(this.className);for(s=0;s<o.length;++s){var u=o[s].name;for(var a=0;a<i.length;++a)if(i[a].name===u){i.splice(a,1);break}}for(s=0;s<i.length;++s)n&&n.addEvent("",{engine:r,name:i[s].name,type:i[s].type,options:i[s].options,value:i[s].value,initialValue:i[s].initialValue},function(){this.engine.createProperty(this.name,this.type,this.initialValue,this.options),this.engine.property(this.name,this.value)},function(){this.engine.removeProperty(this.name)}),r.removeProperty(i[s].name);this.property("value",r.property(t)),this.initialProperty("value",r.initialProperty(t))}},onPropertyChanged:function(e,t,n){this._super(e,t,n);if(e==="value"&&this.name){var r=this.engine();r&&r.property(this.name,n)}},onPropertyGet:function(e){this._super(e);if(e==="value"&&this.name){var t=this.engine();return t&&t.property(this.name)}},onInitialPropertyChanging:function(e,t,n){this._super(e,t,n);if(e==="value"&&this.name){var r=this.engine();r&&r.initialProperty(this.name,n)}},onInitialPropertyGet:function(e){this._super(e);if(e==="value"&&this.name){var t=this.engine();return t&&t.initialProperty(this.name)}},onGlobalPropertyChanged:function(e,t,n){this.name===e&&(this.property("value",n,!0,!0),this._meta.dirty=!0)},onGlobalInitialPropertyChanged:function(e,t,n){this.name===e&&(this.initialProperty("value",n,!0,!0),this._meta.dirty=!0)},onGlobalPropertyRemoved:function(e){this.name==e&&(this.name="")},onGlobalPropertyRenamed:function(e,t){this.name==e&&(this.name=t)}}),wcPlayNodes.wcNodeStorage.extend("wcNodeStorageString","String","Local",{init:function(e,t){this._super(e,t),this.description("Stores a string value."),this.createProperty("value",wcPlay.PROPERTY.STRING,"",{multiline:!0,input:!0,output:!0})}}),wcPlayNodes.wcNodeStorage.extend("wcNodeStorageNumber","Number","Local",{init:function(e,t){this._super(e,t),this.description("Stores a number value."),this.createProperty("value",wcPlay.PROPERTY.NUMBER,"",{input:!0,output:!0})}}),wcPlayNodes.wcNodeStorage.extend("wcNodeStorageToggle","Toggle","Local",{init:function(e,t){this._super(e,t),this.description("Stores a boolean (toggleable) value."),this.createProperty("value",wcPlay.PROPERTY.TOGGLE,!1,{input:!0,output:!0})}})