/**
 * Loader for external scripts.
 */
var ScriptLoader = function() {

    // Interface.
    this.beginLoad = beginLoad;
    this.onGlobalScriptElement = onGlobalScriptElement;

    var timerHandle = null;
    var checkInterval = 50;
    var pendingCallbacks = {};

    function beginLoad(path) {

        var doc = document;

        // No duplicates.
        var scripts = doc.getElementsByTagName("script");
        for (var i = 0; i < scripts.length; i++) {
            var src = scripts.item(i).src;
            if (src.length >= path.length &&
                src.substring(src.length - path.length) == path) {
                return;
            }
        }

        var s = doc.createElement("script");
        s.setAttribute("type", "text/javascript");
        s.setAttribute("src", path);

        doc.body.appendChild(s);

    }

    function onGlobalScriptElement(elementName, callback, callbackArg) {

        if (checkScriptElement(elementName)) {
            callback(callbackArg);
        } else {

            // Register the callback.
            pendingCallbacks[elementName] = {
                callback: callback,
                callbackArg: callbackArg
            };

            if (!timerHandle) {
                timerHandle = setInterval(checkElements, checkInterval);
            }
        }
    }

    function checkElements() {

        var pendingCount = 0;
        for (var elementName in pendingCallbacks) {
            var callbackInfo = pendingCallbacks[elementName];
            pendingCount++;
            if (checkScriptElement(elementName)) {
                callbackInfo.callback(callbackInfo.callbackArg);
                delete pendingCallbacks[elementName];
            }
        }

        if (pendingCount == 0) {
            clearInterval(timerHandle);
            timerHandle = null;
        }
    }

    function checkScriptElement(elementName) {
        return typeof(window[elementName]) != "undefined";
    }

}

function Dot() {

    var id;
    var rating;
    var subject;
    var content;
    var url;
    var affiliateUrl;
    var category;
    var tags;
    var permissions;
    var imageUrl;
    var imageWidth;
    var imageHeight;

    this.getId = function() {
        return id;
    };
    this.setId = function(value) {
        id = value;
    };

    this.getRating = function() {
        return rating;
    };
    this.setRating = function(value) {
        rating = value;
    };

    this.getSubject = function() {
        return subject;
    };
    this.setSubject = function(value) {
        subject = value;
    };

    this.getContent = function() {
        return content;
    };
    this.setContent = function(value) {
        content = value;
    };

    this.getUrl = function() {
        return url;
    };
    this.setUrl = function(value) {
        url = value;
    };

    this.getAffiliateUrl = function() {
        return affiliateUrl;
    };
    this.setAffiliateUrl = function(value) {
        affiliateUrl = value;
    };

    this.getCategory = function() {
        return category;
    };
    this.setCategory = function(value) {
        category = value;
    };

    this.getTags = function() {
        return tags;
    };
    this.setTags = function(value) {
        tags = value;
    };

    this.getPermissions = function() {
        return permissions;
    };
    this.setPermissions = function(value) {
        permissions = value;
    };

    this.getImageUrl = function() {
        return imageUrl;
    };
    this.setImageUrl = function(value) {
        imageUrl = value;
    };

    this.getImageWidth = function() {
        return imageWidth;
    };
    this.setImageWidth = function(value) {
        imageWidth = value;
    };

    this.getImageHeight = function() {
        return imageHeight;
    };
    this.setImageHeight = function(value) {
        imageHeight = value;
    };

}

function getElementText(element) {
    var text = "";
    for (var node = element.firstChild; node; node = node.nextSibling) {
        if (node.nodeType == 3) {
            text += node.nodeValue;
        } else if (node.nodeType == 1) {
            text += getElementText(node);
        }
    }
    return text;
}

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/, "");
};

function getIntVal(id) {
    return parseInt($(id).value);
}

function showElement(o) {

    var el = (typeof(o) == "string") ? $(o) : o;

    if (!Element.visible(el)) {
        Element.toggle(el);
    }
}

function hideElement(o) {

    var el = (typeof(o) == "string") ? $(o) : o;

    if (Element.visible(el)) {
        Element.toggle(el);
    }
}

function hideElements(rg) {

    for (var i = 0; i < rg.length; i++) {
        hideElement(rg[i]);
    }
}

// Add innerText to all elements
//
if (typeof(HTMLElement) != "undefined") {

    HTMLElement.prototype.__defineGetter__("innerText", function () {
        var range;

        range = document.createRange( );
        range.selectNode(this);

        return range.toString();
    });

    HTMLElement.prototype.__defineSetter__("innerText", function(text) {
        var range;
        
        range = document.createRange();
        range.selectNodeContents(this);
        range.deleteContents();
        this.appendChild(document.createTextNode(text));

        return text;
    });    
}



// Pop over registration box
//
var g_timer = null;

function showRegistrationBoxForVoteAttempt() {
    return showRegistrationBox("/event/vote_attempt");
}

function showRegistrationBox(urchinEvent) {

    if (urchinEvent != null) {
        try {
            urchinTracker(urchinEvent);
        } catch(e) {
        }
    }

    if ((isSafari()) || (isIEPre7())) {
        // If we don't do this, Safari makes the redirect to the registration page
        // before making the urchinTracker call.
        setTimeout("navigateToRegistrationLoginPage()", 100);
        return false;
    }

    RegistrationHandler.RenderRegistrationLoginDialog(
        document.location.href,
        onRenderRegistrationLoginDialog,
        navigateToRegistrationLoginPage);
}

function hideRegistrationBox() {

    var objectTags;

    objectTags = document.getElementsByTagName("OBJECT");

    for (var i = 0; i < objectTags.length; i++) {
        objectTags[i].style.visibility = "";    
    }

    objectTags = document.getElementsByTagName("EMBED");

    for (var i = 0; i < objectTags.length; i++) {
        objectTags[i].style.visibility = "";    
    }

    hideDialogBox();
}

function onRenderRegistrationLoginDialog(request) {

    var s;
    var objectTags;

    s = "<div class=\"registrationDialogTop\"></div><div class=\"registrationDialogMiddle\">" +
        request.responseText + "</div><div class=\"registrationDialogBottom\"></div>";
        
    showDialogBox(s, 688, true);

    objectTags = document.getElementsByTagName("OBJECT");

    for (var i = 0; i < objectTags.length; i++) {
        objectTags[i].style.visibility = "hidden";    
    }

    objectTags = document.getElementsByTagName("EMBED");

    for (var i = 0; i < objectTags.length; i++) {
        objectTags[i].style.visibility = "hidden";    
    }

    Event.observe(document.body, "keyup", onBodyKeyUp, false);
    Event.observe($("registrationUserName"), "keyup", onUsernameTextEntered, false);
    Event.observe($("registrationUserName"), "focus", onInputFocus, false);
    Event.observe($("registrationUserName"), "blur", onInputBlur, false);
    Event.observe($("registrationPassword"), "focus", onInputFocus, false);
    Event.observe($("registrationPassword"), "blur", onInputBlur, false);
    Event.observe($("registrationEmailAddress"), "focus", onInputFocus, false);
    Event.observe($("registrationEmailAddress"), "blur", onInputBlur, false);
}

function redirectWithTimeout(locationHref) {
    setTimeout(function() { document.location.href = locationHref; }, 100);
    return false;
}

function navigateToRegistrationLoginPage() {
    document.location.href = "signIn?show=ur&returnUrl=" + encodeURIComponent(document.location.href);
}

function dialogLogIn() {

    $("loginReturnUrl").value = document.location.href;
    $("loginForm").submit();
}

function isIE() {
    return window.attachEvent;
}

function isSafari() {
    return navigator.appVersion.match(/Safari/);
}

function isOpera() {
    return window.opera;
}

function isIEPre7() {
    return isIE() && !isOpera() && 
        (navigator.userAgent.indexOf("MSIE 6") >= 0 || navigator.userAgent.indexOf("MSIE 5.5") >= 0);
}
    
function showDialogBox(html, width, isModal) {

    var mask;
    var box;
    var boxStyle;

    mask = $("dialogMask");
    
    if (mask) {
        Element.remove(mask);
    }

    mask = document.createElement("div");
    document.body.appendChild(mask);

    mask.id = "dialogMask";
    mask.style.height = window.document.body.offsetHeight + "px";

    box = $("dialogBox");

    if (box) {
        Element.remove(box);
    }

    box = document.createElement("div");
    document.body.appendChild(box);

    box.id = "dialogBox";
    box.style.width = width + "px";
    box.innerHTML = html;

    positionDialogBox(box);

    document.body.onkeypress = keyPressDialogBox;

    if (isModal) {
        document.body.onmousedown = null;    
    } else {
        document.body.onmousedown = hideDialogBox;    
    }
}

function positionDialogBox(box) {

    var boxStyle;

    boxStyle = box.style;
    boxStyle.left = ((document.body.clientWidth - box.offsetWidth) / 2) + "px";    
    boxStyle.top = ((document.documentElement.clientHeight - box.offsetHeight) / 4) + 
        document.documentElement.scrollTop + "px";
}

function keyPressDialogBox(e) {

    if (!e) {
        e = event;
    }
        
    if (e.keyCode != 27) {        
        return;
    }
    
    hideDialogBox();
}

function hideDialogBox() {

    var mask;
    var box;

    mask = $("dialogMask");
    box = $("dialogBox");

    if (mask) {
        Element.remove(mask);
    }

    if (box) {
        Element.remove(box);
    }
        
    document.body.onkeypress = null;
}

function onBodyKeyUp(e) {

    if (e.keyCode != 27) {
        return;
    }

    hideRegistrationBox();   
}

function onInputFocus(e) {

    var row;
    
    row = Event.element(e).parentNode.parentNode;
    row.className = "highlightRow";
}

function onInputBlur(e) {

    var row;
    
    row = Event.element(e).parentNode.parentNode;
    row.className = "";
}

function dialogRegister() {

    if (!$("registrationTermsOfUse").checked) {
        alert(g_agreeToTerms);
        return;
    }

    $("registrationSuccessUrl").value = document.location.href;

    try {
        urchinTracker("/event/acct_created");
    } catch(e) {
    }
    
    setTimeout(function() { $("registrationForm").submit(); }, 100);
}

function onUsernameTextEntered(e) {

    var usernameValue = $("registrationUserName").value;
    
    if (usernameValue && usernameValue != "") {
       
        if (e.keyCode != 144) {

            writeMessage("Checking availability...", "friendlyPrompt");
            
            if (g_timer != null) {
                clearTimeout(g_timer);
            }

            g_timer = setTimeout(checkUserName, 400);
        }
    } else {
        writeMessage("", "");
    }
}

function writeMessage(msg, cssClass) {

    var msgElement = $("registrationUserNameMessage");
    
    if (msgElement.firstChild) {
        msgElement.removeChild(msgElement.firstChild);
    }
            
    msgElement.className = cssClass;
    msgElement.appendChild(document.createTextNode(msg));
}

function checkUserName() {

    var inputValue = $("registrationUserName").value;
    var encUsernameValue = encodeURIComponent(inputValue);
    new Ajax.Request("UsernameChecker.ashx" +
                     "?login=" +
                     encUsernameValue,
                    { method: "GET",
                      onSuccess: usernameCheckRequestComplete });
}

function usernameCheckRequestComplete(request) {
    var result = request.responseXML.getElementsByTagName("value")[0];
    var css = request.responseXML.getElementsByTagName("cssClass")[0];
 
    var msg = getElementText(result);
    var cssClass = getElementText(css);
    var msgElement = $("registrationUserNameMessage");
   
    if(msgElement.firstChild) {
        msgElement.removeChild(msgElement.firstChild);
    }
    msgElement.className = cssClass;
    msgElement.appendChild(document.createTextNode(msg));      
}

function isNullOrEmpty(s) {
    return ((s == null) || (s.length == 0));
}

function javascriptEscape(s) {

    return s.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"").replace(/'/g, "\\'"); //"
}

var g_baseEmailRegex =
        "(([a-zA-Z0-9_\\-\\.\\+]+)@" +
        "((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))" +
        "([a-zA-Z]{2,7}|[0-9]{1,3}))";

var g_emailRegex = "^\\s*" + g_baseEmailRegex + "\\s*$";

function RegExpValidator(pattern, errorElement, errorText) {

    var self = this;

    self.pattern = pattern;
    self.errorElement = errorElement;
    self.errorText = errorText;
    self.validate = validate;

    function validate(value) {

        var re = new RegExp(pattern);

        if (value.match(re)) {
            self.errorElement.style.display = "none";
            return true;
        }

        self.errorElement.innerText = self.errorText;
        self.errorElement.style.display = "";
        return false;
    }
}

function RequiredFieldValidator(requiredElement, minimumLength, errorElement, errorText) {

    var self = this;

    self.requiredElement = requiredElement;
    self.errorElement = errorElement;
    self.minimumLength = minimumLength;
    self.errorText = errorText;

    self.validate = function() {

        if (self.requiredElement.value.trim().length < self.minimumLength) {

            self.errorElement.innerText = self.errorText;
            showElement(self.errorElement);
            return false;
        }

        hideElement(self.errorElement);
        return true;
    }
}
