/* Global */
/*************************************************/
Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function (obj, fromIndex) {
        if (fromIndex == null) {
            fromIndex = 0;
        } else if (fromIndex < 0) {
            fromIndex = Math.max(0, this.length + fromIndex);
        }
        for (var i = fromIndex, j = this.length; i < j; i++) {
            if (this[i] === obj)
                return i;
        }
        return -1;
    };
}

jQuery.fn.present = function () {
    return this.length > 0;
};

// A more accessible "hover" function which functions with keyboard focus
jQuery.fn.extend({
    hover: function (fnOver, fnOut) {
        return this.bind('mouseenter focusin focus click', fnOver).bind('mouseleave blur focusout', fnOut);
    }
});


// Fade and slide effect
jQuery.fn.fadeThenSlideAndRemove = function (callback) {
    var that = this;
    return this.fadeTo(200, 0, 'linear').slideUp(300, function () {
        $(that).remove();
        if (typeof callback === "function") {
            callback();
        }
    });
};
String.method('trim', function () {
    return this.replace(/^\s+|\s+$/g, '');
});

$.ajaxSetup({
    error: function (e, xhr, settings, exception) {
        app.helpers.ajaxError(exception);
    },
    timeout: 60 * 1000,
    dataType: 'json'
});

/* End global */
/*************************************************/

var app = {
    html: {
        inlineIndicator: '<img src="../magazine/front/images/inline_indicator_dark.gif" alt="Loading&hellip;" width="16" height="16" class="inlineIndicator"/>'
    },
    msg: {
        error: "An error occurred, please try again.",
        deletes: "Are you sure you want to delete this?"
    },
    keys: {
        TAB: 9,
        ENTER: 13,
        ESC: 27
    },
    browser: {
        IE6: false,
        IE7: false,
        IE: false
    },
	flash : {
		minMajorVer: 7
	},
	helpers : {
        isKey: function (evt, key) {
            return evt.keyCode && evt.keyCode === key;
        },
        isValid: function (ok, msg) {
            return { valid: ok || false, msg: ok ? "Ok" : msg };
        },
        deDupe: function (arr) {
            var i,
			    len = arr.length,
			    out = [],
			    obj = {};

            // Use object hash to count and remove dupes
            for (i = 0; i < len; i++) {
                obj[arr[i]] = typeof obj[arr[i]] != "undefined" ? obj[arr[i]] + 1 : 1;
            }

            // Put de-duped into out array and return
            for (i in obj) {
                out.push(i);
            }
            return { count: obj, arr: out };
        },
        ajaxError: function (msg) {
            alert(msg ? msg : app.msg.error);
        },
        curry: function (fn) {
            var slice = Array.prototype.slice,
				stored_args = slice.call(arguments, 1);

            return function () {
                var new_args = slice.call(arguments),
					args = stored_args.concat(new_args);

                return fn.apply(null, args);
            }
        },
        addDefault: function (key, value) {
            if (typeof app.DEFAULTS === "undefined") {
                app.DEFAULTS = {};
            }
            app.DEFAULTS[key] = value;
        },
        extendDefault: function (key, merge) {
            app.DEFAULTS = app.DEFAULTS || {};
            app.DEFAULTS[key] = app.DEFAULTS[key] || {};
            $.extend(app.DEFAULTS[key], merge || {});
		},
		getFlashVersion: function() {
			// ie
			try {
				try {
					// avoid fp6 minor version lookup issues
					// see: http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
					var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6');
					try { axo.AllowScriptAccess = 'always'; }
					catch(e) { return '6,0,0'; }
				} catch(e) {}
				return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
			// other browsers
			} catch(e) {
				try {
					if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
						return (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1];
					}
				} catch(e) {}
			}
			return '0,0,0';
		},
		hasFlash: function() {
			return app.helpers.getFlashVersion().split(',').shift() >= app.flash.minMajorVer;
		},
        getFlashObj: function getFlashObj(movie) {
            if (window.document[movie]) {
                return window.document[movie];
            }
            if (navigator.appName.indexOf("Microsoft Internet") == -1) {
                if (document.embeds && document.embeds[movie]) {
                    return document.embeds[movie];
                }
            } else {
                return document.getElementById(movie);
            }
        }
    },
    pagetype: function () {
        $(function () {
            app.pagetype = $('body').attr('id');
        });
    } (),
    pagetypes: {
        RESOURCES: "resources",
        PROFILE: "profile",
        JOBS: "jobs"
    },
    depends: function () {
        var i, j,
		    dependency,
		    dependencyCheck,
		    arr = arguments,
		    valid = true;
        if (typeof app.DEFAULTS === "undefined") {
            return false;
        }
        for (i = 0; i < arr.length; i++) {
            dependency = arr[i].split(".");
            dependencyCheck = app;
            for (j = 0; j < dependency.length; j++) {
                dependencyCheck = dependencyCheck[dependency[j]];
                if (typeof dependencyCheck === "undefined") {
                    return false;

                }
            }
        }
        return true;
    }
}

/* IE detection */
/*@cc_on
if (@_jscript_version == 5.7 && window.XMLHttpRequest)
    app.browser.IE7 = true;
else if (@_jscript_version == 5.6 || (@_jscript_version == 5.7 && !window.XMLHttpRequest))
    app.browser.IE6 = true;
app.browser.IE = true;
@*/

/* Chain */
/* Chain events and page states */
/*************************************************/

app.chain = {
    steps: function (stepsArray) {
        var that = {},
		    all = [];

        that.continueUntil = function () {
            var i, j = 0;

            // Keep enabling until a test fails
            // If test passes then enable next step
            // step 1 is always enabled
            while (all[j].testAllRules() && j + 1 < all.length) {
                j += 1;
                all[j].enable();
            };

            // Disable subsequent steps
            i = j + 1;
            for (i; i < all.length; i += 1) {
                all[i].disable();
            }
        };

        that.addStep = function (step) {
            step.steps = that;
            all.push(step);
        }

        that.addSteps = function (stepsArray) {
            var i = 0;
            for (i; i < stepsArray.length; i += 1) {
                that.addStep(stepsArray[i]);
            }
        }

        if (typeof stepsArray === 'object') {
            that.addSteps(stepsArray);
        }

        return that;
    }
};

/* Chain: Step */
/* A page state with defined rules */
/*************************************************/

app.chain.step = function (spec) {
    var that = {},
	    enabled,
	    rules = [], // Rules: Checked in sequence, if passes
	    $elements = typeof spec.css === 'string' ? $(spec.css) : [], // Elements related to the step, reference stored
	    enablePreFn = spec.enablePreFn || false,
	    enablePostFn = spec.enablePostFn || false,
	    disablePreFn = spec.disablePreFn || false,
	    disablePostFn = spec.disablePostFn || false,
	    forceTest = spec.forceTest || false, // Never use cached test results
	    omnitureEvent = spec.omniture || false;

    that.addRule = function (ruleSpec) {
        ruleSpec.step = that;
        rules.push(app.chain.rule(ruleSpec));
        return that;
    };

    that.testAllRules = function (force) {
        var i;
        if (rules.length < 1) {
            return true;
        }

        for (i = 0; i < rules.length; i += 1) {

            if (force || forceTest) {
                rules[i].test();
            }

            if (!rules[i].rulePassed()) {
                return false;
            }
        }
        return true;
    };

    that.testSingleRule = function (i) {
        return rules[i] && rules[i].test();
    };

    that.disable = function () {
        if (enabled || typeof enabled === 'undefined') {
            if (typeof disablePreFn === "function") {
                disablePreFn();
            }
            $elements.filter(':input').each(function () {
                this.disabled = true;
            }).addClass('disabledInput').end().hide();
            enabled = false;
            if (typeof disablePostFn == "function") {
                disablePostFn();
            }
        }
    }

    that.enable = function () {
        if (!enabled || typeof enabled === 'undefined') {
            if (typeof omnitureEvent === "object") {
                omnitureEvent.log();
            }
            if (typeof enablePreFn === "function") {
                enablePreFn();
            }
            $elements.filter(':input').each(function () {
                this.disabled = false;
            }).removeClass('disabledInput').end().show();
            enabled = true;
            if (typeof enablePostFn == "function") {
                enablePostFn();
            }
        }
    }

    return that;
}

/* Chain: rule */
/* A rule with defined listener */
/*************************************************/
app.chain.rule = function (spec) {
    var that = {},
	    passed,
	    step = spec.step || false,
	    fn = spec.rule,
	    el = spec.el,
	    listenerSpec = spec.listenerSpec || { events: spec.events} || false;

    if (typeof listenerSpec === 'object') {
        if (typeof listenerSpec.el === 'undefined') {
            listenerSpec.el = spec.el;
        }
        app.chain.listener(listenerSpec, that)
    }

    that.rulePassed = function () {
        return typeof passed === 'undefined' ? that.test() : passed;
    };

    that.test = function () {
        return passed = fn($(el));
    };

    that.getStep = function () {
        return step;
    }

    return that;
}

/* Chain: Listener */
/* On change, execute rule.test and go through chain */
/*************************************************/
app.chain.listener = function (spec, rule) {
    var fn = spec.fn || false, // Run post-test with test result passed in
	    el = spec.el || false,
	    events = spec.events || false,
	    rule = rule || false;

    $(el).live(events, function (evt) {
        if (spec.preventDefault) {
            evt.preventDefault();
        }

        if (typeof fn === "function") {
            fn(rule ? rule.test() : true, $(el), evt);
        } else if (typeof rule.test === "function") {
            rule.test();
        }

        // !! Enable/disable steps as required
        if (typeof rule !== "undefined") {
            rule.getStep().steps.continueUntil();
        }
    });
}


/* End chain */
/*************************************************/

/* Forms */
/*************************************************/

app.configure = function (options) {
    var options = options || {},
	    optionals = options.optionals || false,
	    dates = options.dates || false,
	    deletes = options.deletes || false,
	    keepAlive = options.keepAlive || false;

    if (optionals) {
        app.forms.optionals();
    }

    if (dates) {
        app.forms.dates();
    }

    if (deletes) {
        app.forms.deletes();
    }

    if (keepAlive) {
        app.forms.keepAlive();
    }
}

app.forms = {
    optionals: function ($scope) {
        var optionals = typeof $scope === "undefined" ? $('input.optional, textarea.optional') : $scope.find('input.optional, textarea.optional');

        optionals.each(function () {
            if ($(this).val().length > 0) {
                $(this).prev('label').find('span.placeholder').hide();
            }
        }).focus(function () {
            $(this).prev('label').find('span.placeholder').hide();
        }).blur(function () {
            if ($(this).val().length === 0) {
                $(this).prev('label').find('span.placeholder').css('display', 'inline');
            }
        });
    },
    dates: function () {
        $('div.date input').each(function () {
            if ($(this).val().length > 0) {
                $(this).prev('label').hide();
            }
        }).focus(function () {
            $(this).prev('label').hide();
        }).blur(function () {
            if ($(this).val().length === 0) {
                $(this).prev('label').css('display', 'inline');
            }
        });
    },
    deletes: function () {
        $('a.delete').live('click', function (evt) {
            return confirm(app.msg.deletes);
        });
    },
    keepAlive: function () {

        // Set timeout to Session length minus 5 mins, if no default, set to 25 mins
        var timeToListenFor = 5 * 60 * 1000,
		    triggerListenersDelay = app.DEFAULTS && app.DEFAULTS.sessionExpires ? app.DEFAULTS.sessionExpires - timeToListenFor : 25 * 60 * 1000;

        app.timeout = setTimeout("app.keepAlive()", triggerListenersDelay);

        // Check for user action, otherwise let session expire
        app.keepAlive = function () {
            app.sessionExpires = setTimeout("app.sessionExpiring()", timeToListenFor + 1);
            $('body').bind('click keyup', function () {
                // make call to stop session expiry if page has action
                $.ajax({
                    type: 'GET',
                    url: app.DEFAULTS.keepAliveUrl || '/application.session.keepalive.aspx',
                    dataType: 'json',
                    success: function (result) {
                        // on success, kill timeout
                        // if error - leave timeout and warning will still show.
                        app.timeout = setTimeout("app.keepAlive()", triggerListenersDelay);
                        clearTimeout(app.sessionExpires);
                    }
                });
                $('body').unbind();
            });
        };

        // Remove bind after session expires
        app.sessionExpiring = function () {
            $('body').unbind();
            $('h2').after('<p class="errorFlash"><strong>Warning</strong>: Your session has expired. This page has been left for longer than ' + ((triggerListenersDelay / 60 / 1000) + 5) + ' minutes, for security reasons anything entered on this page will not be saved.</p>');
        }
    }
}


/* Omniture */
app.analytics = {
    omniture: {
        events: {
            addJob: { name: "AddJob", event: "event81" },
            addLocation: { name: "AddLocation", event: "event83" },
            deleteJob: { name: "DeleteJob", event: "event82" },
            deleteLocation: { name: "DeleteLocation", event: "event84" }
        },

        setData: function (settings) {
            //console.log(this);
            var events = app.analytics.omniture.events;
            $.each(settings, function (i, val) {
                $(val.selector).data('omniture', events[val.key]);
            });
        }
    },

    event: function (spec) {
        var that = {},
	    	name = spec.name,
	    	s,
	    	logged = false;

        that.log = function (async) {
            var async = async || false;
            if (typeof s_gi === "function" && !logged) {
                var omnitureTL = function () {
                    s = s_gi('tslnewdev');
                    s.events = spec.event;
                    s.linkTrackEvents = spec.event;
                    s.linkTrackVars = spec.linkTrackVars || "events";
                    s.tl(this, 'o', name);
                };

                async ? setTimeout(omnitureTL, 100) : omnitureTL();

                logged = true;
            }
        }

        return that;
    },
    ga: {
        evt: function (category, action, label, value) {

            // defensive coding - analytics code may not be on page
            if (typeof _gaq !== "undefined") {
                if (typeof value === "string") {
                    value = parseFloat(value);
                }

                if (typeof value === "number" && !isNaN(value)) {
                    _gaq.push(['_trackEvent', category, action, label, value]);
                } else {
                    _gaq.push(['_trackEvent', category, action, label]);
                }
            }
        },
        page: function (url) {
            if (typeof _gaq !== "undefined") {
                _gaq.push(['_trackPageview', url]);
            }
        },
        userValue: function () {
            var scopes = {
                VISITOR: 1,
                SESSION: 2,
                PAGE: 3
            },
            // 5 allowed
				indexes = {
				    LOGGED_IN: 1,
				    SITE_SECTION: 2
				};

            return function (index, name, value, scope) {
                var index = typeof index === "number" ? index : indexes[index.toUpperCase()],
				    scope = scope ? scopes[scope.toUpperCase()] : scopes.PAGE;

                if (typeof _gaq !== "undefined" && typeof index === "number" && index > 0 && index < 6) {
                    _gaq.push(['_setCustomVar', index, name, value, scope]);
                }
            }
        } ()
    }
}

app.cookie = {
    create: function (name, value, days) {
        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            var expires = "; expires=" + date.toGMTString();
        }
        else var expires = "";
        document.cookie = name + "=" + value + expires + "; path=/";
    },
    read: 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;
    },
    erase: function (name) {
        app.cookie.create(name, "", -1);
    }
}


app.grammarize = {
    item: function (x, str) {
        // Assumes friendly plural
        var isAn = /^[aeiou]/ig.test(str) ? "an" : "a";
        return x === 1 ? isAn + " " + str : x + " " + str + "s";
    },
    join: function (arr) {
        var sentence = "",
		    i = 0;

        for (i; i < arr.length; i++) {
            if (i === 0) {
                sentence += arr[i];
            } else if (i === arr.length - 1) {
                sentence += " and " + arr[i] + ".";
            } else {
                sentence += ", " + arr[i];
            }
        }
        return sentence;
    },
    itemSentence: function (strArray) {
        var i = 0,
		    arr = [],
		    sentence = "",
		    deDuped = app.helpers.deDupe(strArray);

        for (str in deDuped.count) {
            arr.push(app.grammarize.item(deDuped.count[str], str));
        }
        return app.grammarize.join(arr);
    },
    sentence: function (strArray) {
        return app.grammarize.join(app.helpers.deDupe(strArray).arr);
    }
}


/* Specific JS */
/*************************************************/

app.general = {
    moreText: function () {

        /* Expand description */
        $('div.prose a.more').click(function (evt) {
            evt.preventDefault();
            $(this).hide().next('span').show();
        });
    },
    following: function () {
        /* Follow / unfollow action */
        if (app.DEFAULTS.LOGGED_IN) {
            $('.follow, .unfollow').click(function (evt) {
                $this = $(this);
                evt.preventDefault();

                var theData = {}, isFollow = $this.hasClass('follow');
                theData[isFollow ? 'follow' : 'unfollow'] = $this.data('ac');

                $this.hide().after(app.html.inlineIndicator);
                $.ajax({
                    url: app.DEFAULTS.JSON.FOLLOW_URL,
                    cache: false,
                    data: theData,
                    success: function (data) {
                        if (data && data.valid) {
                            $this
										.next()
										.remove()
										.end()
										    .blur()
											.toggleClass('follow unfollow')
											.html(isFollow ? 'Unfollow' : 'Follow')
											.attr('title', isFollow ? 'Remove from following' : "We'll tell you when this person uploads new resources")
											.show();
                        } else {
                            error();
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        error();
                    }
                });

                function error() {
                    app.helpers.ajaxError();
                    $this.next().remove().end().show();
                }
            });
        }
    }
}

app.resources = {
    reviews: function () {

        /* Expand reviews */
        if ($('table.reviews').present()) {
            $('table.reviews .review p a').click(function (evt) {
                var parent = $(this).parents('tr');
                evt.preventDefault();

                if (parent.hasClass('min')) {
                    $(this).attr('title', 'Hide comment');
                    parent.removeClass('min').addClass('max');
                } else {
                    $(this).attr('title', 'Show full comment');
                    parent.removeClass('max').addClass('min');
                }
            });
        }

        /* Expand classifications */
        if ($('.classifications').present() && $('.classifications li').length > app.DEFAULTS.CLASSIFICATIONS_VISIBLE) {
            var classifications = $('.classifications li').slice(app.DEFAULTS.CLASSIFICATIONS_VISIBLE),
			    more = $('<li><a href="#classifications" class="jsControl more">More classifications&hellip;</a></li>');

            classifications.hide();
            $('.classifications').append(more).find('a.jsControl').click(function (evt) {
                evt.preventDefault();
                classifications.show();
                more.hide();
            });
        }

        /* Hide and show Add review field, Validate on submit */
        if (app.DEFAULTS.LOGGED_IN && $('.addReview').present()) {
            app.forms.optionals($('.addReview'));
            $('.addReviewButton').click(function (evt) {
                evt.preventDefault();
                $(this).parent().hide();
                $('.addReview').show();
            });
            $('.addReview a.cancel').click(function (evt) {
                evt.preventDefault();
                $('.addReviewButton').parent().show();
                $('.addReview').hide();
            });

            $('.addReview form').submit(function (evt) {
                var rating = $('.addReview select');
                if (rating.val() == app.DEFAULTS.EMPTY) {
                    evt.preventDefault();
                    $('.addReview').addClass('isError').find('p.errorFlash').show();
                    rating.change(function () {
                        $('.addReview').removeClass('isError').find('p.errorFlash').hide();
                        rating.unbind('change');
                    });
                }
            });
        }
    },
    audit: function () {
        var setAuditSaveButton = function () {
            $('.saveAudit').toggle(-1 != $('.auditValues option:selected').val());
        };
        $('.auditValues').change(function () {
            setAuditSaveButton();
        });
        setAuditSaveButton();
    },
    preview: function () {

        var $preview = $('#preview'),
			embeds = (function () {
			    var $embeds = $('.embeds, .ad'),
					toggle = $embeds.present() ? function (str) {
					    $embeds.css('visibility', str);
					} : function () { };

			    return {
			        show: app.helpers.curry(toggle, "visible"),
			        hide: app.helpers.curry(toggle, "hidden")
			    };
			})(),
			noFlash = '<h3 class="alignCenter">This preview requires Adobe Flash Player</h3><p class="alignCenter">Install the latest version:<br /><br /><a id="getFlash" href="http://www.adobe.com/go/getflashplayer" target="_blank"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>',
			incrementCounter = function (fileid) {
			    if (app.depends("DEFAULTS.JSON.COUNT_URL")) {
			        $.ajax({
			            url: app.DEFAULTS.JSON.COUNT_URL,
			            cache: false,
			            data: { file: fileid },
			            error: function (XMLHttpRequest, textStatus, errorThrown) {
			            }
			        });
			    }
			};

        /* Window actions */
        $(window).bind('resize scroll', function () {
            if ($preview.is(":visible")) {
                $preview.dialog("option", "position", "center");
            }
        });

        // dialog-extend options for maximize/restore mode
        var dialogExtendOptions = {
            "maximize": true,
            "minimize": false,
            "dblclick": false,
            "titlebar": false,
            "events": {
                "restore": function (a, b) {
                    $preview.dialog("option", "position", "center");
                }
            }
        };

        $preview.dialog({
            width: 80,
            height: 80,
            modal: true,
            draggable: false,
            resizable: true,
            autoOpen: false,
            title: "",
            dialogClass: 'previewWindow',
            open: function () {
                embeds.hide();
                $preview.show();
            },
            close: function () {
                $preview.hide();
                if ($preview.data("dialog-state") == "maximized") {
                    $preview.dialogExtend("restore");
                }
                $preview.dialog('option', { width: 80, height: 80, title: "", position: "center" })
						.parent('.ui-dialog').find('.ui-dialog-titlebar .playAgain').remove();

                swfobject.removeSWF("swfobjectHolder");
                embeds.show();
            }
        }).dialogExtend(dialogExtendOptions);


        $('a.preview').click(function (evt) {
            if (!this.href.match(/\.swf$/i)) {
                return true;
            }

            evt.preventDefault();

            var that = this,
				width = $(that).data('width') || 800,
				height = $(that).data('height') || 600;

            if (app.browser.IE6) {
                window.open(that.href, '_blank', 'directories=0,location=0,menubar=0,status=0,titlebar=0,toolbar=0,resizable=1');
                return;
            }

            // load library
            typeof swfobject === "undefined" ? $.getScript('http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js', function () { populate() }) : populate();

            // create flash embed/object
            function loadSWF(wait, callbackfn) {
                wait = wait || 10;
                callbackfn = callbackfn || null;
                $preview.append('<div id="swfobjectHolder"></div>');
                window.setTimeout(function () {
                    swfobject.embedSWF(that.href, "swfobjectHolder", "100%", "100%", "7.0.0", null, null, null, null, callbackfn);
                }, wait);
            }

            // start to fetch flash
            function populate() {
                incrementCounter($(that).data('file'));

                if (swfobject.hasFlashPlayerVersion("7.0.0")) {
                    $preview.parent('.previewWindow').addClass('loading');
                    $preview.dialog('open');
                    loadSWF(500, populateDone);
                } else {
                    $preview.dialog("option", { width: 370, height: 160 });
                    $preview.html(noFlash);
                    $('#getFlash').click(function () {
                        $preview.dialog('close');
                    });
                    $preview.dialog('open');
                }

            }

            // when flash is loaded
            function populateDone(e) {
                $preview.parent('.previewWindow')
							.removeClass('loading')
							.end()
						.dialog('option', { width: width, height: height, position: 'center', title: 'Playing: ' + $(that).data('title') })
						.parent('.ui-dialog').find('.ui-dialog-titlebar').append('<a href="#" class="playAgain sprite formSprite">Play again</a>');

                // on play again
                $('.previewWindow a.playAgain').click(function (evt) {
                    evt.preventDefault();
                    $(this).blur();

                    incrementCounter();
                    swfobject.removeSWF("swfobjectHolder");
                    loadSWF();
                });
            }
        });
    },
    analytics: {
        name: "Resource detail",
        actions: ["Expand classifications", "Expand comment", "Expand rate and review", "Submit rating and review", "Download resource"],
        init: function () {
            try {
                var that = this;
                page = $('#content h1').text();

                // expand classifications
                $('.classifications a.more').live('click', function () {
                    app.analytics.ga.evt(that.name, that.actions[0], page);
                });

                // open comment
                $('.max td.review p a').live('click', function () {
                    app.analytics.ga.evt(that.name, that.actions[1], page);
                });

                // open rate and review
                $('a.addReviewButton').live('click', function () {
                    app.analytics.ga.evt(that.name, that.actions[2], page);
                });

                // download resource
                $('.itemsContainer a').live('click', function (evt) {
                    var loggedIn = app.DEFAULTS && app.DEFAULTS.LOGGED_IN,
					    item = $(this).parent().text().trim().split(/\n/);
                    for (var i = 0, l = item.length; i < l; i++) {
                        item[i] = item[i].trim();
                    }
                    item = item.join(': ');

                    if (loggedIn) {
                        app.analytics.ga.page($(this).attr('href'));
                    }
                    app.analytics.ga.evt(that.name, that.actions[4], item, loggedIn ? 1 : 0);
                });

                // submit form, value = rating given
                $('.addReview form').live('submit', function () {
                    app.analytics.ga.evt(that.name, that.actions[3], page, $(this).find('select').val());
                });

            } catch (exp) {
                //nothing
            }
        }
    }
}

app.jobs = {
    postcode: function () {
        var form = $('form.postcode'),
		    input = form.find('.sliderValue'),
		    display = $('<div class="sliderDisplay clearfix"><b>Max distance:</b> <strong>' + input.val() + ' miles </strong></div>'),
		    div = $('<div>').slider({
		        value: parseFloat(input.val()),
		        animate: true,
		        range: 'min',
		        step: 10,
		        min: 10,
		        max: 100,
		        slide: function (evt, ui) {
		            input.val(ui.value);
		            display.html('<b>Max distance:</b> <strong>' + ui.value + ' miles </strong>');
		        }
		    });
        $('form.postcode').find('.sliderValue').after(div).after(display);
    },
    savedSearches: function () {
        var $searches = $('.savedSearches li'),
		    z = 1000;
        $searches.each(function () {
            var $that = $(this),
			    $changeAlert = $that.find('.changeAlert'),
			    $current = $changeAlert.find(' > a'),
					$eleUL;

            /* Setup */
            $that.css('z-index', z--);
						$eleUL = $("<ul>").appendTo($changeAlert);
            $that.find('option').each(function () {
                var li = $('<li><a href="#' + $(this).val() + '">' + $(this).text() + '</a></li>').data('option', $(this).val());
                $eleUL.append(li);
            });
            //$changeAlert.append('<ul><li><a href="#0">Daily</a></li><li><a href="#1">Weekly</a></li><li><a href="#2">Turn off</a></li></ul>')

            /* Open */
            $current.click(function (evt) {
                evt.preventDefault();
                resetChange();
                var parent = $(this).parent();
                parent.addClass('openChangeAlert');
                $changeAlert.attr('style', '');
            });

            /* Change */
            $changeAlert.find('ul a').click(function (evt) {
                var old = $current.html();
                evt.preventDefault();

                //set form element
                $that.find('select').val($(this).parent().data('option'));
                $current.html($(this).text() + '<span class="disclosureWhite sprite">Change</span>').append(app.html.inlineIndicator).find('span').hide();

                if (!app.depends("DEFAULTS.JSON.SAVED_SEARCH_UPDATE_URL")) {
                    $that.find('form').submit();
                } else {
                    $.ajax({
                        url: app.DEFAULTS.JSON.SAVED_SEARCH_UPDATE_URL,
                        data: $that.find('form').serialize(),
                        success: function (result) {
                            if (result.valid) {
                                $current.find('span').show();
                                $current.find('img').remove();
                                resetChange();

                                $changeAlert.css({ 'background-color': '#54a954' });
                                setTimeout(function () {
                                    $changeAlert.attr('style', '').effect('highlight', { color: '#54a954' }, 500);
                                }, 1500);
                            } else {
                                error();
                            }
                        },
                        error: function () {
                            error();
                        }
                    });
                }

                function error() {
                    resetChange();
                    app.helpers.ajaxError();
                    $current.html(old);
                    $current.find('span').show();
                    $current.find('img').remove();
                }
            });

        });

        $('.savedSearches a.deleteButton, .myJobs a.deleteButton').click(function (evt) {
            evt.preventDefault();
            $this = $(this);
            $list = $this.parents('ul');
            isSavedSearch = $list.hasClass('savedSearches');
            if (confirm(isSavedSearch ? app.msg.deletes : "Are you sure you want to delete this application?\nDeleting this application will not withdraw your application.")) {

                $this.hide().after(app.html.inlineIndicator);
                var lastItem = $list.children('li:not(.empty)').length === 1;
                var theData = {};
                theData[isSavedSearch ? 'savedSearchJob' : 'savedJob'] = 'delete';
                theData.id = $this.data('id');
                 $.ajax({
                    url: isSavedSearch ? app.DEFAULTS.JSON.SAVED_SEARCHES_JOBS_DELETE_URL : app.DEFAULTS.JSON.SAVED_JOBS_DELETE_URL,
                    data: theData,
                    success: function (result) {
                        if (result && result.valid) {
                            $this.parents('li').fadeThenSlideAndRemove(function () {
                                if (lastItem) {
                                    $list.find('li.empty').fadeIn(300);
                                }
                            });
                            if (lastItem) {
                                $('#emailAlerts').fadeThenSlideAndRemove();
                            }
                        } else {
                            error();
                        }
                    },
                    error: function () {
                        error();
                    }
                });

                function error(msg) {
                    app.helpers.ajaxError();
                    $this.next().remove().end().show();
                }
            }
        });

        $('body').click(function (event) {
            if (!$(event.target).is('.changeAlert, .changeAlert a')) {
                resetChange();
            }
        });

        function resetChange() {
            $('.openChangeAlert').removeClass('openChangeAlert');
        }
    },
    detail: function () {
        $('a.video').click(function () {
			if (!app.helpers.hasFlash()) {
				if (confirm('To see this video you need to install/update your Adobe Flash Player from http://get.adobe.com/flashplayer/\nWould you like to be redirected now?')) {
					window.top.location = "http://get.adobe.com/flashplayer/";
				}
				return false;
			}

            $.fancybox({
                'padding': 0,
                'autoScale': false,
                'transitionIn': 'none',
                'transitionOut': 'none',
                'title': this.title,
                'width': 640,
                'height': 385,
                'href': this.href.replace(new RegExp("watch\\?v=", "i"), 'v/'),
                'type': 'swf',
                'swf': {
                    'wmode': 'transparent',
                    'allowfullscreen': 'true'
                }
            });

            return false;
        });
    },
    talentBank: function () {
        $('.leaveBank').live('click', function () {
            return confirm("Are you sure you want to leave the talent bank? All talent bank information will be deleted.");
        });
    },
    talentBankEdit: function () {
        var $addAnother = $('.addAnother a'),
        	$jobs = $('fieldset.nextJob'),
        	$locations = $('fieldset.locations'),
			jobCount = getJobCount(),
			locationCount = getLocationCount(),
			curry = app.helpers.curry,
			ga = {
			    actions: [],
			    track: curry(app.analytics.ga.evt, "Jobs", "Talent Bank")
			};

        // Analytics helpers
        ga.addJob = curry(ga.track, "Add job");
        ga.deleteJob = curry(ga.track, "Delete job");
        ga.deleteCV = curry(ga.track, "Delete CV");
        ga.addLocation = curry(ga.track, "Add location");
        ga.deleteLocation = curry(ga.track, "Delete location");

        // Add another
        $addAnother.click(function (evt) {
            evt.preventDefault();
            $(document).trigger('talentBank.addAnother', [$(this).parents('fieldset'), $(this)]);
        });

        // Update account details warning
        $('.updateAccount').live('click', function () {
            return confirm("Any unsaved changes to this form will be lost, do you want to continue?");
        });

        // Delete
        $('.nextJob a.deleteButton, .locations a.deleteButton').live('click', function (evt) {
            var isLocation = $(this).parents('fieldset').hasClass('locations');

            evt.preventDefault();
            if (confirm(app.msg.deletes)) {

                // doesn't fade correctly in IE
                if (app.browser.IE) {
                    $(this).parent().css('visibility', 'hidden');
                }

                $(this).parent().fadeThenSlideAndRemove(function () {
                    isLocation ? ga.deleteLocation() : ga.deleteJob();
                    $addAnother.parent().show();
                    configure();
                });

                var omniture = $(this).data('omniture');
                if (typeof omniture === "object") {
                    app.analytics.event(omniture).log(true);
                }
            }
        });


        // CV
        $('.cv a.deleteButton').live('click', function (evt) {
            evt.preventDefault();
            if (confirm(app.msg.deletes)) {
                ga.deleteCV();
                $(this).parent().fadeOut(function () {
                    $('#talentBankAttachmentDeleted').val(1);
                    $('.cv.upload').fadeIn();
                });
            }
        });

        $('input.file').bind('change', function (evt) {
            if (validateCV()) {
                $('.upload').removeClass('error');
                // $('.upload.liteError').remove();
                removeGlobalError('errCV');
            }
            else {
                //$('.upload').append('<p class="liteError">Hm!!!</p>');
                // add error below box if not there yet
            }
        });

        $('select.regionLocation').live('change', function (evt) {
            $(document).trigger('talentBank.locationChange', [$(this)]);
        });

        $(document).bind('talentBank.addAnother', function (evt, $fieldset, $addAnother) {
            var cloneSource = $addAnother.parent().prev(),
				clone = cloneSource.clone(),
            	isLocation = $fieldset.hasClass('locations'),
            	count = isLocation ? locationCount : jobCount;
            omniture = $addAnother.data('omniture');

            cloneSelectedValues(cloneSource, clone);
            cloneSetUniqueValues(clone, count);
            clone.hide();
            clone.removeClass('error').find('.error').removeClass('error');
            $addAnother.parent().before(clone);
            clone.fadeIn(500);
            clone.find('select').eq(0).focus();

            // TODO: Refactor
            app.analytics.omniture.setData([isLocation ? { selector: 'fieldset.locations .location a.deleteButton:last', key: "deleteLocation"} :
                                                          { selector: 'fieldset.nextJob .job a.deleteButton:last', key: "deleteJob"}]);

            $(document).trigger('talentBank.enableDelete', [$fieldset]);

            if (isLocation) {
                locationCount++;
                ga.addLocation();
            } else {
                jobCount++;
                ga.addJob();
            }

            configure();

            if (typeof omniture === "object") {
                app.analytics.event(omniture).log(true);
            }
        });

        $(document).bind('talentBank.limitReached', function (evt, $fieldset) {
            $fieldset.find('.addAnother').hide();
        });

        $(document).bind('talentBank.disableDelete', function (evt, $fieldset) {
            $fieldset.find('.deleteButton').fadeOut(200);
        });

        $(document).bind('talentBank.enableDelete', function (evt, $fieldset, fade) {
            var fade = fade || 200;
            $fieldset.find('.deleteButton:hidden').fadeIn(fade);
        });

        $(document).bind('talentBank.locationChange', function (evt, $select) {
            var location = $select.parents('.location');
            location.find('select.la').hide().val(app.DEFAULTS.EMPTY);
            var $subLoc = location.find('[data-parent=' + $select.val() + ']');
            location.find('label.subLocationLabel').toggle($subLoc.present());
            $subLoc.fadeIn(500);
        });


        $(document).bind('talentBank.editInit', function (evt) {
            // If there are jobs and locations in a JSON object then populate blocks
            if (typeof app.DEFAULTS.TALENTBANKJOBSLOCATIONS !== "undefined") {

                jobCount = loadBlocks({
                    data: app.DEFAULTS.TALENTBANKJOBSLOCATIONS.jobs,
                    fieldset: "nextJob",
                    block: "job",
                    workingFunc: function (workingItem, dataItem) {
                        workingItem.find('.career select').val(dataItem.career);
                        workingItem.find('.workplace select').val(dataItem.workplace);
                        workingItem.find('.subject select').val(dataItem.subject);
                    }
                });

                locationCount = loadBlocks({
                    data: app.DEFAULTS.TALENTBANKJOBSLOCATIONS.locations,
                    fieldset: "locations",
                    block: "location",
                    workingFunc: function (workingItem, dataItem) {
                        workingItem.find('.regionLocation').val(dataItem.location);
                        workingItem.find('select.la').hide().val(app.DEFAULTS.EMPTY);
                        var $subLoc = workingItem.find('select[data-parent=' + dataItem.location + ']');
                        $subLoc.val(dataItem.sublocation === null ? 0 : dataItem.sublocation).show();
                        workingItem.find('label.subLocationLabel').toggle($subLoc.present());
                    }
                });

                configure();
            }
        });



        function setOmniture() {
            app.analytics.omniture.setData([{ selector: 'fieldset.nextJob .addAnother a', key: "addJob" },
                                            { selector: 'fieldset.locations .addAnother a', key: "addLocation" },
                                            { selector: 'fieldset.locations .location a.deleteButton:hidden', key: "deleteLocation" },
                                            { selector: 'fieldset.nextJob .job a.deleteButton::hidden', key: "deleteJob"}]);
        }

        /* Clone helper functions */
        function cloneSetUniqueValues(clone, suffix) {
            clone.find('[id]').each(function () {
                $(this).attr('id', this.id.replace(/\-[0-9]+/, "") + '-' + suffix);
            });

            clone.find('[name]').each(function () {
                $(this).attr('name', this.name.replace(/\-[0-9]+/, "") + '-' + suffix);
            });

            clone.find('[for]').each(function () {
                $(this).attr('for', $(this).attr('for').replace(/\-[0-9]+/, "") + '-' + suffix)
            });
        }

        function cloneBlock($firstBlockItem, $addAnotherBlock, idx) {
            // First item
            if (idx === 0) {
                return $firstBlockItem;
            } else {
                var clone = $firstBlockItem.clone();
                cloneSetUniqueValues(clone, idx);
                $addAnotherBlock.before(clone);
                return clone;
            }
        }

        function cloneSelectedValues($cloneSource, $clone) {
            var selects = $cloneSource.find("select");
            $(selects).each(function (i) {
                var select = this;
                $clone.find("select").eq(i).val($(select).val());
            });
        }

        function loadBlocks(config) {
            var count = config.data.length,
                $first = $('fieldset.' + config.fieldset + ' .' + config.block + ':first'),
                $addAnother = $('fieldset.' + config.fieldset + ' .addAnother');

            $.each(config.data, function (idx, dataItem) {
                var htmlBlock = cloneBlock($first, $addAnother, idx);
                config.workingFunc(htmlBlock, dataItem);
            });

            return count;
        }

        /* Validate form */
        $('#content form.standard').submit(function () {
            var ok = true,
                jobsOk = true,
                locationsOk = true,
                errorTemplates = {
                    errJobs: 'One or more jobs are incomplete.',
                    errLocations: 'One or more locations are incomplete.',
                    errCV: 'CV file type not accepted.'
                },
                errorMsgs = [],
                errorPanel = $('<ul class="errorFlash"></ul>');

            // Jobs validation
            $('.nextJob .job').each(function () {
                var workplace = $(this).find('.workplace select'),
				 	career = $(this).find('.career select'),
				 	jobOk = true;

                if (career.val() == app.DEFAULTS.EMPTY) {
                    jobOk = false;
                    career.prev().addClass('error');
                }

                if (workplace.val() == app.DEFAULTS.EMPTY) {
                    jobOk = false;
                    workplace.prev().addClass('error');
                }

                if (!jobOk) {
                    jobsOk = false;
                    $(this).addClass('error');
                }
            });

            if (!jobsOk) {
                errorMsgs.push('errJobs');
            }

            // Location validation
            $('.locations .location').each(function () {
                var location = $(this).find('.regionLocation'),
					subLocation = $(this).find('.la:visible'),
				 	locationOk = true;

                if (location.val() == app.DEFAULTS.EMPTY) {
                    locationOk = false;
                    location.prev().addClass('error');
                }

                if (!locationOk) {
                    locationsOk = false;
                    $(this).addClass('error');
                }
            });

            if (!locationsOk) {
                errorMsgs.push('errLocations');
            }

            // CV validation
            if (!validateCV()) {
                $('.upload').addClass('error');
                errorMsgs.push('errCV');
            }

            // Any error on form?
            ok = errorMsgs.length === 0;

            // Display errors if any            
            if (!ok) {
                $.each(errorMsgs, function (idx, item) {
                    errorPanel.append($('<li class="' + item + '">' + errorTemplates[item] + '</li>'));
                });

                $('.errorFlash').remove();
                $('fieldset.submit').prepend(errorPanel);
            } else {

                setJobsAndLocationsForPOST();
            }

            return ok;
        });

        /* Live validation update */
        $('.error select').live('change', function () {
            if ($(this).val() != app.DEFAULTS.EMPTY) {
                $(this).prev().removeClass('error');
                if ($(this).is('.la')) {
                    $(this).parents('div.location').find('label').removeClass('error');
                }
            }
            if (!$(this).parents('.error').find('label.error').present()) {
                $(this).parents('.error').removeClass('error');
                if (!$('.job.error').present()) {
                    removeGlobalError('errJobs');
                }
                if (!$('.location.error').present()) {
                    removeGlobalError('errLocations');
                }
            }
        });

        function setJobsAndLocationsForPOST() {
            // Get JSON object for jobs and locations for saving
            $('#talentBankJobsLocations').val(JSON.stringify(getJobsAndLocationsJSON()));
        }

        function getJobsAndLocationsJSON() {
            // Create JSON object
            var talentBankJobsLocations = {
                jobs: [],
                locations: []
            };

            $('fieldset.nextJob .job').each(function (i, elm) {
                talentBankJobsLocations.jobs[i] = {
                    career: $(elm).find('.career select').val(),
                    workplace: $(elm).find('.workplace select').val(),
                    subject: $(elm).find('.subject select').val()
                };
            });

            $('fieldset.locations .location').each(function (i, elm) {
                var subLocation = $(elm).find('.la:visible');

                talentBankJobsLocations.locations[i] = {
                    location: $(elm).find('.regionLocation').val(),
                    sublocation: subLocation.present() && subLocation.val() != 0 ? subLocation.val() : null
                };
            });

            return talentBankJobsLocations;
        }

        function validateCV() {
            var cv = $('input.file').val().trim();
            if (cv.length != 0) {
                var extension = cv.split('.');
                return extension.length >= 1 && extension[extension.length - 1].match(app.DEFAULTS.CV_FILE_TYPES) != null;
            }
            return true;
        }

        function removeGlobalError(error) {
            var errorSelector = '.' + error;
            var errorPanel = $('fieldset.submit .errorFlash');
            if (errorPanel.length > 0) {
                if (errorPanel.has(errorSelector).length > 0) {
                    if (errorPanel.children().length === 1) {

                        // If we're submiting the form don't bother in removing error panel
                        var saveClicked = (typeof event !== "undefined" &&
											event !== null &&
											typeof event.toElement !== "undefined" &&
											event.toElement !== null &&
											event.toElement.value === 'Save');

                        if (!saveClicked) {
                            errorPanel.remove();
                        }
                    }
                    else {
                        errorPanel.children(errorSelector).remove();
                    }
                }
            }
        }

        function getJobCount() {
            return $('.nextJob .boxed').length - 1;
        }

        function getLocationCount() {
            return $('.locations .boxed').length - 1;
        }

        function configure() {
            switch (getJobCount()) {
                case (1):
                    $(document).trigger('talentBank.disableDelete', [$jobs]);
                    break;
                case (app.DEFAULTS.JOB_LIMIT || 10):
                    $(document).trigger('talentBank.limitReached', [$jobs]);
                    // No break, fall through default!
                default:
                    $(document).trigger('talentBank.enableDelete', [$jobs, 0]);
                    break;
            }

            switch (getLocationCount()) {
                case (1):
                    $(document).trigger('talentBank.disableDelete', [$locations]);
                    break;
                case (app.DEFAULTS.LOCATION_LIMIT || 5):
                    $(document).trigger('talentBank.limitReached', [$locations]);
                    // No break, fall through default!
                default:
                    $(document).trigger('talentBank.enableDelete', [$locations, 0]);
                    break;
            }
        }

        $(document).trigger('talentBank.editInit');
        setOmniture();
    }
}

app.funnel = {
    rollups: function () {
        var rollups = $('.rollup');
        rollups.each(function () {
            var $that = $(this);
            $that.find('> a').click(function (evt) {
                evt.preventDefault();
                $that.find('ul').toggle();
            });
        });
    }
}

app.listing = {
    filters: function () {
        var filterBarContainer = $('.filterBarContainer'),
		    filterBar = $('.filterBar'),
		    filterOffset = filterBar.offset().top,
		    footerOffset = $('#footer').offset().top,
		    footerHeight = $('#footer').innerHeight(),
		    fixed = false,
		    moreFilters = {
		        threshold: 13,
		        leaveBehind: 10,
		        twoColumnThreshold: 26
		    };

        /* Hide and show filters */
        $('.filters h3').each(function () {
            $(this).html('<a href="#" class="jsControl"><span class="disclosure"></span> ' + $(this).text() + '</a>');
        }).find('a').click(function (evt) {
			evt.preventDefault();
			var $currentLI = $(this).parents('li');
			$currentLI.addClass('active');
			if (!$currentLI.hasClass('manual')) {
				$('.filters li.selected:not(".active"):not(".manual")').removeClass('selected');
			}
			$currentLI.toggleClass('selected').removeClass('active');
            if (fixed) {
                hitBottom();
            }
        });

        /* More filters */
        $('.filters ul ul').each(function () {
            var list = $(this).find('li'),
			    more,
			    filterExpand,
			    col1,
			    col2,
			    wrapper;

            if (list.length > moreFilters.threshold - 1) {
                filterExpand = $('<div class="filterExpand dropDown" style="display: none"></div>');
                more = list.slice(moreFilters.leaveBehind).remove();
                $(this).append('<li><a href="#" class="more jsControl">More&hellip;</a></li>').after(filterExpand);
                if (list.length > moreFilters.twoColumnThreshold) {
                    col1 = $('<ul class="g"></ul>').prepend(more.slice(0, more.length / 2));
                    col2 = $('<ul class="g"></ul>').prepend(more.slice(more.length / 2));
                    wrapper = $('<div class="wrapper"></div>').append(col1).append(col2);
                    filterExpand.addClass('col2').append(wrapper);
                } else {
                    filterExpand.addClass('col1').append($('<ul class="g"></ul>').prepend(more));
                }
            }
        });

        $('.filters a.more').click(function (evt) {
            var moreFilters = $(this).parents('ul').next();

            evt.preventDefault();
            if (moreFilters.is(':visible')) {
                resetFilterExpand();
            } else {
                $(this).addClass('moreSelected').parents('ul').next().show();
            }
        });

        $('body').click(function (evt) {
            if (!$(evt.target).is('a.more, .filterExpand, .filterExpand a, .filterExpand li, .filterExpand .wrapper')) {
                resetFilterExpand();
            };
        });

        $('.filters a.more, .filterExpand').keyup(function (evt) {
            if (evt && evt.keyCode === app.keys.ESC) {
                resetFilterExpand();
            }
        });

        function resetFilterExpand() {
            $('.filterExpand').hide();
            $('.filters a.more').removeClass('moreSelected');
        }


        if (!app.browser.IE6 && !app.browser.IE7) {
            filterBarContainer.append('<div class="g12 fixedSpace fixedBarSpace">&nbsp;</div><div class="g3 fixedSpace">&nbsp;</div>');

            function fixFilters() {
                if (($(window).scrollTop() - filterOffset) > 0) {
                    if (!fixed) {
                        fixed = true;
                        filterBarContainer.addClass('fixedFilterBar');
                        filterBar.css({ top: 0 });
                    } else {
                        hitBottom();
                    }
                } else {
                    if (fixed) {
                        fixed = false;
                        filterBarContainer.removeClass('fixedFilterBar')
                        filterBar.css({ top: 'auto' });
                    }
                }
            }

            function hitBottom() {
                if (fixed) {
                    if (($(window).scrollTop() + filterBar.innerHeight()) - footerOffset > 0) {
                        filterBar.addClass('hitBottom').css({ top: 'auto', bottom: footerHeight + 'px' });
                    } else {
                        filterBar.removeClass('hitBottom').css({ top: '0', bottom: 'auto' });
                    }
                }
            }

            /* Fixed filter */
            fixFilters();
            $(window).scroll(function () {
                fixFilters();
            });
        }
    },
    favouriting: function () {
        var items = $('.resources li, .jobs li');

        items.each(function () {
            var t;
            $(this).hover(function () {
                clearTimeout(t);
                $(this).addClass('hover');
            }, function () {
                var that = $(this);
                t = setTimeout(function () {
                    that.removeClass('hover').find('.newlyFaved').removeClass('newlyFaved').blur();
                }, 200);
            });

            /* Click fave star */
            if (app.DEFAULTS.LOGGED_IN) {

                $(this).find('a.fave, a.undo').live('click', function (evt) {

                    if (app.depends("DEFAULTS.JSON.ADD_FAVOURITE", "DEFAULTS.JSON.REMOVE_FAVOURITE")) {
                        evt.preventDefault();
                    } else {
                        return true;
                    }

                    var that = $(this).is('.undo') ? $(this).parents('li').find('a.fave') : $(this),
					    isFave = that.parents('li.favourite').present(),
					    parent = that.parent(),
					    isResource = that.parents('ul.resources').present(),
					    isJob = !isResource && that.parents('ul.jobs').present(),
					    item = that.parents('li'),
					    slug = item.find('.slug'),
					    count = $('.bar .count span'),
					    msgs = {};

                    if (isJob) {
                        msgs.added = "Saved to My jobs";
                        msgs.add = "Save to My jobs";
                        msgs.remove = "Remove from My jobs";
                    } else if (isResource) {
                        msgs.added = "My favourite";
                        msgs.add = "Add to favourites";
                        msgs.remove = "Remove from favourites";
                    }

                    that.hide().after(app.html.inlineIndicator);

                    /* Making favourite */
                    if (!isFave) {
                        that.addClass('newlyFaved').removeClass('newlyRemoved');
                        $.ajax({
                            url: app.DEFAULTS.JSON.ADD_FAVOURITE,
                            data: { item: item.attr('id') },
                            success: function (result) {
                                if (result && result.valid) {
                                    item.toggleClass('favourite');

                                    if (app.pagetype === app.pagetypes.RESOURCES && $('body').hasClass('myFavourites')) {
                                        item.find('.fader').remove();

                                        if (count.present()) {
                                            var i = parseInt(count.text());

                                            if (i === 0) {
                                                $('.bar .count').html('<span>1</span> resource');
                                            } else if (i === 1) {
                                                $('.bar .count').html('<span>2</span> resources');
                                            } else {
                                                count.text(i + 1);
                                            }
                                        }
                                    }

                                    var $slug;
                                    if (slug.length === 0) {
                                        $slug = $('<p class="slug"><span class="myFave">' + msgs.added + '</span></p>').hide();
                                        if (item.find('h4').present()) {
                                            item.find('h4').before($slug);
                                        } else {
                                            item.prepend($slug);
                                        }
                                        $slug.slideDown(200);
                                    } else {
                                        slug.prepend('<span class="myFave">' + msgs.added + '</span><span class="mdash"> &mdash; </span>');
                                    }

                                    that.find('span').attr('title', msgs.remove).text(msgs.remove);
                                    that.show().focus();


                                    parent.find('img').remove();
                                } else {
                                    error(result ? result.msg : app.msg.error);
                                }
                            },
                            error: function () {
                                error();
                            }
                        });

                        /* Removing from favourites */
                    } else {
                        $.ajax({
                            url: app.DEFAULTS.JSON.REMOVE_FAVOURITE,
                            data: { item: item.attr('id') },
                            success: function (result) {
                                if (result && result.valid) {

                                    item.toggleClass('favourite');

                                    if (!item.find('.mdash').present()) {
                                        if (!$('body').hasClass('myFavourites')) {
                                            slug.slideUp(200, function () {
                                                slug.remove();
                                            });
                                        } else {
                                            slug.remove();
                                        }
                                    } else {
                                        item.find('.myFave, .mdash').remove();
                                    }
                                    that.find('span').attr('title', msgs.add).text(msgs.add);
                                    that.removeClass('newlyFaved').show().focus();

                                    if (app.pagetype === app.pagetypes.RESOURCES && $('body').hasClass('myFavourites')) {
                                        //different action on myfaves
                                        var fader = $('<div class="fader"><p class="flash">Resource removed. <a href="#undo" class="undo jsControl">Undo</a></p></div>').css({ opacity: 0, height: item.height() + "px", width: item.width() + "px" });
                                        if (count.present()) {
                                            var i = parseInt(count.text());

                                            if (i === 1) {
                                                $('.bar .count').html('<span>0</span> resources');
                                            } else if (i === 2) {
                                                $('.bar .count').html('<span>1</span> resource');
                                            } else {
                                                count.text(i - 1);
                                            }
                                        }
                                        item.append(fader);
                                        fader.animate({ opacity: 0.9 }, 200, function () {
                                            item.append('');
                                        });

                                    }


                                    parent.find('img').remove();
                                } else {
                                    error(result ? result.msg : app.msg.error);
                                }
                            },
                            error: function () {
                                error();
                            }
                        });
                    }


                    function error(msg) {
                        that.show().focus().parent().find('img').remove();
                        app.helpers.ajaxError(msg);
                    }
                });

            } // end if logged in

        });
    },

    analytics: {
        name: "Listing",
        actions: ["Filter", "Filter group toggled", "More filters", "Favourite", "Remove from favourites", "Bar filter"],
        init: function () {
            try {
                var that = this;

                // Click a filter, value is the current crumbtrail length
                $('.xoxo a[rel="tag"]').live('click', function () {
                    app.analytics.ga.evt(that.name + ' (' + app.pagetype + ')', that.actions[0], $(this).text(), $('.crumb a').length);
                });

                // Show more filters
                $('.xoxo a.more').live('click', function () {
                    app.analytics.ga.evt(that.name + ' (' + app.pagetype + ')', that.actions[2], $(this).text());
                });

                // Open/close filter groups
                $('.xoxo h3 a').live('click', function () {
                    app.analytics.ga.evt(that.name + ' (' + app.pagetype + ')', that.actions[1], $(this).text());
                });

                // Favourite and unfavourite items
                $('.faveContainer a').live('click', function () {
                    var parent = $(this).parents('li');
                    app.analytics.ga.evt(that.name + ' (' + app.pagetype + ')', parent.is('.favourite') ? that.actions[4] : that.actions[3], parent.attr('id'));
                });

                // Filter from top bar
                $('.bar a').live('click', function () {
                    app.analytics.ga.evt(that.name + ' (' + app.pagetype + ')', that.actions[5], $(this).text().replace(/\([0-9]*\)/g, ""));
                });

            } catch (exp) {
                //nothing
            }
        }
    },

    savingSearch: function () {

        function savingError($saveLink) {
            app.helpers.ajaxError();
            $saveLink.next().remove().end().show();
        }

        function checkEmptySavedSearches() {
            if ($('.savedSearches').length === 0) {
                $('.saveSearchSection')
			        .children('p.lite').remove().end()
			        .addClass('empty').prepend("<p>Your saved searches will appear here.</p>").hide().fadeIn(300);
            }
        }

        $('.saveListingSearch').click(function (evt) {

            $this = $(this);

            if ($this.attr("href") === "#") {
                evt.preventDefault();

                $this.hide().after(app.html.inlineIndicator);
                $.ajax({
                    url: app.DEFAULTS.JSON.SAVE_SEARCH_URL,
                    cache: false,
                    data: {
                        saveSearch: 'add',
                        searchName: $this.data('searchName'),
                        xmlSearch: $this.data('xmlSearch'),
                        filterOption: $this.data('filterOption')
                    },
                    success: function (data) {
                        if (data && data.valid) {
                            $this.next().remove().end().replaceWith('<span class="pushRight savedListingSearch">Search saved</span>');
                        } else {
                            savingError($this);
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        savingError($this);
                    }
                });
            }
        });

        $('.savedSearches .deleteButton').click(function (evt) {
            evt.preventDefault();
            if (confirm(app.msg.deletes)) {
                $this = $(this);

                $.ajax({
                    url: app.DEFAULTS.JSON.DELETE_SEARCH_URL,
                    cache: false,
                    data: {
                        saveSearch: 'delete',
                        saveSearchId: $this.data('saveSearchId')
                    },
                    success: function (data) {
                        if (data && data.valid) {
                            var $list = $this.parents('.savedSearches');
                            if ($list.children('.savedSearchItem').length > 1) {
                                $this.parents('.savedSearchItem').fadeThenSlideAndRemove(function () { checkEmptySavedSearches() });
                            } else {
                                $list.fadeThenSlideAndRemove(function () { checkEmptySavedSearches() }).prev('h2').fadeOut();
                            }
                        } else {
                            app.helpers.ajaxError();
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        app.helpers.ajaxError();
                    }
                });
            }

        });
    },

    /* Begin:- new method for save job searches  */

    savingJobSearch: function () {

        function savingError($saveLink) {
            app.helpers.ajaxError();
            $saveLink.next().remove().end().show();
        }

        function checkEmptySavedSearches() {
            if ($('.savedSearches').length === 0) {
                $('.saveSearchSection')
			        .children('p.lite').remove().end()
			        .addClass('empty').prepend("<p>Your saved searches will appear here.</p>").hide().fadeIn(300);
            }
        }

        $('.saveListingSearch1').click(function (evt) {

            $this = $(this);
            var theData = {};
            //theData.saveSearch = 'add';
            theData.searchName = $this.data('searchName');
            theData.pageUrl = $this.data('pageUrl');
            if ($this.attr("href") === "#") {
                evt.preventDefault();

                $this.hide().after(app.html.inlineIndicator);
                  $.ajax({
                    url: app.DEFAULTS.JSON.SAVE_SEARCH_URL,
                    cache: false,
                    data: theData,
                    success: function (data) {

                        if (data && data.valid) {

                            if (data.msg == "Ok") {
                                $('img.inlineIndicator').css('display', 'none');
                                $this.css('display', 'none');
                                $('span#savedListingSearch').css('display', 'block');
                            }
                        } else {
                            app.helpers.ajaxError();
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        app.helpers.ajaxError();
                    }
                });
            }

        });
    },


    /* End:- new method for save job searches  */


    following: function () {
        $('ul.following .deleteButton').click(function (evt) {
            evt.preventDefault();
            if (confirm('Are you sure you want to unfollow this contributor?')) {
                $this = $(this), $li = $this.parents('li');
                $this.hide().after(app.html.inlineIndicator);
                $.ajax({
                    url: app.DEFAULTS.JSON.FOLLOW_URL,
                    cache: false,
                    data: { 'unfollow': $this.data('ac') },
                    success: function (data) {
                        if (data && data.valid) {
                            var count = $('.bar .count span'),
									fader = $('<div class="fader"><p class="flash">User unfollowed.</p></div>').css({ opacity: 0, height: $li.height() + "px", width: $li.width() + "px" });
                            if (count.present()) {
                                var i = parseInt(count.text());
                                count.text(i - 1);
                            }
                            $li.append(fader);
                            fader.animate({ opacity: 0.9 }, 200, function () {
                                $li.append('');
                            });
                            $this.next().css({ visibility: 'hidden' });
                        } else {
                            error();
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        error();
                    }
                });

                function error() {
                    app.helpers.ajaxError();
                    $this.next().remove().end().show();
                }
            }
        });
    }

}

app.profile = {
    sendMessage: function () {
        var message = $('#sendMessage');
        message.dialog({ width: 310, modal: true, draggable: false, resizable: false, autoOpen: false, dialogClass: 'sendMessageWindow', close: function () {
            message.find('textarea').val("");
        } 
        });
        $('a.sendMessage').click(function (evt) {
            evt.preventDefault();
            message.dialog('open');
        });

        message.find('form').submit(function (evt) {
            var msg = $(this).find('textarea');
            if (msg.val().length === 0) {
                evt.preventDefault();
                error("Please provide a message");
            } else {
                if (!app.depends("DEFAULTS.JSON.SEND_MESSAGE")) {
                    // send form without ajax
                    return true;
                } else {
                    evt.preventDefault();
                }

                message.append(app.html.inlineIndicator).find('input, a.cancel').hide();
                $.ajax({
                    url: app.DEFAULTS.JSON.SEND_MESSAGE,
                    data: {
                        //'to' : message.find('input.user_to').val(), //who sending message to? any other params needed?
                        'msg': msg.val()
                    },
                    success: function (result) {
                        if (result && result.valid) {
                            message.dialog('close');
                            resetWindow();
                        } else {
                            error(result ? result.msg : app.msg.error);
                        }
                    },
                    error: function () {
                        error();
                    }
                });
            }

            function error(errorMsg) {
                resetWindow();
                msg.after('<p class="error">' + (errorMsg ? errorMsg : app.msg.error) + '</p>');
            }

        }).find('a.cancel').click(function (evt) {
            evt.preventDefault();
            resetWindow();
            message.dialog('close');
        });

        function resetWindow() {
            message.find('.error, img').remove();
            message.find('input, a.cancel').show();
        }
    },

    addAsFriend: function () {
        $('a.addAsFriend').click(function (evt) {
            var that = this;
            if (!app.depends("DEFAULTS.JSON.ADD_AS_FRIEND")) {
                // send form without ajax
                return true;
            } else {
                evt.preventDefault();
            }

            $(that).after(app.html.inlineIndicator).hide();
            $.ajax({
                url: app.DEFAULTS.JSON.ADD_AS_FRIEND,
                success: function (result) {
                    if (result && result.valid) {
                        $(that).parent().find('p.error, img.inlineIndicator').remove();
                        $(that).after('<span class="lite">' + result.msg + '</span>').remove();
                    } else {
                        error(result ? result.msg : app.msg.error);
                    }
                },
                error: function () {
                    error();
                }
            });

            function error(errorMsg) {
                $(that).show().parent().find('p.error, img.inlineIndicator').remove();
                $(that).after('<p class="error">' + (errorMsg ? errorMsg : app.msg.error) + '</p>');
            }
        });

    }

}


/* When page loads... */
/* Selectively enable listeners */
/*************************************************/

$(function(){
	var $body = $('body');

	$body.addClass('js');
	$('.hide').hide().removeClass('hide');
	
	/* Listing pages
	   Note: if no results, div.filters might not exist in some cases
	 */
	if($('div.filters').present()) {
		app.listing.filters();
		app.listing.favouriting();
		//app.listing.analytics.init(); --hold off on analytics for now
	}
	
	/* Resources JS */	
	if(app.pagetype === app.pagetypes.RESOURCES) {
	
		/* Resource detail */
			if($body.hasClass('detail')) {
				app.resources.reviews();
				app.general.following();				
				
				if(app.DEFAULTS.LOGGED_IN) {
				    app.resources.preview();
				    app.resources.audit();
				}
				//app.resources.analytics.init();  --hold off on analytics for now
				
			} else if ($body.hasClass('following')) {
				app.listing.following();
			} else if ($body.hasClass('savedSearch') || $body.hasClass('listing')) {
				app.listing.savingSearch();
			}
	}

	/* Jobs JS */
	if (app.pagetype === app.pagetypes.JOBS) {

		/* Post code */
		if ($('form.postcode').present()) {
			app.jobs.postcode();
		}

		/* My jobs */
		if ($body.hasClass('my') && $('.savedSearches li').present()) {
			app.jobs.savedSearches();
		}
		/*Begin :-Added for Save Job searches */
		else if ($body.hasClass('listing-map') || $body.hasClass('listing')) {
			app.listing.savingJobSearch();
		}
		/*End :-Added for Save Job searches */
		/* Job details */
		else if ($body.hasClass('detail')) {
			app.jobs.detail();
		}
		/* Talent bank */
		else if ($body.hasClass('talent-bank')) {
			app.jobs.talentBank();
			if ($body.hasClass('edit')) {
				app.jobs.talentBankEdit();
			}
		}

		// Generate dynamic maps on pages that have them.
		if (jQuery.fn.mapify) {
			jQuery('.map').mapify();
		}
	}

	/* Profile JS */
	if(app.pagetype === app.pagetypes.PROFILE) {
		if($('#sendMessage').present()) {
			app.profile.sendMessage();
		}
		
		if($('a.addAsFriend').present()) {
			app.profile.addAsFriend();
		}
		
		app.general.following();
	}
	
	/* Funnel JS */
	if($body.hasClass('funnel')) {
		app.funnel.rollups();
	}
	
	/* General JS */
	if($('div.prose a.more').present()) {
		app.general.moreText();
	}
	
	if (app.pagetype !== app.pagetypes.ACCOUNTS) {
		app.forms.deletes();
	}
});

var addthis_config = {
    data_track_clickback: true,
    services_compact: 'email, facebook, twitter, more',
    services_expanded: 'digg, stumbleupon, delicious',
    services_exclude: 'print, favorite',
    ui_click: true
};
