/* native type extensions */
Date.CSharpMin = new Date(-62135596800000);
Date.CSharpMax = new Date(253402300799999);
Date.CSharpMaxThreshold = new Date(253402300799999 - 1000*60*60*24*365*2); //Date.CSharpMax - 2 years

Object.extend(String.prototype, {
    pluralize: function() {
        var l = this.length;
        return this.substr(l-1) === 'y' ? this.substr(0,l-1) + 'ies' : this + 's';
    }
});

if (window.Type) {
    Type.registerNamespace('WebTango');
} else {
    WebTango = {};
}

WebTango.UserRoles = Class.create();
Object.extend(WebTango.UserRoles, {
    ClientEditor : 0,
    ClientAdmin : 1,
    CustomerAdmin : 2,
    SystemAdmin : 3
});

if (window.WebTangoConstantsLoader) { WebTangoConstantsLoader(); }

/* misc functions */
WebTango.initTinyMce = function() {
    tinyMCE.init({
        mode : "none",
        theme : "webtango_advanced",
        //editor_selector : editorID,
        cleanup: true,
        relative_urls: false,
        convert_urls: false,
        plugins : "save,directionality,paste",
        theme_webtango_advanced_toolbar_location : "top",
        theme_webtango_advanced_toolbar_align : "_LeftImage",
        theme_webtango_advanced_resize_horizontal : false,
        theme_webtango_advanced_resizing : true,
        paste_create_paragraphs : false,
	    paste_create_linebreaks : false,
	    paste_use_dialog : true,
	    paste_auto_cleanup_on_paste : true,
	    paste_convert_middot_lists : true,
	    paste_unindented_list_class : "",
	    paste_convert_headers_to_strong : false,
        theme_webtango_advanced_buttons3_add : "fullscreen",
        theme_webtango_advanced_path_location : "bottom",
        extended_valid_elements : "a[name|href|target|title|onclick]",
        auto_reset_designmode : true,
        entity_encoding : "raw",
        //height: "400",
        theme_webtango_advanced_resizing_use_cookie : false
    });
};

//loads a javascript at runtime
WebTango.loadScript = function(script_filename) {
    var html_doc = document.getElementsByTagName('head').item(0);
    var js = document.createElement('script');
    js.setAttribute('language', 'javascript');
    js.setAttribute('type', 'text/javascript');
    js.setAttribute('src', script_filename);
    html_doc.appendChild(js);
};

WebTango.logout = function() {
    WebTango.Services.MasterService.Logout(""+window.location.pathname, function() {
        window.location = "/";
    }, WebTango.Feedback.getErrorCallback("Could not log out!"));
};

WebTango.makeWebDeskUrl = function(objectType, OID) {
    if (objectType.startsWith("WebTango.")) {
        objectType = objectType.replace("WebTango.WebDesk.", "~wt.");
    }
    if (objectType.startsWith("PowerNodes.")) {
        objectType = objectType.replace("PowerNodes.", "~$.");
    }
    var url = WebTango.webDeskPrefix + "/" + objectType;
    if (OID) { url += ("/" + OID); }
    return url;
};

//a wrapper function for the script manager notification crap
//just to have a central place to remove it later
WebTango.notifyScriptManager = function() {
    if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
}

WebTango._detectedFlashVersion = null;

WebTango.hasRequiredFlashVersion = function() {
    if (WebTango._detectedFlashVersion === null) {
        WebTango._detectedFlashVersion = deconcept.SWFObjectUtil.getPlayerVersion();
    }
    return (WebTango._detectedFlashVersion['major'] == 9);
}

if (!WebTango.Guid) { WebTango.Guid = {}; }

WebTango.Guid.isMatch = function(guidString) {
    return /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/.test(guidString);
};

WebTango.Guid.isProvisional = function(guid) {
    return guid != WebTango.Guid.Empty && guid.startsWith("00000000-0000");
},
WebTango.Guid.makeFromInt = function(theInt) {
    var str = "" + theInt;
    return WebTango.Guid.Empty.substr(0,WebTango.Guid.Empty.length - str.length) + str;
};


WebTango.AccountSwitcher = Class.create({    
    getAccountLinks: function(src) {
        $(src).hide();
        WebTango.Services.MasterService.GetAccountLinks(""+window.location.pathname, this._onAccountLinksLoaded.bind(this), this._onAccountLinksLoadError.bind(this));
        $('switchAccountSpinner').show();
    },
    _onAccountLinksLoaded: function(result) {
        $('switchAccountSpinner').hide();
        
        Event.observe(window, "click", this._closeSwitcher.bind(this));

        var customers = this._makeFlatList(result,0);
        
        $('switchAccountDropdown').appendChild(
            Builder.node("ul", { className : "accounts" }, customers)
        );
    },
    _makeFlatList: function(list, depth) {
        if (list.length === 0) { return []; }
        
        var nodes = [];
        for (var i=0,l=list.length;i<l;++i) {
            var node = list[i];
            nodes.push(Builder.node("li", {className:WebTango.AccountSwitcher.accountClassNames[depth]}, Builder.node("a", { href : node.Link }, node.Text)));
            nodes.push(this._makeFlatList(node.Children, depth+1));
        }
        return nodes;
    },
    _closeSwitcher: function() {
        $('switchAccountDropdown').immediateDescendants().each(function(elm) { $(elm).remove(); });
        $('switchAccountBegin').show();
        Event.stopObserving(window, "click", this._closeSwitcher.bind(this));
    },
    _onAccountLinksLoadError: function(err) {
        WebTango.Feedback.negative("Error getting accounts: " + err.get_message());
        $('switchAccountSpinner').hide();
    }
});
WebTango.AccountSwitcher._instance = new WebTango.AccountSwitcher();
WebTango.AccountSwitcher.show = function(src) { WebTango.AccountSwitcher._instance.getAccountLinks(src); };


WebTango.Buttons = Class.create({});
Object.extend(WebTango.Buttons, {
    _KILLONCLICK : "this.blur();return false;",
    
    //this function makes the full-blown buttons with presently green image
    //they can be aligned left or right, or can be unaligned
    //the color of the button is defined based on whether the button is 'positive' or 'negative'
    big: function(text, align, isPositive) {
        if (align === undefined) { align = ""; }
        if (isPositive === undefined) { isPositive = true; }
        var cssClass = "button " + align + (isPositive ? "" : " negativebtn");
        
        return Builder.node("a", {className: cssClass, href: "#", onclick: WebTango.Buttons._KILLONCLICK}, Builder.node("span", text));
    },
    button: function(text, isPositive) {
        return Builder.node("input", {type: "button", value: text});
    },
    //this function makes a simple A-tag button.
    //the isPositive parameter can be true (cssclass: "positive")
    //false (cssclass: "negative"), or undefined (no cssclass)
    link: function(text, isPositive) {
        var cssClass = "";
        if (isPositive !== undefined) {
            cssClass = isPositive ? "positive":"negative";
        }
        return Builder.node("a", {className: cssClass, href:"#", onclick: WebTango.Buttons._KILLONCLICK}, text);
    },
    createContentLink : function(text, typeName) {
        var createContentButton = $(Builder.node("a", {className: "positive", href:"#", onclick: WebTango.Buttons._KILLONCLICK}, text));
        Event.observe(createContentButton, "click", function() {
            WebTango.CreateContentModal.show({defaultType: typeName});
        });
        return createContentButton;
    },
    createContentButton: function(options) {
        var defaultOptions = {
            align: "",
            text: "CREATE",
            baseType: null,
            defaultType: null
        };
        options = Object.extend(defaultOptions,options || {});
        var createContentButton = $(Builder.node("a", {className: "button " + options.align, href:"#", onclick: WebTango.Buttons._KILLONCLICK}, Builder.node("span", options.text)));
        Event.observe(createContentButton, "click", function() {
            WebTango.CreateContentModal.show({defaultType: options.defaultType, baseType: options.baseType});
        });
        return createContentButton;
    },
    //makes a gray button for the home-made dropdown menus at the top of the doc editor
    //(e.g. language button)
    menu: function(text) {
        return Builder.node("a", {/*className: "dropdownbutton",*/ href:"#", onclick: WebTango.Buttons._KILLONCLICK},
            Builder.node("span", text)
        );
    },
    search: function() {
        return Builder.node("a", {className: "searchbutton", href: "#", onclick: WebTango.Buttons._KILLONCLICK}, Builder.node("span", "SEARCH"));
    },
    //update the text of a button generated with WebTango.Buttons.menu
    setMenuText: function(button, text) {
        button.immediateDescendants()[0].innerHTML = text;
    }
});

WebTango.ChangesTracker = Class.create({});
Object.extend(WebTango.ChangesTracker, {
    addDirtyObject: function (obj) {
        WebTango.ChangesTracker._dirtyObjects.set(obj, true);
    },
    check: function(eventArgs) {
        var elm = eventArgs.element();
        while (elm && !elm.href) { elm = elm.up(); }
        if (WebTango.ChangesTracker._dirtyObjects.size() > 0) {
            var popup = new WebTango.InlinePopup({
                warningText: "There are unsaved changes, do you wish to discard them?",
                confirmText: "Discard",
                cancelText: "stay on this page",
                element: elm.up(),
                confirmHref : elm.href
            });
            Event.stop(eventArgs); //stop the default event from firing
        } 
    },
    registerListener: function(listenElm, eventName) {
        listenElm = $(listenElm);
        listenElm.observe(eventName || "click", WebTango.ChangesTracker.check.bindAsEventListener(WebTango.ChangesTracker, listenElm));
    },
    removeDirtyObject: function (obj) {
        WebTango.ChangesTracker._dirtyObjects.unset(obj);
    },
    _dirtyObjects: $H()
});

Event.observe(window, "load", function() {
    var listenLink = function(link) {
        WebTango.ChangesTracker.registerListener(link);
    };
    var menu = $("menu");
    if (menu) { menu.select("a").each(listenLink); }
    var subMenu = $("submenu");
    if (subMenu) { subMenu.select("a").each(listenLink); }
});

//cookie helper functions - taken from http://techpatterns.com/downloads/javascript_cookies.php
WebTango.Cookies = Class.create({});
Object.extend(WebTango.Cookies, {
    
    // this deletes the cookie when called
    deleteCookie: function( name, path, domain ) {
        if (WebTango.Cookies.getCookie(name)) {
             document.cookie = name + "=" +
            ((path) ? ";path=" + path : "") +
            ((domain) ? ";domain=" + domain : "") +
            ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
        }
    },

    // this function gets the cookie, if it exists
    getCookie: function( name ) {
	    var start = document.cookie.indexOf( name + "=" );
        var len = start + name.length + 1;
        if (( !start ) && (name != document.cookie.substring( 0, name.length ))) {
            return null;
        }
        if (start == -1) { return null; }
        var end = document.cookie.indexOf( ";", len );
        if ( end == -1 ) { end = document.cookie.length; }
        return unescape( document.cookie.substring( len, end ) );
    },

    setCookie: function( name, value, expires, path, domain, secure ) 
    {
        // set time, it's in milliseconds
        var today = new Date();
        today.setTime( today.getTime() );

        /*
        if the expires variable is set, make the correct 
        expires time, the current script below will set 
        it for x number of days, to make it for hours, 
        delete * 24, for minutes, delete * 60 * 24
        */
        if ( expires ) {
            expires = expires * 1000 * 60 * 60 * 24;
        }
        var expires_date = new Date( today.getTime() + (expires) );

        document.cookie = name + "=" +escape( value ) +
        ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 
        ( ( path ) ? ";path=" + path : "" ) + 
        ( ( domain ) ? ";domain=" + domain : "" ) +
        ( ( secure ) ? ";secure" : "" );
    }
});

WebTango.CreateContentModal = Class.create({
        
    initialize : function() {
        this.idPrefix = "wt_create_content_";
    },
    populateTypeList : function(params, typeList) {
        this.typeOptions = [Builder.node("option", {value: ""}, "- Select -")];
        
        typeList = $H(typeList);
        typeList.each(function (pair) {
            this.typeOptions.push(Builder.node("option", {value: pair.key}, pair.value));
        }.bind(this));
        
        var dl, createButton, cancelButton, typeSelectBox, nameTextBox, navigateToCheckBox;
        var schemaDT, schemaDD, parentDropDown, nameDT, nameDD, destDT, destDD, createSpinner;
        
        var wrapper = Builder.node("div", {className:"formfield"}, [
            dl = Builder.node("dl", [
                Builder.node("dt", "Type"),
                Builder.node("dd", [
                    typeSelectBox = Builder.node("select", {className: "select"}, this.typeOptions)
                ]),
                schemaDT = Builder.node("dt", {style: "display: none;"}, "Select schema"),
                schemaDD = Builder.node("dd", {style: "display: none;"}, []),
                parentDT = Builder.node("dt", {style: "display: none;"}, "Select destination"),
                parentDD = Builder.node("dd", {style: "display: none;"}, []),
                nameDT = Builder.node("dt", {style: "display: none;"}, "Name"),
                nameDD = Builder.node("dd", {style: "display: none;"}, [
                    nameTextBox = Builder.node("input", {type: "text", className: "text tinyfixed"})
                ]),
                destDT = Builder.node("dt", {style: "display: none;"}, "Navigate to content after create"),
                destDD = Builder.node("dd", {style: "display: none;"}, [
                    navigateToCheckbox = Builder.node("input", {type: "checkbox", className: "checkbox"})
                ]),
            ]),
            Builder.node("div", {className: "clearboth"}, ""),
            Builder.node("div", {className: "bottompanel"}, [
                createButton = WebTango.Buttons.big("CREATE","left",true),
                createSpinner = Builder.node("span", {className: "left", style: "display: none"}, [
                    Builder.node("img", {src: "/images/spinner.gif"}),
                    "Creating..."
                ]),
                cancelButton = WebTango.Buttons.link("Cancel",false)
            ])
        ]);
        
        dl.id = this.idPrefix + "dl";
        wrapper.id = this.idPrefix + "wrapper";
        createButton.id = this.idPrefix + "create";
        cancelButton.id = this.idPrefix + "cancel";
        typeSelectBox.id = this.idPrefix + "typeSel";
        nameTextBox.id = this.idPrefix + "name";
        navigateToCheckbox.id = this.idPrefix + "navigateTo";
        schemaDT.id = this.idPrefix + "schemaDT";
        schemaDD.id = this.idPrefix + "schemaDD";
        parentDT.id = this.idPrefix + "parentDT";
        parentDD.id = this.idPrefix + "parentDD";
        nameDT.id = this.idPrefix + "nameDT";
        nameDD.id = this.idPrefix + "nameDD";
        destDT.id = this.idPrefix + "destDT";
        destDD.id = this.idPrefix + "destDD";
        createSpinner.id = this.idPrefix + "spinner";
        
        navigateToCheckbox.checked = true;
        
        Modalbox.show(wrapper, {width:520, title:"Create new content", 
            resizeDuration: 0.1,slideDownDuration:0.1,slideUpDuration:0.1, overLayDuration:0.1,
            afterLoad: function () {
                this.dl = $(this.idPrefix + "dl");
                this.wrapper = $(this.idPrefix + "wrapper");
                this.nameTextBox = $(this.idPrefix + "name");
                this.createButton = $(this.idPrefix + "create");
                this.cancelButton = $(this.idPrefix + "cancel");
                this.typeSelectBox = $(this.idPrefix + "typeSel");
                this.navigateToCheckbox = $(this.idPrefix + "navigateTo");
                this.schemaDT = $(this.idPrefix + "schemaDT");
                this.schemaDD = $(this.idPrefix + "schemaDD");
                this.parentDT = $(this.idPrefix + "parentDT");
                this.parentDD = $(this.idPrefix + "parentDD");
                this.nameDT = $(this.idPrefix + "nameDT");
                this.nameDD = $(this.idPrefix + "nameDD");
                this.destDT = $(this.idPrefix + "destDT");
                this.destDD = $(this.idPrefix + "destDD");
                this.createSpinner = $(this.idPrefix + "spinner");
                
                if (params.defaultType) {
                    WebTango.DomUtils.setDropDownValue(this.typeSelectBox, params.defaultType);
                    this.onTypeChanged();
                }
                
                Event.observe(this.createButton, "click", this.createContent.bind(this));
                WebTango.Events.addEnterHandler(this.nameTextBox, this.createContent.bind(this));
                Event.observe($(this.idPrefix + "cancel"), "click", function() {
                    Modalbox.hide();
                    $F(typeSelectBox).selectedIndex = 0;
                    //$(this.nameTextBox).value = "";
                }.bind(this));
                Event.observe($(this.idPrefix + "typeSel"), "change", this.onTypeChanged.bind(this));
                
            }.bind(this)
        })
    },
    onTypeChanged: function() {
        var selectedType = $F(this.idPrefix + "typeSel");
        if (selectedType != "") {                
            var doResizeNow = false; //if true, resize now, otherwise, the AJAX call will do it when complete
            switch (selectedType) {
                case "PowerNodes.Cms.Document" :
                case "PowerNodes.Cty.BlogDocument" :
                case "PowerNodes.Cal.EventDocument" :
                case "PowerNodes.Shp.Product" : {
                    WebTango.Services.Cms.CreateContent.GetSchemaAndParentList(WebTango.webDeskPrefix, selectedType, this.showSchemaAndParentList.bind(this), WebTango.Feedback.getErrorCallback("Error getting type list"));
                    break;
                }
                default : {
                    this.schemaDD.hide();
                    this.schemaDT.hide();                             
                    this.parentDT.hide();
                    this.parentDD.hide();
                    doResizeNow = true;
                }
            }
            
            this.nameDT.show();
            this.nameDD.show();
            this.destDT.show();
            this.destDD.show();
            //this.navigateToCheckbox.checked = true;
            this.nameTextBox.activate();
            if (doResizeNow) { Modalbox.resizeToContent(); }
        }
    },
    createContent : function() {
        if ($F(this.typeSelectBox) == "") {
            $(this.typeSelectBox).activate(); 
            WebTango.Feedback.negative( "A Content type must be selected");
            return;
        }
        
        if ($F(this.nameTextBox) == "") {
            $(this.nameTextBox).activate();
            WebTango.Feedback.negative( "Name cannot be empty");
            return;
        }
        if (this.typeSelectBox.value == "PowerNodes.Cms.Document" || this.typeSelectBox.value == "PowerNodes.Cty.BlogDocument" || this.typeSelectBox.value == "PowerNodes.Cal.EventDocument" || this.typeSelectBox.value == "PowerNodes.Shp.Product") {
            if (this.schemaDropDown == null || $F(this.schemaDropDown) == "") {
                WebTango.Feedback.negative( "A schema must be created prior to creating documents");
                return;
            }       
        }
        
        var newContent = { __type : 'WebTango.Json.Cms.WebContent' };
        newContent.ObjectType = this.typeSelectBox.value;
        if (this.schemaDropDown != null)
            newContent.SchemaOID = this.schemaDropDown.value;
        if (this.parentDropDown != null)
            newContent.ParentOID = this.parentDropDown.value;
        if (newContent.SchemaOID == "")
            newContent.SchemaOID = WebTango.Guid.Empty;
        if (newContent.ParentOID == "")
            newContent.ParentOID = WebTango.Guid.Empty;
        newContent.DisplayName = this.nameTextBox.value;
        
        this.createButton.hide();
        this.cancelButton.hide();
        this.createSpinner.show();
        
        WebTango.Services.Cms.CreateContent.CreateNewContent(WebTango.powerNodesServiceUrl, WebTango.webDeskPrefix, newContent, this.onContentCreated.bind(this), WebTango.Feedback.getErrorCallback("Error creating content"));
    },
    onContentCreated : function(result) {
        this.createButton.show();
        this.cancelButton.show();
        this.createSpinner.hide();
            
        if (result[0] == "false") {
            WebTango.Feedback.negative(result[1]);
            return;
        }
        if ($(this.navigateToCheckbox).checked) {
            document.location.href = result[1];
        } else {
            WebTango.Feedback.positive("Content successfully created");
            //this.typeSelectBox.selectedIndex = 0;
            $(this.nameTextBox).value = "";
            //Modalbox.hide();
        }
    },
    showSchemaAndParentList : function(list) {
       var selectedType = this.typeSelectBox.value;
       if (selectedType == "PowerNodes.Cty.BlogDocument" || selectedType == "PowerNodes.Cal.EventDocument") {
            
            this.parentOptions = [Builder.node("option", {value: ""}, "- Select -")];
            parentList = $H(list[1]);
            if (parentList.size() > 0) {
                parentList.each(function (pair) {
                    this.parentOptions.push(Builder.node("option", {value: pair.key}, pair.value));
                }.bind(this));
                
                if (this.parentDropDown != null) {
                    Element.remove(this.parentDropDown);
                }
                
                this.parentDropDown = $(Builder.node("select", {className: "select"}, this.parentOptions));
                this.parentDD.appendChild(this.parentDropDown);
                this.parentDropDown.selectedIndex = 0;
                    
                if (parentList.size() > 1) {
                    this.parentDT.show();
                    this.parentDD.show();
                    this.parentDropDown.show();
                }
                else {
                    this.parentDT.hide();
                    this.parentDD.hide();
                    this.parentDropDown.selectedIndex = 1;
                }
            }
            else {
                this.parentDT.hide();
                this.parentDD.hide();
            }
        }
        else {
            this.parentDT.hide();
            this.parentDD.hide();
        }
        
        this.schemaOptions = [Builder.node("option", {value: ""}, "- Select -")];
        schemaList = $H(list[0]);
        if (schemaList.size() > 0) {
            schemaList.each(function (pair) {
                this.schemaOptions.push(Builder.node("option", {value: pair.key}, pair.value));
            }.bind(this));
            
            if (this.schemaDropDown != null) {
                Element.remove(this.schemaDropDown);
            }
            
            this.schemaDropDown = $(Builder.node("select", {className: "select"}, this.schemaOptions));
            this.schemaDD.appendChild(this.schemaDropDown);
            this.schemaDropDown.selectedIndex = 0;
            
            if (schemaList.size() > 1) {
                this.schemaDT.show();
                this.schemaDD.show();
                this.schemaDropDown.show();
            }
            else {
                this.schemaDT.hide();
                this.schemaDD.hide();
                this.schemaDropDown.selectedIndex = 1;
            }
        }
        else {
            this.schemaDT.hide();
            this.schemaDD.hide();
        }
        Modalbox.resizeToContent();
    },
    show : function(params) {
        if (!params) params = {};
        //Get list of content that can be created
        WebTango.Services.Cms.CreateContent.GetTypeList(WebTango.powerNodesServiceUrl, WebTango.webDeskPrefix, params.baseType || null, this.populateTypeList.bind(this,params), WebTango.Feedback.getErrorCallback("Error getting type list"));
    },
    contentCreated : function(webDeskUrl) {
        document.location.href = webDeskUrl;
    }
});

WebTango.CreateContentModal._instance = new WebTango.CreateContentModal();
WebTango.CreateContentModal.show = function() {
    WebTango.CreateContentModal._instance.show();
};


WebTango.DomUtils = Class.create({});
Object.extend(WebTango.DomUtils, {
    //clear the text selected with the mouse
    clearSelection: function() {
        if(document.selection && document.selection.empty){
            //IE
            document.selection.empty();
        }
        if (window.getSelection) {
            //Others (but not relevant to FF)
            var sel = window.getSelection();
            if (sel && sel.rangeCount > 0 && sel.getRangeAt) {
                var rng = sel.getRangeAt(0);
                if (rng) {
                   rng.collapse(true);
                }
            }
        }
    },
    //returns n if node is an nth child
    getChildIndex: function(node) {
        node = $(node);
        var idx = -1;
        while (node) { 
            node = node.previous(); 
            ++idx; 
        }
        return idx;
    },
    getDropDownSelectedText: function(dropdown) {
        if (dropdown.selectedIndex == -1) { return null; }
        return dropdown.options[dropdown.selectedIndex].innerHTML;
    },
    makeLabelAndExplanation: function(label, explanation) {
        return Builder.node("span", { className:"label" }, [
            label,
            Builder.node("span", {className:"explanation"}, explanation)
        ]);
    },
    //replaces oldNode with newNode in-situ in the DOM, returning the new node
    replaceNode:function (newNode, oldNode) {
        var parent = $(oldNode).up();
        parent.replaceChild(newNode, oldNode);
        return newNode;
    },
    setDropDownValue: function(dropdown, newValue) {
        var opts = dropdown.options;
        var optCount = opts.length;
        var found = false;
        for (var i=0;i<optCount;++i) {
            var opt = opts[i];
            if (opt.value == newValue) {
                dropdown.selectedIndex = i;
                found = true;
                break;
            }
        }
        if (!found) { dropdown.selectedIndex = -1; }  
    },
    setDropDownValues: function(dropdown, newValues) {
        dropdown.selectedIndex = -1; //deselect all;
        var opts = dropdown.options;
        var optCount = opts.length;
        var newValCount = newValues.length;
        for (var i=0;i<newValCount;++i) {
            var newValue = newValues[i];
            for (var j=0;j<optCount;++j) {
                var opt = opts[j]; 
                if (opt.value === newValue) {
                    opt.selected = true;
                    break;
                }
            }
        }
    },
    //toggle visibility of dom element 'elm', persisting the setting
    //in cookie 'cookieName'
    toggleWithCookie: function(elm, cookieName) {
        elm = $(elm);
        if (elm.visible()) {
            elm.hide();
            WebTango.Cookies.setCookie(cookieName, 'true', 14, '/', '', false);
        } else {    
            elm.show();
            WebTango.Cookies.deleteCookie(cookieName, '/', '');
        }
    }
});

WebTango.Effects = Class.create({});
Object.extend(WebTango.Effects, {
    //call Effect.Appear on all elements of a class className, except the one with ID exceptId
    appearAllByClassName: function(className, exceptId) {
        var elems = document.getElementsByClassName(className);
        for (var i=0;i<elems.length;i++) {
            if (exceptId && elems[i].id == exceptId) { continue; }
            new Effect.Appear(elems[i]);
        }
    },
    //call Effect.Fade on all elements of a class className, except the one with ID exceptId
    fadeAllByClassName: function(className, exceptId) {
        var elems = document.getElementsByClassName(className);
        for (var i=0;i<elems.length;i++) {
            if (exceptId && elems[i].id == exceptId) { continue; }
            new Effect.Fade(elems[i]);
        }
    },
    fadeAndAppear: function(myId, appearOpts) {
        WebTango.Effects.fadeAllByClassName('uniquepanel', myId);
        new Effect.Appear(myId, appearOpts || {});
        //Navigate to the myId anchor
        //Some users claim that location.hash should be used instead, not sure of the difference though?
        location.href = '#' + myId + "_anchor";
    },
    menuToggle: function(elm) {
        Effect.toggle(elm,'blind', {duration : 0.1}); 
    },
    saveNeededWarning: function(elm) {
        Effect.ScrollTo(elm, {duration:0.4, afterFinish: function() {
            var jslintSTFU = new Effect.Highlight(elm, {startcolor:'ffff00'});
            WebTango.Feedback.attention("Please save or cancel first");
        }});
    },
    saveSucceeded: function(elm) {
        var jslintSTFU = new Effect.Highlight(elm, {startcolor:'74ad1a'});
    }
});


WebTango.Events = Class.create({});
Object.extend(WebTango.Events, {
    addEnterHandler: function(targetElm, handler) {
        Event.observe(targetElm,"keypress", function(eventArgs) {
            if (eventArgs.keyCode == Event.KEY_RETURN) {
                handler();
                Event.stop(eventArgs);
            }
        });
    }
});

WebTango.Feedback = Class.create({});
Object.extend(WebTango.Feedback, {
    attention: function(text) {
        WebTango.Feedback.show("attentionfeedback", text);
    },
    getErrorCallback: function(msg) {
        return function(err) {
            WebTango.Feedback.negative( msg + ": " + err.get_message());
        };
    },
    negative: function(text) {
        WebTango.Feedback.show("negativefeedback", text);
    },
    positive: function(text) {
        WebTango.Feedback.show("positivefeedback", text);
    },
    show: function (classToAdd, text) {
        var panelId = 'webtangoFeedback';
        var labelId = 'webtangoFeedbackContents';
        var panel = $(panelId);
        if (panel) {
            panel.removeClassName('negativefeedback');
            panel.removeClassName('attentionfeedback');
            panel.removeClassName('positivefeedback');
            panel.addClassName(classToAdd);
            $(labelId).update(text);
            
            Effect.Queues.get('feedbackqueue').each(function(e) { e.cancel(); });
            panel.hide();
                    
            Effect.Appear(panel, { to:0.95, queue: {position:'end', scope: 'feedbackqueue'} });
            var dur = classToAdd == "positivefeedback" ? 5.0 : 15.0;
            Effect.Fade(panel, { duration: dur, queue: {position:'end', scope: 'feedbackqueue'}});
        }
    }
});

WebTango.HelpTip = Class.create({
    initialize: function(elmId, tipName) {
        this._element = $(elmId);
        this.Name = tipName;
    },
    cloneToNewParent: function(newParent) {
        newParent = $(newParent);
        var theClone = $(this._element.cloneNode(true));
        theClone.id = null;
        theClone.identify();
        newParent.appendChild(theClone);
        theClone.show();
        return WebTango.HelpTipManager.register(theClone, this.Name);
    },
    hide: function() {
        Effect.Fade(this._element);
    }
});

WebTango.HelpTipManager = Class.create({});
WebTango.HelpTipManager._allTips = $A();
Object.extend(WebTango.HelpTipManager, {
    register: function(elmId, tipName) {
        var helpTip = new WebTango.HelpTip(elmId, tipName);
        WebTango.HelpTipManager._allTips.push(helpTip);
        return helpTip;
    },
    
    clone: function(tipName, newParent) {
        WebTango.HelpTipManager._allTips.each(function (helpTip) {
            if (helpTip.Name == tipName) {
                var clone = helpTip.cloneToNewParent(newParent);
                throw $break;
            }
        });
    },
    
    hide: function(tipName, clickedElm) {
        
        WebTango.Services.MasterService.DisableHelpTip(WebTango.webDeskPrefix, tipName, 
            function(isOK) {
                if (!isOK) { WebTango.Feedback.negative( "Could not hide help tip"); }
            },
            WebTango.Feedback.getErrorCallback("Error hiding help tip")
        );
        
        WebTango.HelpTipManager._allTips.each(function (helpTip) {
            if (helpTip.Name == tipName) {
                helpTip.hide();
            }
        });
        /*if (clickedElm) {
            var wrapper = $(clickedElm).up(".sidebarelement");
            if (wrapper) {
                Effect.Fade(wrapper);
            }
        }*/
    }
});


WebTango.InlinePopup = Class.create({
    initialize: function(options) {
        var confirmButton, cancelButton;
        var align = options.align ? options.align.capitalize() : "Left";
        var theClass = "inplacewarning" + align;
        var children = [Builder.node("h3", "Are you sure?")];
        if (options.warningText) {
            children.push(options.warningText)
            children.push(Builder.node("br"));
        }
        var confirmText = options.confirmText || "Yes, delete it";
        var cancelText = options.cancelText || "Cancel";
        
        if (options.onConfirm) {
            children.push(confirmButton = WebTango.Buttons.link(confirmText, false));
            Event.observe(confirmButton, "click", function() { this.remove(); options.onConfirm(); }.bind(this));
        } else if (options.confirmHref) {
            children.push(confirmButton = $(Builder.node("a", {href: options.confirmHref, className: "negative"}, confirmText)));
            Event.observe(confirmButton, "click", function() { this.remove(); }.bind(this));
        } else {
            children.push(Builder.node("b","Error: neither onConfirm nor confirmHref was specified"));
        }
        
        
        children.push(" or ");
        children.push(cancelButton = WebTango.Buttons.link(cancelText));
        
        this._popup = Builder.node("div", {className: theClass}, [
            Builder.node("div",{className:"top"},children)
        ]);
        var mLeft = options.margins ? options.margins[0] : 90;
        var mTop = options.margins ? options.margins[1] : 20;
        
        Event.observe(cancelButton, "click", this.remove.bind(this));
        if (options.onCancel) {
            Event.observe(cancelButton, "click", options.onCancel);
        }
        $(options.element).insert({after:this._popup});
        $(this._popup).setStyle({marginTop: mTop + "px",marginLeft: mLeft + "px"});
    },
    remove: function() {
        $(this._popup).remove();
    }
});

WebTango.KeepAlive = Class.create({
    initialize: function(interval) {
        var onError = function(err) {
            WebTango.Feedback.negative("Error keeping session alive" + err.get_message());
            setTimeout(function () {
                window.location = "/"; //go to login page
            }, 1000);
        };
        new PeriodicalExecuter(function() {
            WebTango.Services.MasterService.KeepAlive(Prototype.K, onError);
        }, interval);
    }
});

WebTango.LanguageList = Class.create({
    initialize: function(rawList) {
        this._data = $H(rawList);
        this._currentLang = WebTango.defaultLanguage;
    },
    set: function(lang, newText) {
        this._data.set(lang, newText);
    },
    setCurrent:function(newText) {
        return this.set(this._currentLang,newText);
    },
    get: function(lang) {
        var val = this._data.get(lang);
        if (val === undefined) { 
            this.set(lang, null); 
            return null;
        }
        return val;
    },
    getCurrent:function() {
        return this.get(this._currentLang);
    },
    getCurrentKey: function() {
        return this._currentLang;
    },
    hasTranslation:function() {
        return (this.getCurrent() !== null);
    },
    createTranslation:function() {
        var val = this.get(WebTango.defaultLanguage);
        if (val === null) { val = ""; }
        this.setCurrent(val);
    },
    removeTranslation:function() {
        if (this._currentLang == WebTango.defaultLanguage) {
            throw "Cannot remove default translation";
        }
        this._data.unset(this._currentLang);
    },
    
    setLanguage:function(newLangCode) {
        //var oldVal = this.get(newLangCode);
        this._currentLang = newLangCode;
        return this.hasTranslation();
    }
});

WebTango.PublishableView = {
    getPublishedText: function(published, unpublished) {
        var now = new Date();
        var fPublish = this.formatDate(published);
        var fUnPublish = this.formatDate(unpublished);
        var isPublic = this.isPublic(published,unpublished);
        
        if (isPublic) {
            return "Published " + fPublish;
        } else {
            if (published > now && unpublished > published && published < Date.CSharpMaxThreshold) {
                return "Will be published on " + fPublish;
            }
            return "Not published";
        }
    },
    formatDate: function(datetime) {
        if (!datetime) {
            return "Bad date";
        }
        return datetime.localeFormat("d");
    },
    formatTime: function(datetime) {
        return datetime.localeFormat("t");
    },
    isPublic: function(published, unpublished) {
        var now = new Date();
        var impublic = published < now && now < unpublished;
        return impublic;
    }
};

WebTango.QuickNav = Class.create({    
    initialize: function() {
        Event.observe(window, "load", function() {
            if (!window.clipboardData) { 
                $('quickNavButton').title = "Write a URL from your website in the box, then click here to navigate to the corresponding editor";
            } else {
                $('quickNavButton').title = "Click here to get the URL in your clipboard and navigate to the corresponding editor";
            }
            $('quickNavText').value = "";
            Event.observe($('quickNavButton'), "click", this._activate.bind(this));
        }.bind(this));
    },
    _activate: function() {
        var websiteUrl = "";
        
        if (window.clipboardData) {
            websiteUrl = window.clipboardData.getData('Text');
            this._callQuickNavService(websiteUrl);
        } else {
            var quickNavText = $('quickNavText');
            quickNavText.show();
            Event.observe(quickNavText,"keypress", function(eventArgs) {
                if (eventArgs.keyCode == Event.KEY_RETURN) {
                    webSiteUrl = $F('quickNavText');
                    this._callQuickNavService(webSiteUrl);        
                    Event.stop(eventArgs);
                }
            }.bind(this));
            $('quickNavButton').hide();
        }
    },
    _callQuickNavService: function(websiteUrl) {
        WebTango.Services.MasterService.GetQuickNavigationUrl(WebTango.webDeskPrefix, websiteUrl, this._onQuickNavDone.bind(this), this._onQuickNavFailed.bind(this));
        $('quickNavButton').hide();
        $('quickNavText').hide();
        $('quickNavSpinner').show();
    },
    _onQuickNavDone: function(url) {
        window.location.replace(url);
    },

    _onQuickNavFailed: function(err) {
        $('quickNavButton').show();
        $('quickNavText').hide();
        $('quickNavText').value = "";
        $('quickNavSpinner').hide();
        WebTango.Feedback.negative( "Error navigating: " + err.get_message());
    }
});

/* this class is used for representing the set of SiteMapItems that link to the active document
    in the document editor */
WebTango.SiteMapModel = Class.create({
    initialize: function(rawModel) {
        for (var propName in rawModel) {
            this[propName] = rawModel[propName];
        }
        this._itemHash = $H();
        this._itemHash.set(this.OID, this);
        this.Children = $A();
        for(var i=0;i<rawModel.Children.length;++i) {
            this.Children.push(new WebTango.SiteMapItemModel(rawModel.Children[i], this, this));
        }
        
    },
    addChild: function(name,targetOID) {
        var rawChild = this.makeRawChild(name,targetOID); 
        var child = new WebTango.SiteMapItemModel(rawChild, this, this);
        this.Children.push(child);
        return child;
    },
    addItemToHash: function(item) {
        this._itemHash.set(item.OID, item);
    },
    removeItemFromHash: function(itemOID) {
        this._itemHash.unset(itemOID);
    },
    getItem:function(OID) {
        return this._itemHash.get(OID);
    },
    makeRawChild: function(name, targetOID) {
        return {
            OID : this._getNextGuid(),
            DisplayName : name,
            Children: [],
            Url: {
                UrlTarget : "_self",
                IsInternal : true,
                InternalLinkOID: targetOID,
                __type: "WebTango.Json.Cms.Url"
            }
        };
    },
    updateOID: function(oldOID, newOID) {
        var item = this.getItem(oldOID);
        item.OID = newOID;
        this.removeItemFromHash(oldOID);
        this.addItemToHash(item);
    },
    /*toRaw: function() {
        return {
            OID: this.OID,
            DisplayName: this.DisplayName,
            Children: [],
            Url: this.Url,
            __type: "WebTango.Json.Cms.SiteMap"
        };
    },*/
    _guidCounter: 1,
    _getNextGuid: function() {
        return WebTango.Guid.makeFromInt(this._guidCounter++);
    }
});

WebTango.UrlModel = Class.create({
    initialize: function(rawUrl) {
        this.initVersionable();
        this.addProperty("UrlTarget", rawUrl.UrlTarget);
        this.addProperty("IsInternal", rawUrl.IsInternal);
        this.addProperty("ExternalLinkUrl", rawUrl.ExternalLinkUrl);
        this.addProperty("InternalLinkOID", rawUrl.InternalLinkOID);
        this.addProperty("ContentItemName", rawUrl.ContentItemName);
        this.addProperty("InternalPath", rawUrl.InternalPath);
        this.addProperty("ContentItemIsPublic", rawUrl.ContentItemIsPublic);
        this.OID = rawUrl.OID;
    },
    emptyUrl: function() {
        this.setProperty("UrlTarget", "_self");
        this.setProperty("IsInternal", true);
        this.setProperty("ExternalLinkUrl", "");
        this.setProperty("InternalLinkOID", WebTango.Guid.Empty);
        this.setProperty("ContentItemName", "");
        this.addProperty("InternalPath", "");
        this.addProperty("ContentItemIsPublic", true);
    },
    getDescription: function() {
        return this.getProperty("IsInternal") ? "Internal link to: '" + this.getProperty("ContentItemName") + "'" : "External link to: " + this.getProperty("ExternalLinkUrl");
    },
    getHref : function() {
        return this.getProperty("IsInternal") ? this.getProperty("InternalLinkOID") : this.getProperty("ExternalLinkUrl");
    },
    getIsEmpty: function() {
        return (this.getProperty("IsInternal") ? 
            this.getProperty("InternalLinkOID") === WebTango.Guid.Empty : 
            (this.getProperty("ExternalLinkUrl") === null || this.getProperty("ExternalLinkUrl").length === 0));
    },
    toRaw: function() {
        var raw = this.getProperties();
        raw.OID = this.OID;
        raw.__type = "WebTango.Json.Cms.Url";
        return raw;
    }
});

/* this class is used for representing SiteMapItems that link to the active document
    in the document editor */
WebTango.SiteMapItemModel = Class.create({
    initialize: function(rawModel, siteMap, parent) {
        for (var propName in rawModel) {
            this[propName] = rawModel[propName];
        }
        this.Parent = parent;
        this._siteMap = siteMap;
        this._siteMap.addItemToHash(this);
        this.Children = $A();
        for(var i=0;i<rawModel.Children.length;++i) {
            this.Children.push(new WebTango.SiteMapItemModel(rawModel.Children[i], this._siteMap, this));
        }
    },
    addChild: function(name, targetOID) {
        var rawChild = this._siteMap.makeRawChild(name,targetOID); 
        var child = new WebTango.SiteMapItemModel(rawChild, this._siteMap, this);
        this.Children.push(child);
        return child;
    },
    getBreadCrumb: function() {
        var item = this, crumb="";
        while (item) {
            crumb = item.DisplayName + crumb;
            item = item.Parent;
            if (item) crumb = " > " + crumb;
        }
        return crumb;
    },
    toRaw: function() {
        return {
            OID: this.OID,
            DisplayName: this.DisplayName,
            Children: [],
            Url: this.Url,
            ParentREF: this.Parent? this.Parent.OID : WebTango.Guid.Empty,
            __type: "WebTango.Json.Cms.SiteMapItem"
        };
    }
});

WebTango.TabGroup = Class.create({
    initialize: function(tabContainer, contentsContainer) {
        this._tabContainer = $(tabContainer);
        this._contentsContainer = $(contentsContainer);
        
        var tabOnClick = function(idx) {
            var contents = this._contentsContainer.immediateDescendants();
            contents.invoke("hide");
            contents[idx].show();
            var tabs = this._tabContainer.immediateDescendants();
            tabs.invoke("removeClassName","current");
            tabs[idx].addClassName("current");
        };
        
        $A(this._tabContainer.getElementsByTagName("a")).each(function (link, idx) {
            link.onclick = WebTango.Buttons._KILLONCLICK;
            $(link).observe("click", tabOnClick.bind(this,idx));
        }, this);
    }

});

WebTango.TreeUtils = Class.create({});
Object.extend(WebTango.TreeUtils, {
    /*  recursively applies function 'treeMethod' to the nodes of the DhtmlXTree instance 'tree', passing contents of
        the array 'args' as arguments to the function. The recursion starts at the node with ID 'itemId' */
    map: function(tree, itemId, treeMethod, args) {
        var curriedMethod = treeMethod.curry(itemId);
        for (var i=0;i<args.length;++i) {
            curriedMethod = curriedMethod.curry(args[i]);
        }
        curriedMethod.bind(tree)();
        var childString = tree.getSubItems(itemId);
        if (childString) {
            childString.split(',').each(function (childId) {
                WebTango.TreeUtils.map(tree, childId, treeMethod, args);
            });
        }
    }
});

/* validation */

WebTango.Validation = Class.create({});
Object.extend(WebTango.Validation, {
    _ERROR_CLASSNAME : "validationerror",
    addDefaultChangeHandler: function(elm, validationFunction) {
        elm = $(elm);
        elm.observe("change", WebTango.Validation.create({
            validate : validationFunction,
            onAccept : WebTango.Validation.removeErrorClass,
            onReject : WebTango.Validation.addErrorClass,
            args: elm
        }));
    },
    addDefaultSubmitHandler: function(field, errorMsg, validationFunction) {
        return {            
            validate : validationFunction, 
            args : field,
            acceptArgs : [field, errorMsg],
            rejectArgs : [field, errorMsg]
        }
    },
    create: function(valObj) {
	    if (!valObj.validate) { throw "must have validate"; }
        if (!valObj.args) { throw "must have args"; }
        var rejectArgs = valObj.rejectArgs || valObj.args;
        var acceptArgs = valObj.acceptArgs || valObj.args;
        
        return function() {
            var valid = valObj.validate(valObj.args);
            if (valid) { if (valObj.onAccept) { valObj.onAccept(acceptArgs); } }
            else { if (valObj.onReject) { valObj.onReject(rejectArgs); } }
            return valid;
        };
    },
    createChain: function(obj) {
        var chainFunctions = obj.chain.map(function(chainPart) {
            return WebTango.Validation.create({
                validate: chainPart.validate,
                args: chainPart.args,
                acceptArgs : chainPart.acceptArgs,
                rejectArgs : chainPart.rejectArgs,
                onReject : obj.onReject || chainPart.onReject,
                onAccept : obj.onAccept || chainPart.onAccept
            });
        });
        return function() {
            var success = true;
            chainFunctions.each( function(chainFunction) {
                success = chainFunction() && success;
            });
            if (success && obj.finalAccept) { obj.finalAccept(); }
            if (!success && obj.finalReject) { obj.finalReject(); }
        };
    },
    createMsg: function(text) {
        return $(Builder.node("div", {className:"validationerror", style:"display:none"}, Builder.node("span", text)));
    },
    isBoolString: function(arg) {
        var val = arg.value;
        return (val == "True" || val == "False");
    },
    isDate: function(arg) {
	    return Date.parseLocale(arg.value, "d") !== null;
	},
	isEAN8: function(arg) {
	    var val = arg.value;
	    return  /^[0-9]{8}$/.test(val);
	},
	isEAN13: function(arg) {
	    var val = arg.value;
	    return  /^[0-9]{13}$/.test(val);
	},
	isEmail: function(arg) {
	    var val = arg.value;
	    return  /^[A-Za-z0-9._%-]+@[A-Za-z0-9._%-]+\.[A-Za-z]{2,4}$/.test(val);
	},
	isFloat: function(arg) {
	    return !isNaN(Number.parseLocale(arg.value));
	},
	isInteger: function(arg) {
	    var val = arg.value;
	    return  /^\-?[0-9]+$/.test(val);
	},
	isISBN: function(arg) {
	    var val = arg.value;
	    return  /^[-0-9]{6,12}$/.test(val);
	},
	isNonEmpty: function(arg) {
	    var val = arg.value;
	    return !!val;
	},
	isTime: function(arg) {
	    return Date.parseLocale(arg.value, "t") !== null;
	},
	addErrorClass: function(arg) {
        $(arg).addClassName(WebTango.Validation._ERROR_CLASSNAME);
    },
    addErrorClassAndAppear: function(args) {
        WebTango.Validation.addErrorClass(args[0]); 
        Effect.Appear(args[1]);
    },
    removeErrorClass: function(arg) {
        $(arg).removeClassName(WebTango.Validation._ERROR_CLASSNAME);
    },
    removeErrorClassAndFade: function(args) {
        WebTango.Validation.removeErrorClass(args[0]);
        Effect.Fade(args[1]);
    },
    color: function (arg) { 
        $(arg).setStyle({backgroundColor: '#f0f'}); 
    },
    removeColor: function (arg) { 
        $(arg).setStyle({backgroundColor: ''}); 
    }
});

WebTango.Versionable = {
    initVersionable: function() {
        this._properties = $H();
        this._pendingProperties = $H();
    },
    addProperty: function(name, initialValue) {
        this._properties.set(name, initialValue);
        this._pendingProperties.set(name, null);
    },
    getProperties: function() {
        var res = {};
        this._properties.keys().each(function(name) {
            res[name] = this.getProperty(name);
        }, this);
        return res;
    },
    getProperty: function(name) {
        var pendingVal = this._pendingProperties.get(name);
        if (pendingVal !== null) { return pendingVal; }
        return this._properties.get(name);
    },
    setProperty: function(name,value) {
        if (value !== this.getProperty(name)) {
            this._pendingProperties.set(name,value);
        }
    },
    commitProperties: function() {
        this._properties.keys().each(function(key) {
            this.commitProperty(key);
        }, this);
    },
    commitProperty: function(name) {
        var pendingVal = this._pendingProperties.get(name);
        if (pendingVal !== null) {
            this._properties.set(name,pendingVal);
        }
        this._pendingProperties.set(name,null);
    },
    rollbackProperties: function() {
        this._properties.keys().each(function(key) {
            this.rollbackProperty(key);
        }, this);
    },
    rollbackProperty: function(name) {
        this._pendingProperties.set(name, null);
    }
};

WebTango.UrlModel.addMethods(WebTango.Versionable);

WebTango.FileUploader = Class.create({
    initialize: function() {
    
    },
    beginFileSelect: function(options) {
        if (!WebTango.hasRequiredFlashVersion()) {
            if (options.onNoFlashDetected) { options.onNoFlashDetected(); }
            else { WebTango.Feedback.negative( "No flash plugin found. Flash is required for file upload."); }
            return;
        }
        var uploader = this._getUploader();
        this._uploadType = options.type;
        uploader.customSettings.onDialogComplete = options.onDialogComplete;
        uploader.customSettings.onFileUploaded = options.onFileUploaded;
        uploader.customSettings.onAllUploadsComplete = options.onAllUploadsComplete;
        
        var postParams = {"EsKey": WebTango.esKey, "Type": options.type};
        var extendedParams = Object.extend(postParams, options.postParams);
        //save params for later as SWFUpload does not like changing them
        this._postParams = extendedParams;
        
        setTimeout(function() { 
            var isImage = options.type.endsWith("Image");
            var typePattern = isImage ? "*.jpg;*.jpeg;*.gif;*.png" : "*.*";
            var description = isImage ? "Images (JPEG, GIF, and PNG)" : "All files";
            uploader.setFileTypes(typePattern, description);
            uploader.selectFile();
        },300);
    },
    setPostParam:function(name, value) {
        this._postParams[name] = value;
    },
    startUpload: function() {
        this._uploader.setPostParams(this._postParams);
        this._uploader.startUpload();
    },
    _getUploader: function() {
        if (this._uploader === undefined) {
            this._uploader = new SWFUpload({
				// Backend Settings
				upload_url: "/cms.ashx/Utils/UploadTargetSWF",	// Relative to the SWF file or absolute
				post_params: {},
				
				// File Upload Settings
				file_size_limit : "2048",	// 2MB TODO
				file_upload_limit : "0",
                file_queue_limit : "1",

				file_queue_error_handler : function(fileObj, error_code, message) { alert ("File queue error : " + error_code + " " + message); },
				file_dialog_complete_handler : function (num_files_queued) {
	                try {
		                if (num_files_queued > 0) { 
		                    if (this.customSettings.onDialogComplete) { this.customSettings.onDialogComplete(); }
		                    //this.startUpload(); 
		                }
	                } catch (ex) { this.debug(ex); }
                },
				upload_error_handler : function(fileObj, error_code, message) { alert ("Upload error : " + error_code + " " + message); },
				upload_success_handler : function(fileObj, server_data) {
	                if (this._uploader.customSettings.onFileUploaded) {
	                    var jsondata = server_data.evalJSON(true);
	                    var newFile = null;
	                    jsondata.__type = this._uploadType;
	                    switch(this._uploadType) {
	                        case "WebTango.Json.Environment.StaffImage":
	                            //here we just pass a dummy json object with the new image URL
	                            newFile = jsondata;
	                            break;
	                    }
	                    this._uploader.customSettings.onFileUploaded(newFile);
	                }
		        }.bind(this),
				upload_complete_handler : function(fileObj) {
				    if (this.getStats().files_queued > 0) { 
				        this.startUpload(); 
				    } else {
				        if (this.customSettings.onAllUploadsComplete) { this.customSettings.onAllUploadsComplete(); }
				    }
				},

				// Flash Settings
				flash_url : "/Applets/swfupload_f9.swf",	// Relative to this file or absolute
				
				// Debug Settings
				debug: false
			});
        }
        return this._uploader;
    }
});

////OLD STUFF FROM WTFUNCS THAT SHOULD NOT BE USED!!!

//General purpose delete confirmation
//The sender parameter is a reference to the clicked button/link
function ConfirmDelete(sender) {
    return confirm("Are you sure you really want to delete this?");
}

//this global variable should exist as it is modified by some old code
//no new code should use it - instead the WebTango.ChangesTracker class should be used
var pageIsDirty = false;
WebTango.notifyScriptManager();
