(function ($s, $e) {
    var Canvas = function (_options) {
        var _self = this, _warnBar;

        if (!(_self instanceof Canvas))
            return new Canvas(_options);

        var options = {
            baseUrl: ''
            , parentContainer: ''
            , slate: null
            , user: {}
            , owningUserProfile: ''
        };

        $s.extend(options, _options);

        _self.getNewSlateJson = function (_name, _description) {
            var _place = document.createElement("div");
            _place.style.display = "none";
            document.body.appendChild(_place);

            var _newSlate = $s.instance.slate({ container: _place, viewPort: { width: 50000, height: 50000, allowDrag: true, left: 5000, top: 5000 }, name: _name, description: _description }).canvas.init();
            var _nodes = [
                $s.instance.node({ name: 'MASTER_NODE', text: 'Start Here', fontSize: 20, xPos: 5500, yPos: 5300, height: 75, width: 125, vectorPath: 'roundedrectangle', backgroundColor: '90-#FF0000-#a31616', lineColor: "blue", lineWidth: 3 })
            ];
            _newSlate.nodes.addRange(_nodes);

            var _json = _newSlate.exportJSON();
            document.body.removeChild(_place);
            return _json;
        };

        var onSlateSel = function (json) {
            if ($s.isFunction(options.onSlateUpdated)) {
                options.onSlateUpdated.apply(this, [json]);
            }
        };

        var _urls = [
              { type: 'get', url: options.baseUrl + '/GetSlates?page={page}&rpp={rpp}' }
            , { type: 'del', url: options.baseUrl + '/DeleteSlate' }
            , { type: 'active', url: options.baseUrl + '/SetActiveSlate' }
            , { type: 'save', url: options.baseUrl + '/SaveSlate' }
            , { type: 'deletekey', url: options.baseUrl + '/Collaboration/Delete/{slateid}' }
            , { type: 'addkey', url: options.baseUrl + '/Collaboration/AddKey/{slateid}' }
            , { type: 'update', url: options.baseUrl + "/UpdateUser" }
            , { type: 'userDevDetails', url: options.baseUrl + "/User/DevDetails" }
        ];

        var buttons = [
            { height: 315, file: 'openSlate', el: "lnkOpenSlate", onSlateSelected: onSlateSel }
            , { height: 300, file: 'newSlate', el: "lnkNewSlate", onSlateSelected: onSlateSel }
            , { height: 150, file: 'embed', el: "lnkEmbedSlate", popFromBottom: true }
            , { height: 0, file: 'exporter', el: "lnkExportSlate" }
            , { height: 260, file: 'properties', el: "lnkProperties" }
            //, { height: 0, file: 'save', el: "lnkSave" }
            , { height: 100, file: 'collaboration', el: "lnkCollaborate", popFromBottom: true }
            , { height: 300, file: 'account', el: "lnkAccount" }
            , { height: 150, file: 'developer', el: "lnkDeveloper" }
        ];

        _self.url = function (type) {
            var _url = '';
            $s.each(_urls, function () {
                if (this.type === type) {
                    _url = this.url;

                    //ajax requests
                    _gaq.push(['_trackEvent', 'Slate', this.type, this.url]);
                    return;
                }
            });
            return _url;
        };

        _self.fire = function (file) {
            var btn = null;
            $s.each(buttons, function () {
                if (this.file === file) {
                    btn = this;
                    return;
                }
            });
            if (btn.height > 0) {
                new Notify().message({
                    hgt: btn.height
                        , duration: 100
                        , className: 'embedBar'
                        , delayClose: 0
                        , spinner: null
                        , popFromBottom: btn.popFromBottom || false
                        , hideClose: false
                        , onOpen: function (container, _ntfy) {
                            var _invoke = eval('_self.' + btn.file);
                            _warnBar = document.createElement("div");
                            var _bottomBar = document.createElement("div");
                            container.appendChild(_warnBar);
                            container.appendChild(_bottomBar);

                            var _btnOptions = $s.extend(btn, {
                                c: _bottomBar
                                , u: 'Template/' + btn.file
                                , n: _ntfy
                                , onToggleSwitch: function (prop, isOn) {
                                    alert(prop + " : " + isOn);
                                }
                                , initToggle: []
                            });

                            _invoke.apply(_self, [_btnOptions]);
                        }
                });
            } else {
                var _invoke = eval('_self.' + btn.file);
                _invoke.apply(_self, [btn]);
            }
        };

        $s.each(buttons, function () {
            var btn = this;
            $s.el(btn.el).onclick = function (e) {
                _self.fire(btn.file);
            }
        });

        _self.getOption = function (key) { return options[key]; };

        _self.showMsg = function (txt, klass) {
            if (klass === undefined) klass = 'pd_warn';
            _warnBar.setAttribute("class", klass);
            $e(_warnBar, "height: 30px", {
                duration: 200
                , after: function () {
                    _warnBar.innerHTML = txt + " <span style='font-size:8pt;'>(click to close)</span>";
                    _warnBar.onclick = function (e) {
                        _self.removeMsg();
                    };
                }
            });
        };

        _self.removeMsg = function () {
            _warnBar.innerHTML = "";
            $e(_warnBar, "height: 0px", {
                duration: 200
                , after: function () {
                    _warnBar.setAttribute("class", "");
                }
            });
        };

        _self.loadContent = function (url, callback) {
            $s.ajax(url, function (respText, resp) {
                callback.apply(this, [respText]);
            });
        };

        _self.wireSwitches = function (init, callback) {
            var _switches = [];
            $s.each($s.select('div.sb_switch'), function () {
                var _btn = this;
                var _id = $s.onOff(_self.getOption("baseUrl"), _btn, function (id) {
                    $s.toggleOnOff(id);
                    if ($s.isFunction(callback)) {
                        callback.apply(this, [_btn.getAttribute("rel"), $s.isOn(id)]);
                    }
                });
                _switches.push({ id: _id, name: _btn.getAttribute("rel") });
            });
            return _switches;
        };

        _self.welcome = function (intro) {
            if (!intro) intro = "Hi and welcome to Slatebox!";
            //welcome to slatebox...no slates yet
            new Notify().message({
                hgt: 132
                , duration: 100
                , className: 'embedBar'
                , delayClose: 0
                , spinner: null
                , popFromBottom: true
                , hideClose: false
                , onOpen: function (container, _ntfy) {
                    container.innerHTML = "<div style='width:900px;'><div style='font-size:16pt;width:880px;'><span style='font-size: 20pt;color:#3E7C3E'>" + intro + "</span> <a href='http://youtu.be/zykzgsQIqeE' target='_blank' style='color:#fff;'>Please click here for a really simple overview of how to use Slatebox.</a><div>" +
                        "<div style='font-size:10pt;margin-top:20px;padding:5px;border-top:1px dashed #ccc;width:880px;'>If you have any questions, please email us at <a href='mailto:support@slatebox.com' style='color:#fff;'>support@slatebox.com</a> and we'd love to help. Have fun!</div></div>";
                }
            });
        };

        window.Canvas.instance = _self;
    };
    window.Canvas = Canvas;
    Canvas.fn = Canvas.prototype = {};
})(Slatebox, emile);(function ($s, $c) {
    $c.fn.account = function (_options) {
        var _self = this, u = {}, url = _self.url("update");

        var options = {
            c: null
            , u: null
            , initToggle: null
            , onSwitchToggle: null
        }

        $s.extend(options, _options);

        _self.loadContent(options.u, function (content) {
            u = _self.getOption("user");
            u.IsActive = true;

            var burl = _self.getOption("baseUrl");
            options.c.innerHTML = content.replace(/{userName}/g, u.name).replace(/{baseUrl}/g, burl).replace(/{verify}/g, (u.IsEmailVerified ? "" : " <span style='color:red;font-size:10pt;'>(unverified)</span>"));

            var _ids = _self.wireSwitches(options.initToggle, function (prop, isOn) {
                u[prop] = isOn;
                var _msg = '';
                switch (prop) {
                    case "IsProfilePublic":
                        if (isOn) _msg = "Your profile at " + burl + "/" + u.name + " <b>is now PUBLIC</b>!";
                        else _msg = "Your profile at " + burl + "/" + u.name + " <b>is NO LONGER</b> public!";
                        break;
                }
                update(_msg);
            });

            var _getId = '';
            if (u.IsProfilePublic) {
                $s.each(_ids, function () { if (this.name === "IsProfilePublic") { _getId = this.id; return; } });
                $s.toggleOnOff(_getId);
            }

            //wire up profile image
            $s.el("imgUserProfile").src = _self.getOption("owningUserProfile");

            $s.el("lnkDeactivate").onclick = function (e) {
                if (confirm("Are you sure you would like to deactivate your account? You will no longer have access to any of your slates!")) {
                    u.IsActive = false;
                    $s.ajax(url, function (respText, resp) {
                        alert('Your account has been deactivated');
                        window.location.href = _self.getOption("baseUrl") + '/Logout';
                    }, JSON.stringify(u));
                }
            };

            $s.el("btnConfirmPasswordChange").onclick = function (e) {
                if ($s.el("txtNewPassword").value === "" || $s.el("txtNewPasswordConfirm").value === "") {
                    _self.showMsg("You must have values for both the new and the confirmed password!", "pd_warn");
                } else if ($s.el("txtNewPassword").value !== $s.el("txtNewPasswordConfirm").value) {
                    _self.showMsg("The passwords do not match!", "pd_warn");
                } else {
                    u.Password =$s.el("txtNewPassword").value;
                    update("Your password has been changed!");
                }
            };

            $s.el("txtEmail").value = u.email;
            if (!u.IsEmailVerified) {
                $s.el("txtEmail").style.backgroundColor = 'red';
            }
            $s.el("btnUpdateEmail").onclick = function (e) {
                if (!validEmail($s.el("txtEmail").value)) {
                    _self.showMsg("Your email is invalid!", "pd_warn");
                } else {
                    u.Email = $s.el("txtEmail").value;
                    update("Your email has been updated!");
                }
            };
        });

        function update(msg) {
            $s.ajax(url, function (respText, resp) {
                _self.showMsg(msg, "pd_info");
            }, JSON.stringify(u));
        };

        function validEmail(email) {
            var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
            return email.match(re);
        };

        return _self;
    }
})(Slatebox, Canvas);(function ($s, $c) {
    $c.fn.collaboration = function (_options) {
        var _self = this;

        var options = {
            c: null
            , u: null
            , initToggle: null
            , onSwitchToggle: null
        }

        $s.extend(options, _options);

        _self.loadContent(options.u, function (content) {
            options.c.innerHTML = content;
            _self.wireSwitches(options.onToggleSwitch);
            var _slate = _self.getOption("slate");

            var _ids = _self.wireSwitches(options.initToggle, function (prop, isOn) {
                _slate.options[prop].allow = isOn;
                $s.ajax(_self.url("save"), function (respText, resp) {
                    var _msg = '';
                    switch (prop) {
                        case "collaboration":
                            if (isOn) {
                                _self.showMsg("You have enabled collaboration", "pd_info");
                                addOrGetKey();
                            } else {
                                $s.ajax(_self.url("deletekey").replace(/{slateid}/g, _slate.options.id), function (respText, resp) {
                                    _self.showMsg("You have disabled collaboration", "pd_info");
                                    $s.el("collaborationDetails").style.display = "none";
                                    $s.el("collaborationUrl").innerHTML = "";
                                }, '{}', "DELETE");
                            }
                            break;
                    }
                }, _slate.exportJSON());
            });

            function addOrGetKey() {
                $s.ajax(_self.url("addkey").replace(/{slateid}/g, _slate.options.id), function (respText, resp) {
                    var obj = JSON.parse(respText);
                    $s.el("collaborationDetails").style.display = "block";
                    $s.el("collaborationUrl").innerHTML = obj.url;

                    $s.each($s.select("a.twitter-share-button"), function () {
                        this.setAttribute("data-url", obj.url);
                    });

                    //call the tweet button
                    var d = document, s = "script", id = "twitter-wjs";
                    var js, fjs = d.getElementsByTagName(s)[0]; if (!d.getElementById(id)) { js = d.createElement(s); js.id = id; js.src = "//platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs); };

                }, '{}', "PUT");
            };

            if (_slate.options.collaboration && _slate.options.collaboration.allow) {
                //save the slate to ensure the latest updates
                $s.ajax(_self.url("save"), function (respText, resp) {
                    var _getId = "";
                    $s.each(_ids, function () { if (this.name === "collaboration") { _getId = this.id; return; } });
                    $s.toggleOnOff(_getId);
                    addOrGetKey();
                }, _slate.exportJSON());
            }
        });
        return _self;
    }
})(Slatebox, Canvas);(function ($s, $c) {
    $c.fn.embed = function (_options) {
        var _self = this, _slate;

        var options = {
            c: null
            , u: null
            , initToggle: null
            , onSwitchToggle: null
        }

        $s.extend(options, _options);

        var apiKey = '';
        _self.loadContent(options.u, function (content) {
            options.c.innerHTML = content;
            _self.wireSwitches(options.onToggleSwitch);

            $s.el("slateSize").value = '400';

            _slate = _self.getOption("slate");

            var u = _self.getOption("user");
            $s.ajax(_self.url('userDevDetails'), function (respText, resp) {
                var det = JSON.parse(respText);
                apikey = det.api;
                updateCode();
                $s.el("btnGenerate").onclick = function (e) {
                    updateCode();
                };
                $s.el("txtEmbeddableCode").onclick = function (e) {
                    $s.el("txtEmbeddableCode").select();
                };
            });
        });

        function updateCode() {
            if (!$s.isNumeric($s.el("slateSize").value)) {
                $s.el("txtEmbeddableCode").value = "";
                _self.showMsg("You have to provide a number for the embeddable size!", "pd_warn");
            } else {
                var _maxSize = $s.el("slateSize").value;
                var _code = $s.el("hiddenEmbeddableCode").value
                    .replace(/{slateid}/gi, _slate.options.id)
                    .replace(/{apikey}/gi, apikey)
                    .replace(/{baseUrl}/gi, _self.getOption("baseUrl"))
                    .replace(/{size}/gi, _maxSize)
                    .replace(/  /g, "")
                    .replace(/[\r\n]+(?=[^\r\n])/g, "");

                $s.el("txtEmbeddableCode").value = _code;
            }
        };

        return _self;
    }
})(Slatebox, Canvas);(function ($s, $c) {
    $c.fn.exporter = function (_options) {
        var _self = this;

        var options = {
            el: {}
            , urls: []
        }

        $s.extend(options, _options);

        $s.el(options.el).innerHTML = 'Exporting... ';

        var _slate = _self.getOption("slate");

        $s.ajax(_self.url("save"), function (respText, resp) {
            var _orx = _slate.getOrientation();

            var f = document.createElement('form');
            f.setAttribute("action", "Export");
            f.setAttribute("method", "post");
            document.body.appendChild(f);

            var fvals = [
                { k: 'orient.SlateId', v: _slate.options.id }
                , { k: 'orient.Width', v: parseInt(_orx.width) }
                , { k: 'orient.Height', v: parseInt(_orx.height) }
                , { k: 'orient.Left', v: parseInt(_orx.left) }
                , { k: 'orient.Top', v: parseInt(_orx.top) }
                , { k: 'type', v: 'png' }
            ];

            $s.each(fvals, function () {
                var h = document.createElement('input');
                h.setAttribute("type", "hidden");
                h.name = this.k;
                h.id = this.k;
                h.value = this.v;
                f.appendChild(h);
            });

            f.submit();

            setTimeout(function () {
                $s.el(options.el).innerHTML = 'Export as PNG ';
                _slate.message.show("Slate exported!", 2000);
            }, 3000);

        }, _slate.exportJSON(), "POST");

        return _self;
    }
})(Slatebox, Canvas);(function ($s, $c) {
    $c.fn.newSlate = function (_options) {
        var _self = this;

        var options = {
            c: null
            , u: null
            , initToggle: null
            , onToggleSwitch: null
            , urls: []
        }

        $s.extend(options, _options);

        _self.loadContent(options.u, function (content) {
            options.c.innerHTML = content;
            _self.wireSwitches(options.onToggleSwitch);
            $s.el("txtSlateName").focus();
            $s.el("lnkSubmit").onclick = function (e) {
                if ($s.el("txtSlateName").value === "") {
                    _self.showMsg("You have to provide a name.");
                } else {
                    $s.el("lnkSubmit").value = "creating..."
                    $s.el("lnkSubmit").setAttribute("disabled", "disabled");
                    $s.ajax(_self.url("save"), function (respText, resp) {
                        var _json = respText;
                        //_newSlate.loadJSON(respText);
                        //set active slate
                        $s.ajax(_self.url("active"), function (respText, resp) {
                            _self.removeMsg();
                            options.n.closeMessage();
                            if ($s.isFunction(options.onSlateSelected)) {
                                options.onSlateSelected.apply(this, [_json]);
                            }
                        }, JSON.stringify({ slateId: JSON.parse(_json).options.id }), 'POST');
                    }, _self.getNewSlateJson($s.el("txtSlateName").value, $s.el("txtSlateDescription").value));
                }
            };

            $s.el("txtSlateName").onclick = function (e) {
                _self.removeMsg();
            };
        });

        return _self;
    }
})(Slatebox, Canvas);(function ($s, $c) {
    $c.fn.openSlate = function (_options) {
        var _self = this, _slates = [], options = {};
        $s.extend(options, _options);

        _self.loadContent(options.u, function (content) {
            options.c.innerHTML = content;
            $s.el("loadSlates").innerHTML = "Loading...please wait.";
            var _search = $s.instance.search({
                container: "loadSlates"
                , slateStyle: ''
                , apiKey: '06eeb0435d'
                , loadUrl: _self.url('get')
                , rpp: 4
                , baseApiUrl: ''
                , outerFrameStyle: ''
                , height: 250
                , onSlateBound: function (slate, underSlate) {
                    var _tmp = "{name}&nbsp;<a href='javascript:' rel='{id}' class='deleteSlate'>Delete</a><div style='font-size:9pt;'>{description}</div>"
                    var _n = (slate.options.name || '').length > 10 ? slate.options.name.substring(0, 10) + "..." : (slate.options.name || '');
                    var _d = (slate.options.description || '').length > 25 ? slate.options.description.substring(0, 25) + "..." : (slate.options.description || '');
                    underSlate.innerHTML = _tmp.replace(/{name}/g, _n).replace(/{description}/g, _d).replace(/{id}/g, slate.options.id);
                }
                , onSlateBindingComplete: function (slates, pageIndex) {
                    _slates = slates;

                    if (_slates.length === 0) {
                        $s.el("loadSlates").innerHTML = "<h2 class='green'>You have not saved any slates yet!</h2>";
                    }

                    var cx = $s.el("lnkCreateSlate");

                    cx.onmouseover = function (e) {
                        cx.style.backgroundColor = "#fff";
                    };
                    cx.onmouseout = function (e) {
                        cx.style.backgroundColor = "#eee";
                    };

                    cx.onclick = function (e) {
                        _self.removeMsg();
                        options.n.closeMessage();
                        setTimeout(function () {
                            $c.instance.fire("newSlate");
                        }, 500);
                    };

                    $s.each($s.select("a.deleteSlate"), function () {
                        var _a = this;
                        _a.onclick = function () {
                            var _id = _a.getAttribute("rel"), u = _self.getOption("user");
                            if (_id === _self.getOption("slate").options.id) {

                                //get a new active id
                                var _activeSlate = { id: "", json: "" };
                                if (_slates.length > 1) _activeSlate = _.detect(_slates.reverse(), function (s) { return s.id !== _id; });

                                if (_activeSlate.id !== "") {
                                    activate(_activeSlate.id, function () {
                                        if ($s.isFunction(options.onSlateSelected)) {
                                            options.onSlateSelected.apply(this, [_activeSlate.json]);
                                        }
                                        del(_id);
                                    });

                                } else {
                                    //we know this was the last slate on this page...
                                    if (_slates.length === 1 && pageIndex > 1) {
                                        goBackAndDelete(_id);
                                    } else {
                                        del(_id, function () {
                                            //no slates left
                                            if ($s.isFunction(options.onSlateSelected)) {
                                                options.onSlateSelected.apply(this, [_self.getNewSlateJson('', '')]);
                                            }

                                            _self.removeMsg();
                                            options.n.closeMessage();

                                            _self.welcome("You just deleted your last saved slate!");
                                        });
                                    }
                                }
                            } else {
                                if (_slates.length === 0) {
                                    (pageIndex > 1) ? goBackAndDelete(_id) : del(_id);
                                } else {
                                    del(_id);
                                }
                            }
                        };
                    });

                    function goBackAndDelete(_id) {
                        _search.setOption("pageNumber", _search.getOption("pageNumber") - 1);
                        del(_id, function () {
                            _activeSlate = _slates.reverse()[0];
                            activate(_activeSlate.id, function () {
                                if ($s.isFunction(options.onSlateSelected)) {
                                    options.onSlateSelected.apply(this, [_activeSlate.json]);
                                }
                            });
                        });
                    };

                    function del(id, callback) {
                        var _durl = _self.url("del");
                        $s.ajax(_durl, function (respText, resp) {
                            _search.loadSlates(function () {
                                if ($s.isFunction(callback)) callback.apply(this);
                            });
                        }, JSON.stringify({ SlateId: id }), 'DELETE');
                    };

                    function activate(id, callback) {
                        //set active slate
                        $s.ajax(_self.url("active"), function (respText, resp) {
                            setTimeout(function () {
                                callback.apply(this);
                            }, 300);

                        }, JSON.stringify({ slateId: id }), 'POST');
                    };

                    $s.each($s.select("div.openSlate"), function () {
                        var _s = this;
                        _s.onclick = function (e) {
                            var _id = this.getAttribute("rel");
                            $s.each(_slates, function () {
                                if (this.id === _id) {
                                    _self.removeMsg();
                                    options.n.closeMessage();

                                    //set active slate
                                    var _json = this.json;
                                    activate(_id, function (_newSlate) {
                                        if ($s.isFunction(options.onSlateSelected)) {
                                            options.onSlateSelected.apply(this, [_json]);
                                        }
                                    });

                                    return;
                                }
                            });
                        };
                        /*
                        _s.onmouseover = function (e) {
                        _s.style.backgroundColor = "#fff";
                        };
                        _s.onmouseout = function (e) {
                        _s.style.backgroundColor = "#033333";
                        };
                        */
                    });
                }
            });
        });
        return _self;
    }
})(Slatebox, Canvas);(function ($s, $c) {
    $c.fn.properties = function (_options) {
        var _self = this;

        var options = {
            c: null
            , u: null
            , initToggle: null
            , onToggleSwitch: null
        }

        $s.extend(options, _options);

        var url = _self.url("save");

        _self.loadContent(options.u, function (content) {
            options.c.innerHTML = content;
            var init = options.initToggle;
            var _slate = _self.getOption("slate");

            var _ids = _self.wireSwitches(init, function (prop, isOn) {
                _slate.options[prop] = isOn;
                $s.ajax(url, function (respText, resp) {
                    var _msg = '';
                    switch (prop) {
//                        case "showBirdsEye":
//                            _msg = "You have turned OFF the corner bird's eye view";
//                            if (isOn) {
//                                _msg = "You have turned ON the corner bird's eye view";
//                                _slate.birdseye.enable();
//                            } else {
//                                _slate.birdseye.disable();
//                            }
//                            break;
                        case "isPublic":
                            _msg = "You have made this slate PRIVATE.";
                            if (isOn) _msg = "You have made this slate PUBLIC.";
                            break;
                    }
                    _self.showMsg(_msg, "pd_info");
                }, _slate.exportJSON());
            });

            var _getId = "";
            if (_slate.options.isPublic) {
                $s.each(_ids, function () { if (this.name === "isPublic") { _getId = this.id; return; } });
                $s.toggleOnOff(_getId);
            }
//            if (_slate.options.showBirdsEye) {
//                $s.each(_ids, function () { if (this.name === "showBirdsEye") { _getId = this.id; return; } });
//                $s.toggleOnOff(_getId);
//            }

            wire();
        });

        function wire() {

            $s.el("lnkSubmit").onclick = function (e) {
                var _name = $s.el("txtSlateName").value;
                var _descript = $s.el("txtSlateDescription").value;
                if (_name === "") {
                    _self.showMsg("You have to provide a name!", "pd_warn");
                } else {
                    var _slate = _self.getOption("slate");
                    _slate.options.name = _name;
                    _slate.options.description = _descript || "";

                    $s.ajax(url, function (respText, resp) {
                        _self.removeMsg();
                        options.n.closeMessage();
                        _slate.message.show("Slate updated!", 2000);
                    }, _slate.exportJSON());
                }
            };

            var _slate = _self.getOption("slate");
            $s.el("txtSlateName").value = _slate.options.name;
            $s.el("txtSlateDescription").value = _slate.options.description;
        };

        return _self;
    }
})(Slatebox, Canvas);(function ($s, $c) {
    $c.fn.save = function (_options) {
        var _self = this;

        var options = {
            el: {}
            , urls: []
            , showMessage: false
            , callback: null
        }

        $s.extend(options, _options);

        var sv = function () {
            $s.el(options.el).innerHTML = 'Saving... ';
            var _slate = _self.getOption("slate");

            //save and set as active
            $s.ajax(_self.url("save"), function (respText, resp) {
                var _savedSlate = JSON.parse(respText);
                setActive(_savedSlate, function () {
                    if (options.showMessage) _slate.message.show("Slate saved!", 2000);
                    $s.el(options.el).innerHTML = 'Save ';
                    if ($s.isFunction(options.callback)) {
                        options.callback.apply(this, [options.saveCount]);
                    }
                });
            }, _slate.exportJSON(), 'POST');

            function setActive(_savedSlate, callback) {
                if (!_self.getOption("user").Filter) _self.getOption("user").Filter = { CurrentSlateId: '' };
                if (_self.getOption("slate").options.id !== _self.getOption("user").Filter.CurrentSlateId) {
                    _self.getOption("user").Filter.CurrentSlateId = _self.getOption("slate").options.id;

                    $s.ajax(_self.url("active"), function (respText, resp) {
                        callback.apply(this);
                    }, JSON.stringify({ slateId: _savedSlate.options.id }), 'POST');
                } else {
                    callback.apply(this);
                }
            };
        };
        
        sv();

        return _self;
    }
})(Slatebox, Canvas);(function ($s, $c) {
    $c.fn.developer = function (_options) {
        var _self = this;

        var options = {
            c: null
            , u: null
            , initToggle: null
            , onSwitchToggle: null
        }

        $s.extend(options, _options);

        _self.loadContent(options.u, function (content) {
            var u = _self.getOption("user");
            $s.ajax(_self.url('userDevDetails'), function (respText, resp) {
                var det = JSON.parse(respText);
                options.c.innerHTML = content.replace(/{apiKey}/g, det.api).replace(/{secretKey}/g, det.secret);
            });
        });

        return _self;
    }
})(Slatebox, Canvas);;(function($s) {
    var _canvasView = function (_options) {
        var _self = this;

         if (!(_self instanceof _canvasView))
            return new _canvasView();

        var options = {
            userName: ''
            , gravatarUrl: ''
            , id: ''
            , email: ''
            , isEmailVerified: false
            , isProfilePublic: false
            , baseUrl: ''
            , canvasContainer: ''
            , minimumNumberOfCollaboratorsForAutoSave: 0
            , setAsActiveUrl: ''
            , currentInvite: { owningUserName: '', gravatarUrl: '', currentUserIp: '' }
        };

        $s.extend(options, _options);
        if (options.currentInvite.userName === "") options.currentInvite = null;

        if ($s.isIE() < 9) {
            IE({
                onMissing: function() {
                    $s.each($s.select("li.mitem"), function () {
                        this.onclick = null;
                        this.style.color = "#333";
                    });
                    $s.each($s.select("li.mitemg"), function () {
                        this.onclick = null;
                        this.style.color = "#333";
                    });

                    $s.el("slateCanvas").innerHTML = "<div class='ie_compat_warn'>Ouch, you've got an ancient IE browser!<div class='ie_compat_link'><a href='javascript:' id='lnkInstallFrame'>Please install the free Google Chrome Plugin to use $s >></a></div></div>";
                    $s.el("lnkInstallFrame").onclick = function () {
                        $s.select("div.chromeFrameOverlayUnderlay")[0].style.display = "block";
                        $s.select("table.chromeFrameOverlayContent")[0].style.display = "block";
                    }
                }, onInstalled: function() {
                    load();
                }
            });
        } else {
            load();
        }

        function load() {
            loadActive(function (_mainSlate, isLoaded, totalCount) {
               
                var _owningUserName = options.userName, _owningUserProfile = options.gravatarUrl, _loggedOnUserIp = 'host'
                    , _loggedOnUser = options.userName, _loggedOnUserProfile = options.gravatarUrl;

                if (options.currentInvite != null) {
                    _owningUserName = options.currentInvite.userName;
                    _owningUserProfile = options.currentInvite.gravatarUrl;
                    _loggedOnUserIp = options.currentInvite.currentUserIp;
                    if (_loggedOnUser === '') _loggedOnUser = 'Guest_' + $s.guid().substring(0, 4);
                    _mainSlate.init(_loggedOnUser, _loggedOnUserProfile, _loggedOnUserIp);
                } else {
                    _mainSlate.init(_owningUserName, _owningUserProfile, _loggedOnUserIp);
                }

                _mainSlate.options.viewPort.allowDrag = true;
                _mainSlate.options.enabled = true;

                canvas = new Canvas({
                    baseUrl: options.baseUrl
                    , parentContainer: options.canvasContainer
                    , slate: _mainSlate
                    , onSlateUpdated: function (json) {
                        _mainSlate.loadJSON(json);
                        _mainSlate.birdseye && _mainSlate.birdseye.reload(json);
                        autosave();
                    }
                    , user: { id: options.id, name: options.userName, email: options.email, IsEmailVerified: options.isEmailVerified, IsProfilePublic: options.isProfilePublic }
                    , owningUserProfile: _owningUserProfile
                });

                function autosave() {
                    //set up autosaving when more than minimumNumberOfCollaboratorsForAutoSave collaborator(s)
                    var _saveInProgress = false, _saveCount = 0;
                    _mainSlate.options.onSlateChanged = function (subCount) {
                        if (subCount > options.minimumNumberOfCollaboratorsForAutoSave) {
                            _saveCount++;
                            if (!_saveInProgress) {
                                _save(_saveCount);
                            }
                        }
                    };

                    var _save = function (_sc) {
                        _saveInProgress = true;
                        //save and set as active
                        $s.ajax(options.setSlateAsActiveUrl, function (respText, resp) {
                            _saveInProgress = false;
                            if (_sc !== _saveCount)
                                _save(_saveCount);

                        }, _mainSlate.exportJSON(), 'POST');
                    };
                };
                autosave();

                if (options.currentInvite !== null) {
                    $s.el("top").style.visibility = "hidden";
                    $s.el("top").style.height = "120px";
                    _mainSlate.canvas.darken(50);

                    var _updateable = 0, _subs = [], _attempts = 0, _maxAttempts = 5, _userLocked = false;

                    var _update = window.setInterval(function () {
                        if (_updateable === 0) _attempts++;
                        if ((_updateable === 1 || _updateable === 2)) {
                            if (!_userLocked) {
                                switch (_updateable) {
                                    case 1:
                                        vis("visible");
                                        $s.el("collab_welcome").innerHTML = "Hi, welcome to Slatebox!";
                                        _mainSlate.canvas.lighten();
                                        break;
                                    case 2:
                                        var _limit = "Sorry, there are already too many people collaborating on this slate. You can watch, but cannot participate.";
                                        if (options.userName !== "") {
                                            _limit += "<div style='padding-top:10px;font-size:14pt;'>You are already logged-in as " + _loggedOnUser + ". <a href='/RemoveInvite' style='color:#fff;'>" +
                                                    "Click here to go to your own slates</a></div>";
                                        } else {
                                            _limit += "<div style='padding-top:10px;font-size:14pt;'>Why not <a href='/Register' style='color:#fff;'>sign up</a> or <a href='/Login' style='color:#fff;'>log in</a> and " +
                                                    "create your own slate?<div style='margin-top:10px;font-size:10pt;'></div>";
                                        }
                                        $s.el("collab_welcome").innerHTML = _limit;
                                        vis("hidden");
                                        _mainSlate.websync.hide();
                                        _mainSlate.canvas.darken(50);
                                        break;
                                }
                                _userLocked = true;
                            }
                        } else if (_attempts > _maxAttempts) {
                            _mainSlate.canvas.darken(50);

                            vis("hidden");

                            if (options.userName !== "") {
                                $s.el("collab_welcome").innerHTML = "Sorry, " + _owningUserName + " is no longer online! " +
                                        "<div style='margin-top:10px;font-size:14pt;'>You are already logged-in as " + _loggedOnUser + ".<br/><a href='/RemoveInvite' style='color:#fff;'>" +
                                            "Go to your own slates ></a></div>" +
                                        "<div style='margin-top:10px;font-size:10pt;color:#fff;'>" +
                                        "(This slate will automatically activate if the host comes back online.)</div>";
                            } else {
                                $s.el("collab_welcome").innerHTML = "Sorry, " + _owningUserName + " is no longer online! <br/> " +
                                        "Why not <a href='/Register' style='color:#fff;'>sign up</a> or <a href='/Login' style='color:#fff;'>log in</a> and " +
                                        "create your own slate?<div style='margin-top:10px;font-size:10pt;'>" +
                                        "(This slate will automatically activate if the host comes back online.)</div>";
                            }
                        }
                    }, 1000);

                    var vis = function (vtype) {
                        $s.each($s.select("div.pending_websync"), function () {
                            this.style.visibility = vtype;
                        });
                    };

                    _mainSlate.websync.attach(function (subs) {
                        _subs = subs;
                        _updateable = 0;
                        if (subs.length === 2) {
                            _updateable = 1;
                            _userLocked = false;
                        } else if (subs.length > 2) {
                            _updateable = 2;
                        }
                        if ($s.el("collab_guest"))
                            $s.el("collab_guest").innerHTML = _loggedOnUser;
                    });

                    new Notify().message({
                        hgt: 132
                            , duration: 100
                            , className: 'embedBar'
                            , delayClose: 0
                            , spinner: null
                            , hideClose: true
                            , onOpen: function (container, _ntfy) {

                                container.innerHTML =
                                    "<div style='width:900px;'>" +
                                        "<div style='float:left;'>" +
                                            "<div class='collab_big' id='collab_welcome'>" +
                                                "Hi, welcome to Slatebox! Trying to connect you with " + _owningUserName + "..." +
                                            "</div>" +
                                            "<div class='collab_small pending_websync' style='visibility:hidden'>" +
                                                "<div style='float:left;padding-top:20px;padding-right:10px;'>You are now on a live slate with " + _owningUserName + "</div>" +
                                                "<div style='float:left;padding:5px;'><img id='collab_host_image' src='" + _owningUserProfile + "'/></div>" +
                                            "</div>" +
                                        "</div>" +
                                        "<div style='float:left;padding-left:30px;width:430px;height:100px;font-size:11pt;visibility:hidden' id='pending_details' class='pending_websync'>" +
                                        "</div>" +
                                    "</div>";

                                if (options.userName === "") {
                                    $s.el("pending_details").innerHTML = "You can collaborate now, but it'd be nice if you would let " + _owningUserName + " know who you are! " +
                                                    "Currently, you're listed as <span id='collab_guest'></span>." +
                                                    "<div style='padding-top:15px;'>Name: <input type='text' id='txtGuestName' style='width:300px;' maxlength='15'/>" +
                                                    "&nbsp;<input type='button' id='btnGuestName' value='Go >'/></div>";

                                    $s.el("btnGuestName").onclick = function (e) {
                                        var _initName = $s.el("txtGuestName").value;
                                        if (_initName !== "") {
                                            var _guestName = $s.el("collab_guest").innerHTML;
                                            _mainSlate.websync.updateName(_guestName, _initName);
                                            $s.el("pending_details").style.marginTop = "-8px";
                                            $s.el("pending_details").innerHTML = "<b>Excellent. Nice to meet you, " + _initName + "!</b> Want your own $s account? <b>(Don't worry, you won't go anywhere.)</b>" +
                                            "<div style='clear:both;margin-top:10px;margin-left:20px;'><div style='float:left;width:80px;'>Username: </div><div style='float:left;'><input type='text' id='txtGuestUsername' style='width:150px;' maxlength='15' value='" + _initName + "'/>&nbsp;<span id='userNameTaken'></span></div></div>" +
                                            "<div style='clear:both;margin-left:20px;'><div style='float:left;width:80px;'>Email: </div><div style='float:left;'><input type='text' id='txtGuestEmail' style='width:150px;' maxlength='125'/></div></div>" +
                                            "<div style='clear:both;margin-left:20px;'><div style='float:left;width:80px;'>Password:</div><div style='float:left;'><input type='password' id='txtGuestPassword' style='width:150px;' maxlength='20'/>&nbsp;<input type='button' id='btnCreateUser' value='Go >'/></div></div>";

                                            //check username
                                            $s.el("txtGuestUsername").onchange = function (e) {
                                                $s.el("txtGuestUsername").style.backgroundColor = "#fff";
                                                if ($s.el("txtGuestUsername").value !== "") {
                                                    ct();
                                                } else {
                                                    $s.el("txtGuestUsername").style.backgroundColor = "#ffff99";
                                                }
                                            };

                                            //create user...
                                            $s.el("btnCreateUser").onclick = function () {
                                                var _msgs = valid();
                                                if (_msgs.length > 0) {
                                                    alert("Oops. Something is missing: \n\n-" + _msgs.join(' \n- '));
                                                } else {
                                                    var _user = $s.el("txtGuestUsername").value;
                                                    var _email = $s.el("txtGuestEmail").value;
                                                    var _pwd = $s.el("txtGuestPassword").value;
                                                    $s.ajax("/CreateUser", function (respText, resp) {
                                                        var u = JSON.parse(respText);
                                                        if (u.UserName !== _user) {
                                                            alert("Oops. There was a problem: \n\n" + u.UserName);
                                                        } else {
                                                            //update user gravatar
                                                            $s.ajax("/Avatar?email=" + _email, function (respText, resp) {
                                                                _loggedOnUser = u.UserName;
                                                                _loggedOnUserProfile = JSON.parse(respText).src;
                                                                _mainSlate.websync.updateName(_initName, _loggedOnUser, _loggedOnUserProfile);
                                                                $s.el("pending_details").innerHTML = "You are listed below as " + _loggedOnUser + "!<div style='padding-top:10px;font-size:14pt;'>Done? <a href='/RemoveInvite' style='color:#fff;'>Go to your own slates.</a>";
                                                            });
                                                        }
                                                    }, JSON.stringify({ Email: _email, Password: _pwd, UserName: _user }), "PUT");
                                                }
                                            };

                                            var _isTaken = false;
                                            var ct = function () {
                                                var _name = $s.el("txtGuestUsername").value;
                                                $s.ajax("/CheckUsername/" + _name, function (respText, resp) {
                                                    _isTaken = (respText === 'true');
                                                    if (_isTaken === true) {
                                                        $s.el("userNameTaken").innerHTML = " (Sorry, Taken!)";
                                                        $s.el("userNameTaken").style.color = '#FFFF00';
                                                    } else {
                                                        $s.el("userNameTaken").innerHTML = " (Available!)";
                                                        $s.el("userNameTaken").style.color = '#2DD700';
                                                    }
                                                });
                                            };

                                            var valid = function () {
                                                var msgs = [];
                                                $s.el("txtGuestEmail").style.backgroundColor = "#fff";
                                                $s.el("txtGuestEmail").style.backgroundColor = "#fff";
                                                var _email = $s.el("txtGuestEmail").value;
                                                var _pwd = $s.el("txtGuestPassword").value;
                                                if (_isTaken) msgs.push("This username is already taken!");
                                                if (_email === "") { msgs.push("You must provide a valid email"); $s.el("txtGuestEmail").style.backgroundColor = "#ffff99"; }
                                                if (_pwd === "" || _pwd.length < 6) { msgs.push("You need a password at least 6 characters long"); $s.el("txtGuestPassword").style.backgroundColor = "#ffff99"; }
                                                return msgs;
                                            };

                                            //check username right away
                                            ct();

                                        } else {
                                            $s.el("txtGuestName").style.backgroundColor = "#ffff99";
                                        }
                                    };
                                } else {
                                    $s.el("pending_details").innerHTML = "You are listed below as " + _loggedOnUser + "!<div style='padding-top:10px;font-size:14pt;'>Done? <a href='/RemoveInvite' style='color:#fff;'>Go to your own slates.</a>";
                                }
                            }
                    });
                } else {
                    if (!isLoaded) {
                        if (totalCount > 0) {
                            canvas.fire("openSlate");
                        } else {
                            canvas.welcome();
                        }
                    }
                }
            });
        };

        function loadActive(callback) {
            //check if they have an active slate...
            var sb = new $s();
            var _mainSlate = sb.slate({ container: 'slateCanvas', viewPort: { width: 50000, height: 50000, allowDrag: true, left: 5000, top: 5000} }).canvas.init({ imageFolder: options.imageFolder });

            $s.ajax("/GetActiveSlate", function (respText, resp) {
                var _active = JSON.parse(respText);
                if (_active.slate !== null && _active.slate.options.name !== "EMPTY") {
                    _mainSlate.loadJSON(JSON.stringify(_active.slate));
                    callback.apply(this, [_mainSlate, true]);
                } else {
                    var _nodes = [
                           sb.node({ name: 'MASTER_NODE', text: 'Start Here', xPos: 5500, yPos: 5300, height: 100, width: 150, vectorPath: 'ellipse', backgroundColor: '#c3ff68', lineColor: "blue", lineWidth: 3 })
                        ];
                    _mainSlate.nodes.addRange(_nodes);
                    callback.apply(this, [_mainSlate, false, _active.totalSlates]);
                }
            });
        }
    };
    window.CanvasView = _canvasView;
})(Slatebox);;(function ($s) {
    var _ieCheck = function(_options) {
        var _self = this;
        if (!(_self instanceof _ieCheck))
            return new _ieCheck();

        var options = {
            onMissing: null
            ,onLoaded: null
        }

        $s.extend(options, _options);

        var _ce = CFInstall.check({
            mode: "overlay"
            , user: true
            , node: "prompt"
            , onmissing: function () {
                if ($s.isFunction(options.onMissing)) options.onMissing.apply(this);
            }
            , oninstalled: function () {
                if ($s.isFunction(options.onInstalled)) options.onInstalled.apply(this);
            }
        });
    }
    window.IE = _ieCheck;
})(Slatebox);
