﻿function object(o) {
    function F() { }
    F.prototype = o;
    return new F();
}

/** global scope */
if (typeof _global_ === "undefined") {
    _global_ = {
        /*
        Use function @namespace to create dot separated namespaces. For example: 
        Create a nested namespace:
        _global_["@namespace"]("foo");
        _global_["@namespace"]("foo.bar");
        _global_["@namespace"]("foo.bar.something");
        Then add functions to the namespace:	
        foo.bar.something.else = function() {};
        */
        "@namespace": function(str) {
            var a = str.split(".");
            var o = window;
            for (var i = 0; i < a.length; i++) {
                if (!o[a[i]]) {
                    o[a[i]] = {};
                }
                o = o[a[i]];
            }
        }
    }
};

// Create the global Teach For Australia namespace to avoid JS collisions with other scripts running on the page (eg. prototype, scriptaculous, or custom scripts)
_global_["@namespace"]("TFA");

/** Define constants used in scripts on this page
------------------------------------------------------------------ */
_global_["@namespace"]("TFA.Events");

// Attach functions to handle events that occur on the named event source. Doesn't override previously registered handlers for the same source/event.
// See: http://www.howtocreate.co.uk/tutorials/javascript/domevents
TFA.Events.AddEvent = function(source, eventName, functionName, useCapture) {
    useCapture = (typeof (useCapture) == "undefined") ? false : true;  // if true the event is only handled when it occurs on child/ancestor elements of the source/target element
    if (source.addEventListener) {
        source.addEventListener(eventName, functionName, useCapture);
        return true;
    }
    else if (source.attachEvent) {
        var r = source.attachEvent('on' + eventName, functionName);
        return r;
    }
    else {
        source['on' + eventName] = functionName;
    }
}

/** DOM methods
------------------------------------------------------------------ */
_global_["@namespace"]("TFA.DOM");

// getElementById shorthand.  Returns a single node.
TFA.DOM.ByID = function(id, node) {
    return document.getElementById(id);
}

// getElementsByTagName shorthand. Returns an array.
TFA.DOM.ByTag = function(tag, node) {
    var tag = tag || '*';
    var node = node || document;
    var e = node.getElementsByTagName(tag);
    return e;
}

// Returns elements that contain a CSS class. Returns an array.
TFA.DOM.ByClass = function(cssClass, node, tag) {
    // create new array to store matches
    var matches = [];
    var node = node || document;
    var tag = tag || '*';
    var els = TFA.DOM.ByTag(tag, node);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)" + cssClass + "(\\s|$)");
    for (i = 0, j = 0; i < elsLen; i++) {
        if (pattern.test(els[i].className)) {
            matches[j] = els[i];
            j++;
        }
    }
    return matches;
}

// Returns an element with ID = 'string'. If none it returns a collection of elements that have CSS class name = 'string'.
TFA.DOM.FindNodes = function(string, parent) {
    var node = false;
    var parent = parent || document;
    // try to get by id first
    node = TFA.DOM.ByID(string, parent);
    // now try by classname
    if (!node) node = TFA.DOM.ByClass(string, parent);
    return node;
}

// Set inline style of an element
TFA.DOM.SetNodeStyle = function(element, newStyle) {
    if (element && newStyle) {
        // IE
        if (typeof (element.style.cssText) != 'undefined')
            element.style.cssText = newStyle;
        // older browsers; not IE
        else
            element.setAttribute('style', newStyle);
    }
}

TFA.DOM.HasClass = function(element, cssClassName) {
    if (element && element.className) {
        var pattern = new RegExp('(\\s|^)' + cssClassName + '(\\s|$)');
        return pattern.test(element.className);
    }
    else {
        return false;
    }
}

TFA.DOM.AddClass = function(element, cssClassName) {
    if (element) {
        if (!TFA.DOM.HasClass(element, cssClassName)) {
            if (!element.className)
                element.className = cssClassName;
            else
                element.className += " " + cssClassName;
        }
    }
}

TFA.DOM.RemoveClass = function(element, cssClassName) {
    if (element) {
        if (TFA.DOM.HasClass(element, cssClassName)) {
            var reg = new RegExp('(\\s|^)' + cssClassName + '(\\s|$)');
            element.className = element.className.replace(reg, ' ');
        }
    }
}

// use to replace one CSS class with another on an element
TFA.DOM.ReplaceClass = function(element, oldClassName, newClassName) {
    TFA.DOM.RemoveClass(element, oldClassName);
    TFA.DOM.AddClass(element, newClassName);
}

TFA.DOM.ShowElement = function(id) {
    var e = TFA.DOM.ByID(id);
    if (typeof (e) != "undefined") {
        TFA.DOM.RemoveClass(e, "hidden");
        TFA.DOM.AddClass(e, "visible");
    }
}

TFA.DOM.HideElement = function(id) {
    var e = TFA.DOM.ByID(id);
    if (typeof (e) != "undefined") {
        TFA.DOM.RemoveClass(e, "visible");
        TFA.DOM.AddClass(e, "hidden");
    }
}

/** Browser/client methods
------------------------------------------------------------------ */
_global_["@namespace"]("TFA.Client");


TFA.Client.ReadCookie = function(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}



/** Miscellaneous methods
------------------------------------------------------------------ */
_global_["@namespace"]("TFA.Misc");


TFA.Misc.CheckUniScoresProvided = function(sender, args) {

    args.IsValid = false;
    return;

    // Check that the field variables have been initialised
    if (resultsPercentage && gPAScore && maxGPAScore && numberOfCoursesCompleted && numberOfHighDistinctions && numberOfDistinctions) {

        var validPercentScoreIsProvided = false;
        if (TFA.String.HasValue(resultsPercentage.value)) {
            var resultsPercent = resultsPercentage.value.Trim();
            if (TFA.Math.IsNumeric(resultsPercent)) {
                resultsPercent = parseFloat(resultsPercent);
                validPercentScoreIsProvided = (resultsPercent >= 0) && (resultsPercent <= 100);
            }
        }
        if (validPercentScoreIsProvided)
            return true;

        var validGpaScoreIsProvided = false;
        if (TFA.String.HasValue(gPAScore.value) && TFA.String.HasValue(maxGPAScore.value)) {
            var gpaScore = gPAScore.value.Trim();
            var maxGpaScore = maxGPAScore.value.Trim();
            if (TFA.Math.IsNumeric(gpaScore) && TFA.Math.IsNumeric(maxGpaScore)) {
                gpaScore = parseFloat(gpaScore);
                maxGpaScore = parseFloat(maxGpaScore);
                validGpaScoreIsProvided = (gpaScore >= 0) && (gpaScore <= 10) && (maxGpaScore >= 0) && (maxGpaScore <= 10);
            }
        }
        if (validGpaScoreIsProvided)
            return true;

        var validDistinctionsIsProvided = false;
        if (TFA.String.HasValue(numberOfCoursesCompleted.value) && TFA.String.HasValue(numberOfHighDistinctions.value) && TFA.String.HasValue(numberOfDistinctions.value)) {
            var numCoursesCompleted = numberOfCoursesCompleted.value.Trim();
            var numHighDistinctions = numberOfHighDistinctions.value.Trim();
            var numDistinctions = numberOfDistinctions.value.Trim();
            if (TFA.Math.IsNumeric(numCoursesCompleted) && TFA.Math.IsNumeric(numHighDistinctions) && TFA.Math.IsNumeric(numDistinctions)) {
                numCoursesCompleted = parseFloat(numCoursesCompleted);
                numHighDistinctions = parseFloat(numHighDistinctions);
                numDistinctions = parseFloat(numDistinctions);
                validDistinctionsIsProvided = (numCoursesCompleted >= 0) && (numCoursesCompleted <= 60) &&
                    (numHighDistinctions >= 0) && (numHighDistinctions <= numCoursesCompleted) &&
                    (numDistinctions >= 0) && (numDistinctions <= (numCoursesCompleted - numHighDistinctions));
            }
        }
        if (validDistinctionsIsProvided)
            return true;

        var alternativeScoreIsProvided = TFA.String.HasValue(alternativeScoringDetails.value.Trim());
    }

    var isValid = validPercentScoreIsProvided || validGpaScoreIsProvided || validDistinctionsIsProvided || alternativeScoreIsProvided

    alert(isValid);

    args.IsValid = validPercentScoreIsProvided || validGpaScoreIsProvided || validDistinctionsIsProvided || alternativeScoreIsProvided;
}

/** String functions
------------------------------------------------------------------ */
_global_["@namespace"]("TFA.String");

// Returns true if the string parameter contains only spaces, tabs or EOL characters
TFA.String.IsBlank = function (string) {
  var isBlank = true;
  for (var i=0; isBlank && (i < string.length); i++) {
    var c = string.charAt(i);
    if ((c != ' ') && (c != '\n') && (c != '\t')) isBlank = false;
  }
  return isBlank;
}

// Returns true if the string parameter equals null, an empty string, a tab, EOL or space character. 
TFA.String.HasValue = function (value) {
  if ((value == null) || (value=="") || TFA.String.IsBlank(value)) return false;
  else return true;
}

TFA.String.IsValidEmail = function (value) {
	var emailOk   = true;
	var atPos     = value.indexOf('@');
	var periodPos = value.lastIndexOf('.');
	var spacePos  = value.indexOf(' ');
	var length    = value.length - 1;         // Array is from 0 to length-1
	if ((atPos < 1) ||                        // '@' cannot be in first position
	    (periodPos <= atPos+1) ||             // Must be at least one valid char between '@' and '.'
	    (periodPos == length ) ||             // Must be at least one valid char after '.'
	    (spacePos  != -1))                    // No empty spaces permitted
	      emailOk = false;
	return emailOk;
}

/** String functions
------------------------------------------------------------------ */
_global_["@namespace"]("TFA.Math");


TFA.Math.IsNumeric = function(value) {
    if (isNaN(parseFloat(value))) {
        return false;
    }
    return true;
}



/** Javascript prototype extensions
------------------------------------------------------------------ */

// Create string Trim() prototype method
if (typeof String.prototype.Trim === 'undefined') 
{
	String.prototype.Trim = function() 
	{
		s = this.replace(/^\s+/, '');
		return s.replace(/\s+$/, '');
	};
}

/*
if (typeof String.prototype.GetFunctionBody === 'undefined') {
    String.prototype.GetFunctionBody = function() {
        var str = this.toString();
        str = str.replace(/[^{]+{/, "");
        str = str.substring(0, str.length - 1);
        str = str.replace(/\n/gi, "");
        if (!str.match(/\(.*\)/gi)) str += ")";
        return str;
    }
}
*/

/* TODO: jsmin */