// AIS
/*
	use minify to reduce filesize of published ais.js

	requires: jquery-1.3.2.min.js
	no longer requires: jquery.cookie.min.js
	
	naming conventions:
		camelCaseFunctions 
		CapitalisedCamelCaseConstructors  
		under_score_variables 
		hyphenated-css-classes-and-ids
		$jquery_objects start with a $ sigil
	
	beware! jQuery doesn't like to compete with window.onload used by other scripts
	
*/
/*globals $, jQuery, ais */

// jQuery.noConflict();
var ais = ais || {};

(function($) {

    ais.init = function() {

        if ($('#scWebEditRibbon').size() === 0) { // then you're not in sitecore edit mode
            ais.jsCSS();
            ais.url.hash.init();

            ais.prepLinkRels("Opens in new window");
            ais.initSearch(".search-field");
            ais.prepMainNav(".nav-bar");
            ais.prepQuotes(20000, 3000); //pause between fades, fade_speed
            ais.initAccordion();
            ais.switcher.init(); // style sheet & font size switcher

            //ais.tabs.init();
            ais.roller.init();
            
          /*  if (window.location.pathname == '/') {
                ais.ticker.init({ wipe_speed: 2, pause_speed: 500 });
            }*/
            ais.social.init();

            ais.preCache([
                '/chrome/angles/lines/angle_42x98_b60000_fff_line.png',
                '/chrome/angles/lines/angle_42x98_7c0d6e_e7d4e7_line.png',
                '/chrome/angles/lines/angle_7c0d6e_fff_84x98.png',
                '/chrome/angles/angle_e7d4e7_84x98.png',
                '/chrome/angles/angle_fff_84x98.png'
			]);

            // ais.test();
        } else {
            $("#wrapper").addClass('webedit');
        }
    };

    ais.initSearch = function(search_selector_str) {
        $(search_selector_str)
		    .each(function() {
		        var search_field_text, $submit_btn; //$search_field = $(this)

		        //search_field_text = $(this).val();
		        search_field_text = $(this).attr("title"); /* fixes f5 refresh ff3 bug */
		        $(this)
				    .focus(function() {
				        if (this.value === search_field_text) {
				            this.value = '';
				            $(this).addClass("focussed");
				        }
				    })
				    .blur(function() {
				        if (this.value === "") {
				            this.value = search_field_text;
				            $(this).removeClass("focussed");
				        }
				    });

		        // $submit_btn = $(this).nextAll("input[type='submit']:first"); //.get(0); 
		        //$submit_btn = $(this).next("input[type='submit']:first"); 
		        //$(this).keypress(function (e) {
		        //if (e.which && e.which === 13) { // || (e.keyCode && e.keyCode === 13)) {
		        //$submit_btn.click();
		        //}; 
		        //});

		    });
    };

    ais.jsCSS = function() {
        // enable javascript dependent css
        $('body').addClass('js');
    };

    ais.prepLinkRels = function(message) {
        // fix _blank rel=external
        message = message || "(Opens in new window)";

        $("a[rel*='external']")
			.click(function() {
			    window.open($(this).attr('href'));
			    return false;
			})
			.each(function() {
			    var title = $(this).attr("title");
			    if (!title) {
			        $(this).attr("title", message);
			        // this.setAttribute("title", message);
			    }
			});
    };

    ais.cookie = { // cookie functions copied from code by Peter Paul Koch : http://www.quirksmode.org
        set: function(name, value, days) {
            var date, expires;
            if (days) {
                date = new Date();
                date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                expires = "; expires=" + date.toGMTString();
            } else {
                expires = "";
            }
            document.cookie = name + "=" + value + expires + "; path=/";
        },
        get: function(name) {
            var nameEq, cookie_array, i, i_cookie;
            nameEq = name + "=";
            cookie_array = document.cookie.split(';');
            for (i = 0; i < cookie_array.length; i++) {
                i_cookie = cookie_array[i];
                while (i_cookie.charAt(0) === ' ') {
                    i_cookie = i_cookie.substring(1, i_cookie.length);
                }
                if (i_cookie.indexOf(nameEq) === 0) {
                    return i_cookie.substring(nameEq.length, i_cookie.length);
                }
            }
            return null;
        },
        del: function(name) {
            ais.cookie.set(name, "", -1);
        }
    };

    // ed
    //for(var i = 0; i < 6; i++){
    //var target = temp.get(i);
    //var div = document.createElement('div');
    //div.className = "this";
    //div.appendChild(target.cloneNode(true));
    //target.replaceNode(div);
    //};
    ////temp.wrap('<div class="this"></div>');
    //debugger;

    ais.prepMainNav = function(selector_str) {

        $('a:not(.this)', selector_str)
			.hover(
				function() {
				    $(this)
						.parent()
						.parent()
						.not('.this')
						.addClass('hover');
				},
				function() {
				    $(this)
						.parent()
						.parent()
						.removeClass('hover');
				});

        /*
        $('span, a.this', selector_str)
        .wrap('<div class="this"></div>')
        .wrap('<div></div>');
        $('a:not(.this)', selector_str)
        .wrap('<div></div>')
        .wrap('<div></div>')
        .hover(
        function () {
        $(this)
        .parent()
        .parent()
        .addClass('hover');
        }, 
        function () {
        $(this)
        .parent()
        .parent()
        .removeClass('hover');
        });
			
		$(selector_str)
        .each(function () {
        $(this)
        .children(':first')
        .addClass('first');
        //.filter('.this')
        //.addClass('this-first')
        //.removeClass('first')
        });
        */
    };

    ais.prepQuotes = function(pause, fade_speed) {
        var quoteGroupClosure;

        quoteGroupClosure = function($group, number_of_quotes, quote_width) {
            var current_quote, timeout, timeoutQuoteFunction;
            current_quote = 0;

            timeoutQuoteFunction = function() {
                var position;

                //fadeout current quote
                $group.fadeOut(fade_speed, function() {

                    //update current index, reset if too large
                    current_quote++;
                    if (current_quote >= number_of_quotes) {
                        current_quote = 0;
                    }

                    position = 0 - (current_quote * quote_width);

                    // move group to show new (current) quote
                    $group.get(0).style.left = position + "px";

                    // and fade it in
                    $group.fadeIn(fade_speed);
                });

                clearTimeout(timeout);
                timeout = setTimeout(timeoutQuoteFunction, pause);
            };
            timeout = setTimeout(timeoutQuoteFunction, pause); // set first timeout
        };

        $('.quotes-box')
			.each(function() {
			    // this function could act as the closure instead, despite .each feeling like a loop
			    var $quotes_group, $quotes, quote_width, group_width_str, number_of_quotes;

			    $quotes_group = $('.quotes-group', this); // should only be one although $ is a group (of one)
			    $quotes = $('.quote', $quotes_group);
			    number_of_quotes = $quotes.length;

			    // set width of quotes frame
			    quote_width = $quotes.get(0).offsetWidth;
			    group_width_str = (quote_width * number_of_quotes) + "px";
			    $quotes_group.get(0).style.width = group_width_str;

			    // make sure group is positioned correctly
			    if (!$quotes_group.get(0).style.left) {
			        $quotes_group.get(0).style.left = "0px";
			    }

			    quoteGroupClosure($quotes_group, number_of_quotes, quote_width);
			});
    };
    /*	
    ais.initAccordion = function () {
    // requires: only one accordion per page
		
		var page_str = ais.prefs.text.page + " ";
    $('.accordion').each(function () {
		
			$('.leaf', this)
    .each(function (i) {
    var page_num, $leaf, $leaf_inner, $a, $span_open_close, $span_hover;
    page_num = i + 1;
					
    $leaf = $(this);
    $leaf
    .wrapInner('<div class="leaf-inner"></div>');
						
    $leaf_inner = $leaf
    .children('.leaf-inner')
    .eq(0)
    .hide();	
					
    $span_hover = $('<span></span>')
    .text(page_str + page_num);
						
    $span_open_close = $('<span></span>')
    .append($span_hover);
					
    $a = $('<a href="#"></a>');
    $a
    .addClass('leaf-toggle')
    .click(function () {
						
    if ($leaf_inner.is(':visible')) {
    $leaf
    .removeClass('leaf-open')
    .children('.leaf-inner')
    .slideUp('slow');		
    } else {
    $leaf
    .addClass('leaf-open')
    .children('.leaf-inner')
    .slideDown('slow')
    .end()
    .siblings()
    .removeClass('leaf-open')
    .filter(':visible')
    .children('.leaf-inner')
    .slideUp('slow');
    }
    $a.blur();
    return false;
    })
    .hover(
    function () {
    $span_hover.addClass("hover");
    }, 
    function () {
    $span_hover.removeClass("hover");
    })
    .append($span_open_close);
						
    $leaf.prepend($a);
    });
				
    // opens first leaf of each accordion , remove [this] if only first leaf of page is required to be open
    $('.leaf:first', this) 
    .addClass("leaf-open")
    .children('.leaf-inner')
    .show();
    });
    };
    */
    ais.initAccordion = function() {
        // v2.2.6 added .leaf.start-closed
        // v2.2.5 from phh library
        // requires: phh.prefs.text.page
        // requires: core.css 	.leaf-inner.closed {display:none;}
        // requires: print.css 	div.leaf-inner.closed {display:block;}

        // hide & .closed used for printing a fully open accordion
        // .leaf.start-closed causes leaf to start in closed state

        /*
        assumes:
        .accordion
        .leaf
        h2.leaf-title
        .leaf
        h2.leaf-title.delete
				
		creates:
        .accordion
        .leaf.open
        a.leaf-toggle
        span
        span
        div.leaf-inner
        .leaf
        a.leaf-toggle
        span
        span
        div.leaf-inner.closed
					
		h2.leaf-title copied to a.leaf-toggle/span/span
        h2.leaf-title.delete is deleted once copied
        */

        var 
			page_str, hide, removeStyle,
			toggle_txt_show, toggle_txt_hide;

        page_str = ais.prefs.text.page + " ";

        toggle_txt_show = "View Choices";
        toggle_txt_hide = "Hide Choices";

        hide = function() {// callback
            $(this)
				.addClass('closed')
				.removeAttr("style")
				;
        };
        removeStyle = function() {
            $(this).removeAttr("style");
        };

        $('.accordion').each(function() {
            $('.leaf', this)
			    .each(function(i) {
			        var 
						page_num,
						$leaf,
						$leaf_inner,
						$a,
						$span_open_close,
						$span_hover,
						leaf_title,
						$first_leaf_title,
						toggle_txt_flag;

			        page_num = i + 1;
			        toggle_txt_flag = false;

			        $leaf = $(this)
					    .wrapInner('<div class="leaf-inner"></div>');

			        $leaf_inner = $leaf
					    .children('.leaf-inner')
					    .eq(0)
					    .hide()
						.addClass('closed')
						.removeAttr("style")
						;

			        // if leaf has toggle-txt
			        toggle_txt_flag = ($leaf.hasClass("toggle-txt"));
			        if (toggle_txt_flag) {
			            leaf_title = ($leaf.hasClass('start-closed')) ? toggle_txt_show : toggle_txt_hide; // ternary conditional operater	
			        } else {
			            // if leaf title is not present in html then create it from prefs
			            $first_leaf_title = $('.leaf-title:first', this);

			            leaf_title = $first_leaf_title.text() || page_str + page_num;
			            if ($first_leaf_title.hasClass('delete')) {
			                $first_leaf_title.remove();
			            }
			        }

			        $span_hover = $('<span></span>').text(leaf_title);
			        $span_open_close = $('<span></span>').append($span_hover);

			        $a = $('<a href="#"></a>');
			        $a
					    .addClass('leaf-toggle')
					    .click(function() {

					        if ($leaf_inner.is(':visible')) {
					            $leaf
								    .removeClass('open')
								    .children('.leaf-inner')
								    .slideUp('slow', hide)
									;

					            if (toggle_txt_flag) {
					                $span_hover.text(toggle_txt_show);
					            }
					        } else {
					            $leaf
								    .addClass('open')
								    .children('.leaf-inner')
								    .slideDown('slow', removeStyle) // removeStyle not necessary
									.removeClass('closed')
								    .end()
								    .siblings()
								    .removeClass('open')
								    .filter(':visible')
								    .children('.leaf-inner')
								    .slideUp('slow', hide)
									;
					            if (toggle_txt_flag) {
					                $span_hover.text(toggle_txt_hide);
					            }
					        }
					        $a.blur();
					        return false;
					    })
					    .hover(
						    function() {
						        $span_hover.addClass("hover");
						    },
						    function() {
						        $span_hover.removeClass("hover");
						    })
					    .append($span_open_close);
			        $leaf.prepend($a);
			    });

            // opens first leaf of each accordion, remove [this] if only first accordion's leaf of page is required to be open
            $('.leaf:first', this)
			    .not('.start-closed') // leave .start-closed as closed leaves
				.addClass('open')
				.children('.leaf-inner')
				.show()
				.removeClass('closed')
				.removeAttr("style") // not necessary
				;
        });
    };





    ais.switcher = {
        test: function(arg) {
            alert('test: ' + arg);
        },
        init: function() {
            var initCssSwitching, initFontSwitching;

            // alert('switcher init');

            // check ifeither cookie exists:
            // if yes: switch to cookie choices (if possible, else use default) and signal choices
            // if no:
            // can cookies be used?
            // if no: abandon installation
            // if yes: set cookie with defaults (no need to switch, but make sure signals ok)

            initCssSwitching = function() {

                // make a list of useable css link tags
                var prefs, link_elements, titles, i, i_title, default_title, css_cookie_str, setStyleSheetLinks, attachClick, setStyleSheet, setCssCookie;

                setStyleSheetLinks = function(style_sheet_title) {
                    // called by: initCssSwitching(), setStyleSheet()
                    $("link[rel*='style'][title='" + style_sheet_title + "']")
						.each(function() { // only swap if style can be found
						    $("link[rel*='style'][title][media='screen']")
								.each(function() {// disable all
								    this.disabled = true;
								});
						    this.disabled = false; // enable matching style sheet			
						});
                }; // eo: setLinks

                // closure for attaching event to node within loop
                attachClick = function($node, title) {
                    $node.click(function() {
                        setStyleSheet(title);
                        //setCssCookie(title);
                        $(this).blur();
                        return false;
                    });
                };

                setCssCookie = function(style_sheet_title) {
                    if (titles[style_sheet_title] === undefined) {
                        alert('setCssCookie error: ' + style_sheet_title);
                        return;
                    }
                    ais.cookie.set(prefs.cookie_name, style_sheet_title, prefs.cookie_expiry);
                };

                setStyleSheet = function(style_sheet_title) {
                    // argument matches <link title> and may be:
                    // Default	
                    // Enhanced Readability Style 
                    // High Contrast Style

                    if (titles[style_sheet_title] === undefined) {
                        alert('setStyleSheet error: ' + css_cookie_str);
                        return;
                    }

                    var i, i_abbr, i_node, i_title, i_label, i_class, i_action, i_selected, $options_selector, current_title, previous_css_class, new_css_class, er;

                    // update style sheet
                    setStyleSheetLinks(style_sheet_title);

                    // if needed remove class from body
                    // then add class to body
                    current_title = ais.cookie.get(prefs.cookie_name);
                    if (current_title) {
                        previous_css_class = prefs.lookup[current_title].css_class;
                        $("#wrapper").removeClass(previous_css_class);
                    }
                    new_css_class = prefs.lookup[style_sheet_title].css_class;
                    $("#wrapper").addClass(new_css_class);

                    // update signals
                    $options_selector = $(prefs.options_selector); //.get(0);
                    $options_selector.html('');

                    for (i = 0; i < prefs.options.length; i++) {

                        i_title = prefs.options[i].title; 	// "Default",								// matches <link> CopyAdvice
                        i_action = prefs.options[i].action; 	// "view the page in the Default style",	// used in button <a><abbr> title
                        i_selected = prefs.options[i].selected;
                        i_label = prefs.options[i].label; 	// "C",										// label text of button
                        i_class = prefs.options[i].css_class; // "default",

                        if (i_title === style_sheet_title) {

                            try { // ie6 !abbr
                                i_abbr = $('<abbr></abbr>')
									.text(i_label)
									.attr({ title: i_selected });
                            }
                            catch (er) {
                                i_abbr = $('<span></span>')
									.text(i_label)
									.attr({ title: i_selected });
                            }

                            i_node = $('<span></span>')
								.addClass(i_class)
								.addClass('this')
								.append(i_abbr);

                        } else {

                            try { // ie6 !abbr
                                i_abbr = $('<abbr></abbr>')
									.text(i_label)
									.attr({ title: i_action });
                            }
                            catch (er) {
                                i_abbr = $('<span></span>')
									.text(i_label)
									.attr({ title: i_action });
                            }

                            i_node = $('<a></a>')
								.attr('href', '#')
								.addClass(i_class)
								.append(i_abbr);

                            attachClick(i_node, i_title);
                        }
                        $options_selector.append(i_node);
                    }

                    setCssCookie(style_sheet_title); // link has been tested to exist

                    // remove previous class on body if there
                    // add class to body
                    //$('body').addClass('js'); // can't remember why? remove this???

                }; // eo: setStyleSheet


                // funcs are now defined, so now do stuff for initialising
                prefs = ais.prefs.css;

                // make look up hash from prefs
                prefs.lookup = {};
                for (i = 0; i < prefs.options.length; i++) {
                    i_title = prefs.options[i].title;

                    prefs.lookup[i_title] = {
                        index: i,
                        title: i_title,
                        css_class: prefs.options[i].css_class
                    };
                }

                link_elements = $('link[rel*=style][title][media=screen]'); // returns object
                if (!link_elements || (link_elements.length < 2)) {
                    // no style sheets to switch between, so don't install switcher
                    alert('373 link_elements ' + link_elements);
                    return;
                }

                // make css link titles hash
                titles = {};
                for (i = 0; i < link_elements.length; i++) {
                    i_title = link_elements[i].title;
                    titles[i_title] = i;
                }

                // find the (first) css link that isn't an alternative, otherwise (something is wrong but) use an available (alt?) link
                default_title = $('link[rel*=style][title][media=screen]').not('[rel*=alt]')[0].title || i_title;

                // check if cookie exists
                css_cookie_str = ais.cookie.get(prefs.cookie_name);
                /*
                if (css_cookie_str) {
                if (titles[css_cookie_str] !== undefined) { // then cookie style available on this page
                // swap style to match cookie (if needed)
                setStyleSheet(css_cookie_str);	
                } else { // cookie exists but style unavailable, so use default style and update cookie
                // use default style, so no need to swap styles
                ais.cookie.set(prefs.cookie_name, default_title, prefs.cookie_expiry);
                setStyleSheet(css_cookie_str);	// abstract into just signal update?
                }
                } else { // no cookie! try to create one...
                // use default style, so no need to swap styles
                ais.cookie.set(prefs.cookie_name, default_title, prefs.cookie_expiry);
					
					css_cookie_str = ais.cookie.get(prefs.cookie_name);
                if (!css_cookie_str) { // cannot create cookie, cookies must be turned off, so don't install switcher
						
						alert('406 css_cookie_str ' + css_cookie_str);
                return;
                } else {
                setStyleSheet(css_cookie_str);
                }
                }
                */
                if (css_cookie_str) {
                    if (titles[css_cookie_str] === undefined) {
                        // cookie exists, but there is no corresponding link title
                        ais.cookie.set(prefs.cookie_name, default_title, prefs.cookie_expiry);
                    }
                } else {
                    // no cookie! try to create one...
                    ais.cookie.set(prefs.cookie_name, default_title, prefs.cookie_expiry);
                    css_cookie_str = ais.cookie.get(prefs.cookie_name);
                    if (!css_cookie_str) {
                        // cannot create cookie so don't install switcher
                        // alert('504 css_cookie_str ' + css_cookie_str);
                        return;
                    }
                }

                // by this point cookie must exist and have a corresponding link title, as does css_cookie_str
                // body will not have a style sheet class (when init called)
                setStyleSheet(css_cookie_str); // abstract into just signal update?

                // switch style sheet functions
                // update style sheet
                // update buttons
            };


            initFontSwitching = function() {
                var i, prefs, font_cookie_str, font_cookie_num, setFontSize, setFontCookie, attachClick;

                // closure for attaching event to node within loop
                attachClick = function($node, index) {
                    $node.click(function() {
                        setFontSize(index);
                        setFontCookie(index);

                        $(this).blur();
                        return false;
                    });
                };

                setFontCookie = function(option_num) {
                    // requires: a number as a string
                    ais.cookie.set(prefs.cookie_name, String(option_num), prefs.cookie_expiry);
                };

                setFontSize = function(option_num) {
                    // requires a number
                    if (typeof option_num === String) {
                        option_num = Number(option_num);
                    }

                    var font_size, $options_selector, i_size_num, i_label, i_action, i_selected, i_node, i_abbr;

                    // set font size
                    font_size = prefs.options[option_num].size + "%";
                    $('body').css({ fontSize: font_size });

                    // signal font size
                    $options_selector = $(prefs.options_selector); //.get(0);
                    $options_selector.html('');

                    for (i = 0; i < prefs.options.length; i++) {
                        i_size_num = prefs.options[i].size;
                        i_label = prefs.options[i].label;
                        i_action = prefs.options[i].action;
                        i_selected = prefs.options[i].selected;

                        if (i === option_num) {

                            try {
                                i_abbr = $('<abbr></abbr>')
										.text(i_label)
										.attr({ title: i_selected });
                            }
                            catch (er) {
                                i_abbr = $('<span></span>')
										.text(i_label)
										.attr({ title: i_selected });
                            }

                            i_node = $('<span></span>')
								.addClass('font-size-' + i)
								.addClass('this')
								.append(i_abbr);

                        } else {

                            try {
                                i_abbr = $('<abbr></abbr>')
										.text(i_label)
										.attr({ title: i_action });
                            }
                            catch (er) {
                                i_abbr = $('<span></span>')
								.text(i_label)
								.attr({ title: i_action });
                            }

                            i_node = $('<a></a>')
								.attr('href', '#')
								.addClass('font-size-' + i)
								.append(i_abbr);

                            attachClick(i_node, i);

                        }
                        $options_selector.append(i_node);
                    }
                }; // eo: setFontSize

                // vars
                prefs = ais.prefs.font;

                // check cookie exists, or could exist (and be set to default), and read it or leave function
                font_cookie_str = ais.cookie.get(prefs.cookie_name);
                if ((font_cookie_str === null) || (font_cookie_str === undefined)) { // value of cookie string can be 0 thus falsy
                    // if no cookie, then create one set to default value
                    ais.cookie.set(prefs.cookie_name, prefs.default_index, prefs.cookie_expiry);

                    font_cookie_str = ais.cookie.get(prefs.cookie_name);
                    if (!font_cookie_str) { // cannot create cookie, cookies must be turned off, so don't install switcher
                        return;
                    }
                }

                // if at this point then cookies may be set, 
                // either cookie has been read, or cookie set to default
                // and cookie_str is set

                font_cookie_num = Number(font_cookie_str);
                setFontSize(font_cookie_num); // cookie holds array index number		
            }; // eo: initFontSwitching

            initCssSwitching();
            initFontSwitching();
        }
    };




    ais.prefs = {
        text: { // if multilingual required this could be written into head (with an english backup in .js)
            backtotop: "back to top", // not used
            page: "Page" // used by accordion
        },
        cookie_expires: 90,
        font: { // switcher
            options_selector: ".font-size-options", //jQuery
            default_index: 0,
            options: [
				{ size: 100, px: 13, action: "switch to normal font size", selected: "normal font size is displayed", label: "A" },
				{ size: 123, px: 16, action: "switch to larger font size", selected: "larger font size is displayed", label: "A" },
				{ size: 140, px: 18, action: "switch to largest font size", selected: "largest font size is displayed", label: "A" }
			],
            cookie_name: "copyadvice-font-size"
        },
        css: { // switcher
            options_selector: ".css-switcher-options", //jQuery
            options: [
				{
				    title: "Default", 							// matches <link> CopyAdvice
				    action: "view the page in the Default style", // used in button <a><abbr> title
				    selected: "the Default page style is being used", // used in span / .this <abbr> title
				    label: "C", 									// text of button
				    css_class: "default", 							// css class to style button
				    simple_flag: false								// activate simple mode, turn off js features / animations // optional
				},
				{
				    title: "Enhanced Readability Style",
				    action: "view the page in an Enhanced Readability style",
				    selected: "the Enhanced Readability style is being used",
				    label: "C",
				    css_class: "enhanced"
				},
				{
				    title: "High Contrast Style",
				    action: "view the page in a High Contrast style",
				    selected: "the High Contrast style is being used",
				    label: "C",
				    css_class: "high-contrast"
				}
			],
            cookie_name: "copyadvice-css"
        }
    };

    ais.prepScroller = function() {
        $("a[href^='#']")
	        .click(function() {
	            var id, scroll_top;
	            id = $(this).attr('href');
	            scroll_top = $(id).offset().top;
	            $('html, body').animate({ scrollTop: scroll_top }, 2000);
	            $(this).blur();
	            return false;
	        });
    };

    ais.cache = {};
    ais.preCache = function(img_name_array) {
        // cache images
        var i, cache, img_name; //, error;

        cache = ais.cache || {};
        // ais = ais ? ais : {};

        if (arguments.length === 0) {
            //error = new Error(); 
            //error.name = 'ais.preCache'; 
            //error.message = 'cannot pre cache';
            //throw(error);

            // alert('preCache');
            return false;
        }

        for (i = 0; i < img_name_array.length; i++) {
            img_name = img_name_array[i];

            // only cache image if it is not already in cache
            if (!cache[img_name]) {
                cache[img_name] = new Image();
                cache[img_name].src = img_name;
            }

        }

        /*
        var s, str = ""
        for (s in ais.cache) {
        str = ais.cache[s].src + ' ';
		
		alert(str);
        }
        */
    };



    ais.roller = {
        // v1.2
        // v1.1 height detection in case units are too few for height of roller
        // v1.2 slow down and stop on mouse over
        // v1.0 
        /*
        requires:
        .roller
        .units
        .unit
        .unit
        .unit
			
			
        .js .roller {
        height:20em;
        border:1px solid #ddd;
        overflow:hidden;
        padding-left:10px;
        padding-right:10px;
        margin-top:6px;
        margin-bottom:18px;
        }
        .js #main .roller h4 {margin:0;}
        .js #main .roller p {margin:0; padding:0;}
        .js .roller .unit {padding-bottom:18px;}
	
	
	*/
        speed: 40,
        init: function() {
            var the = this;

            $('.roller')
				.each(function() {
				    var 
						roller = this,
						$roller = $(this),
						$units = $('.units', $roller),
						tallest_unit = 0,
						max_roller_height,
						min_roller_height = 100,
						moveUnit,
						slow_down = false,
						speed = the.speed,
						slowest_speed = 300,
						timeout,
						timeoutFunction,
						startTimeout;

				    startTimeout = function() {
				        clearTimeout(timeout);
				        timeout = setTimeout(timeoutFunction, speed);
				        // $('#dev').text(speed);
				    };

				    moveUnit = function() {
				        var 
							$first_unit,
							unit_height,
							margin_target;

				        $first_unit = $('.unit:first', $units);

				        // get height
				        unit_height = $first_unit.innerHeight();
				        margin_target = 0 - unit_height;

				        timeoutFunction = function() {
				            var 
							    margin_height,
							    margin_height_str,
							    new_margin_top;

				            margin_height_str = $first_unit.css("margin-top"); //0px
				            //margin_height = margin_height_str.slice(0, -2);
				            margin_height = parseInt(margin_height_str, 10); // radix of 10
				            //alert('mt ' + $first_unit[0].style.marginTop); // wont be set ???

				            new_margin_top = margin_height - 1;
				            $first_unit.css("margin-top", new_margin_top);

				            if (new_margin_top <= margin_target) {
				                // move unit to bottom
				                $first_unit
									.css("margin-top", "0px")
									.appendTo($units); // was $roller

				                // move next unit
				                moveUnit();
				            } else {
				                // move this unit a little more

				                if (slow_down) {
				                    if (speed < slowest_speed) {
				                        speed = Math.round(speed * 1.5);
				                        startTimeout();
				                    }
				                } else {
				                    // timeout as normal
				                    startTimeout();
				                }
				            }
				        };
				        startTimeout(); // set first timeout
				    };

				    // check height of roller
				    // this is just a basic safety net
				    $('.unit', $units)
						.each(function() {	// compare each unit to find tallest
						    var unit_height = $(this).innerHeight();
						    if (unit_height > tallest_unit) {
						        tallest_unit = unit_height;
						    }
						});
				    max_roller_height = $units.innerHeight() - tallest_unit;
				    if (max_roller_height < min_roller_height) {
				        max_roller_height = min_roller_height;
				    }
				    if ($roller.innerHeight() > max_roller_height) {
				        $roller.css("height", max_roller_height);
				    }

				    $roller
						.hover(
							function() {
							    slow_down = true;
							},
							function() {
							    slow_down = false;
							    speed = the.speed;
							    startTimeout();
							});

				    // call move function for first time
				    moveUnit();
				});
        }
    };





    ais.url = {
        hash: {
            init: function() {
                this.str = decodeURI(location.hash.substring(1)); // substring(1) removes first ? character
            },
            str: ""
        }
    };



    //	ais.test = function () {
    //		// delete this, twas used to get ajax running
    //		
    //		var xml_path = "http://www.asadev.org.uk/RSS-Feeds/Latest-Adjudications-Feed.aspx?bobdfdfq";
    //		
    //		alert('test');
    //		
    //		var ajaxCallback = function (data) {
    //			var $items;
    //			
    //			alert('test ajaxCallback' + data);
    //			
    //			$items = $('item', data);
    //		};
    //		
    //		var error = function (XMLHttpRequest, textStatus, errorThrown) {
    //			  // typically only one of textStatus or errorThrown 
    //			  // will have info
    //			  // this; // the options for this ajax request
    //			  
    //			  alert('error ' + textStatus + ' : ' + errorThrown);
    //			  
    //			  // parseerror undefined
    //		};
    //			
    //		$.ajax({
    //			type : "GET",
    //			url : xml_path,
    //			cache : false,
    //			success : ajaxCallback,
    //			dataType : "xml",
    //			error : error
    //		});
    //	};

    ais.ticker = {
        // v1.2
        /*
        requires:
        server to send xml with headers:
        Cache-Control : no-cache, no-store
        Pragma : no-cache
        Content-Type : text/xml; charset=utf-8

		assumes:
        only one .ticker on the page
		
		comments:
        this should really be done on the server
        and (assuming no double lines) each rss should be written into the page and revealed sequentially
        */
        /*
        xml_path : "http://www.asadev.org.uk/RSS-Feeds/Latest-Adjudications-Feed.aspx",
        */
        prefs: {
            selector_str: ".ticker",
            state: null,
            //xml_path : "xml/ingress.rss2.xml",
            xml_path: "/RSS-Feeds/Meltwater-News.aspx",
            prefix_str: "ASA in the media: ",

            // wipe
            wipe_increment: 2,
            wipe_speed: 1,
            pause_speed: 500,

            // button titles
            play_title: "play",
            pause_title: "pause",
            next_title: "next",
            previous_title: "previous",

            // sprite offsets
            play_static_x: 0,
            play_over_x: -15,
            pause_static_x: -30,
            pause_over_x: -45,
            next_static_x: -60,
            next_over_x: -75,
            previous_static_x: -90,
            previous_over_x: -105
        },
        play_chosen_flag: true,
        swipe_in_progress_flag: true,
        init: function(options) {
            var 
				the,
				prefs,
				ajaxCallback,
				$ticker, $message, $inner,
				$items, item_index, item_index_max,
				startTimeout, timeout,
				wipe_timeout,
				putItemIntoInner, showNextItem, showPreviousItem, swipeNextItem,
				full_width,
				$item, $a,
				x_title, x_link, x_description;

            // define vars	
            the = this; // ais.ticker;
            prefs = $.extend(the.prefs, options);
            $ticker = $(prefs.selector_str);
            item_index = 0; // index of news feed item to be displayed
            the.controls = {
                init: function() {
                    this.toggle.init();
                    this.previous.init();
                    this.next.init();
                },
                setSpriteOffset: function($el, offset_x) {
                    var position_str = offset_x.toString(10) + "px 0";
                    $el.css({ "backgroundPosition": position_str });
                },
                toggle: {
                    $el: null,
                    play: function() {
                        the.play_chosen_flag = true;
                        if (!the.swipe_in_progress_flag) {
                            swipeNextItem();
                        }
                        the.controls.setSpriteOffset(this.$el, the.prefs.pause_over_x);
                        this.$el.attr("title", prefs.pause_title);
                    },
                    pause: function() {
                        // called by toggle
                        the.play_chosen_flag = false;
                        the.controls.setSpriteOffset(this.$el, the.prefs.play_over_x); // assume mouse_state === over
                        this.$el.attr("title", prefs.play_title);
                    },
                    stop: function() {
                        // called by previous or next
                        the.play_chosen_flag = false;
                        the.controls.setSpriteOffset(this.$el, the.prefs.play_static_x); // assume mouse_state === static
                        this.$el.attr("title", prefs.play_title);
                    },
                    mouseClick: function() {
                        if (the.play_chosen_flag) { // playing
                            this.pause();
                        } else { // paused
                            this.play();
                        }
                    },
                    mouseOver: function() {
                        if (the.play_chosen_flag) { // playing (shows click to pause)
                            the.controls.setSpriteOffset(this.$el, the.prefs.pause_over_x);
                        } else { // paused (shows click to play)
                            the.controls.setSpriteOffset(this.$el, the.prefs.play_over_x);
                        }
                    },
                    mouseLeave: function() {
                        if (the.play_chosen_flag) { // playing (shows click to pause)
                            the.controls.setSpriteOffset(this.$el, the.prefs.pause_static_x);
                        } else { // paused (shows click to play)
                            the.controls.setSpriteOffset(this.$el, the.prefs.play_static_x);
                        }
                    },
                    init: function() {
                        var that = this; // phh.ticker.controls.toggle
                        this.$el = $('.toggle', $ticker);
                        this.$el
							.click(function() {
							    that.mouseClick();
							    return false;
							})
							.hover(
								function() {
								    that.mouseOver();
								},
								function() {
								    that.mouseLeave();
								}
							);
                        the.controls.setSpriteOffset(this.$el, the.prefs.pause_static_x);
                    }
                },
                previous: {
                    $el: null,
                    mouseClick: function() {
                        the.controls.toggle.stop();
                        showPreviousItem();
                        the.controls.setSpriteOffset(this.$el, the.prefs.previous_over_x);
                    },
                    mouseOver: function() {
                        the.controls.setSpriteOffset(this.$el, the.prefs.previous_over_x);
                    },
                    mouseLeave: function() {
                        the.controls.setSpriteOffset(this.$el, the.prefs.previous_static_x);
                    },
                    init: function() {
                        var that = this;
                        this.$el = $('.previous', $ticker);
                        this.$el
							.click(function() {
							    that.mouseClick();
							    return false;
							})
							.hover(
								function() {
								    that.mouseOver();
								},
								function() {
								    that.mouseLeave();
								}
							);
                    }
                },
                next: {
                    $el: null,
                    mouseClick: function() {
                        the.controls.toggle.stop();
                        showNextItem();
                        the.controls.setSpriteOffset(this.$el, the.prefs.next_over_x);
                    },
                    mouseOver: function() {
                        the.controls.setSpriteOffset(this.$el, the.prefs.next_over_x);
                    },
                    mouseLeave: function() {
                        the.controls.setSpriteOffset(this.$el, the.prefs.next_static_x);
                    },
                    init: function() {
                        var that = this;
                        this.$el = $('.next', $ticker);
                        this.$el
							.click(function() {
							    that.mouseClick();
							    return false;
							})
							.hover(
								function() {
								    that.mouseOver();
								},
								function() {
								    that.mouseLeave();
								}
							);
                    }
                }
            };

            // define functions
            startTimeout = function(timeoutFunction, timeout, speed) {
                clearTimeout(timeout);
                timeout = setTimeout(timeoutFunction, speed);
            };

            putItemIntoInner = function() {
                // get text
                var $span;

                $item = $items[item_index];
                x_link = $("link", $item).text(); // fails on localhost with $.get, so using $.ajax instead

                // AB:HTML DECODE ON TEXT
                //x_title = $("title", $item).text(); // item_index + ' ' +
                x_title = $("title", $item).text().replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');

                x_description = $("description", $item).text();

                // put html into inner
                $a = $('<a></a>')
					.text(x_title)
					.attr("title", x_description) //AB: Link opens in new window
                //.attr("rel", "external");
					.attr("target", "_blank");
                $a[0].href = x_link;

                //$inner.html($a);

                $span = $('<span></span>');
                $span.text(prefs.prefix_str);
                $inner
				    .html($span)
				    .append($a);
            };

            showNextItem = function() {

                // inc index 
                item_index += 1;
                if (item_index >= item_index_max) {
                    item_index = 0;
                }

                // shrink inner
                $message.width(0);

                putItemIntoInner();

                // expand inner
                $message.width(full_width);
            };

            showPreviousItem = function() {

                // dec index 
                item_index -= 1;
                if (item_index < 0) {
                    item_index = item_index_max - 1;
                }

                // shrink inner
                $message.width(0);

                putItemIntoInner();

                // expand inner
                $message.width(full_width);
            };

            swipeNextItem = function() {
                var finishShowNext, revealInner;

                finishShowNext = function() {
                    // called by revealInner()

                    // then inc index 
                    //item_index += 1;
                    //if (item_index >= item_index_max) {
                    //	item_index = 0;
                    //}

                    // then pause and start again					
                    startTimeout(swipeNextItem, timeout, the.prefs.pause_speed);
                };

                revealInner = function() {
                    if ($message.innerWidth() < full_width) {
                        the.swipe_in_progress_flag = true;

                        $message.width($message.innerWidth() + the.prefs.wipe_increment);
                        startTimeout(revealInner, wipe_timeout, the.prefs.wipe_speed);
                    } else {
                        the.swipe_in_progress_flag = false;

                        // carry on if pause has not been chosen
                        if (the.play_chosen_flag) { // playing
                            finishShowNext();
                        }
                    }
                };

                // shrink inner
                $message.width(0);

                // inc index 
                item_index += 1;
                if (item_index >= item_index_max) {
                    item_index = 0;
                }

                putItemIntoInner();
                revealInner();
            };

            ajaxCallback = function(data) {
                the.insertMarkup($ticker);
                $message = $('.message', $ticker);
                $inner = $('.inner', $ticker);
                $items = $('item', data); //items = data.getElementsByTagName("item");

                // get size of message as target for inner
                full_width = $message.innerWidth();

                // get number of items, set as item_index_max
                item_index_max = $items.length;

                // attach handlers to control links
                the.controls.init($ticker);

                swipeNextItem();
            };

            // get feed json/xml
            // if no feed bug out, else continue
            $.ajax({
                type: "GET",
                url: prefs.xml_path,
                // cache : false,
                success: ajaxCallback,
                dataType: "xml"
            });

            //$.get(prefs.xml_path, callback, "xml"); // bug, returns a string, perhaps due to lack of mime type header of static file ?
        },
        insertMarkup: function($ticker) {
            $ticker
				.html("<div class='message'><div class='inner'></div></div>")
				.append("<div class='controls'><a href='#' class='toggle'></a><a href='#' class='previous'></a><a href='#' class='next'></a></div>");
            $('.toggle', $ticker).attr("title", this.prefs.pause_title);
            $('.previous', $ticker).attr("title", this.prefs.previous_title);
            $('.next', $ticker).attr("title", this.prefs.next_title);
        }
    };




    ais.social = {
        // v0.9
        /*
        div.line.social-bookmarks">
        a.delicious
        href="http://del.icio.us/post"
        span.icon
        delicious
        */
        selector_str: ".social-bookmarks",
        format: {
            delicious: { query: "?v=4&partner=[partner]&noui&url={url}&title={title}" },
            digg: { query: "?phase=2&partner=[partner]&url={url}&title={title}" },
            reddit: { query: "?url={url}&title={title}" },
            facebook: { query: "?u={url}" }, //&t={title}"}, // only need url
            stumbleupon: { query: "?url={url}&title={title}" }
        },
        init: function() {
            var 
                the,
                $bookmarks;
            the = this;

            $bookmarks = $("a", this.selector_str)
                .click(function() {
                    var 
                        class_str,
                        query_str,
                        url,
                        title,
                        href;

                    class_str = $(this).attr("class");
                    if (!class_str) {
                        return true;
                    }
                    url = encodeURIComponent(self.location.href);
                    title = encodeURIComponent($("title:first").html());
                    query_str = the.format[class_str].query;
                    if (!query_str) {
                        return true;
                    }
                    query_str = query_str.replace("{url}", url);
                    query_str = query_str.replace("{title}", title);

                    href = this.href + query_str;

                    // window.open($(this).attr('href'));

                    self.location.href = href;
                    return false;
                });

        }
    };


    $(document).ready(function() {
        ais.init();
    }); // eo:ready
})(jQuery);


// ftw is dis ? use comments please!
// fieldname, remainingname, maxchars
function CheckFieldLength(fn, rn, mc) {
    
    var len = fn.value.length;
    if (len > mc) {
        fn.value = fn.value.substring(0, mc);
        len = mc;
    }
    if (mc - len < 100) {
        if ( (mc - len) == 1 || (mc - len) == 0)
            document.getElementById(rn).innerHTML = '<strong><span style="color:red">' + (mc - len) + '</span> character remaining.</strong>';
        else
            document.getElementById(rn).innerHTML = '<strong><span style="color:red">' + (mc - len) + '</span> characters remaining.</strong>';
    }
    else
        document.getElementById(rn).innerHTML = '<strong>' + (mc - len) + ' characters remaining.</strong>';
}



  
//  http://del.icio.us/post?url=url_is_here&title=title_is_here
//  http://digg.com/submit?phase=2&url=url_is_here&title=title_is_here
//  http://www.facebook.com/share.php?u=url_is_here
//  http://www.google.com/bookmarks/mark?op=edit&bkmk=url_is_here
//  http://slashdot.org/bookmark.pl?title=title_is_here&url=url_is_here
//  http://www.stumbleupon.com/submit?url=url_is_here
//  http://technorati.com/faves?add=url_is_here
//  
//  http://www.stumbleupon.com/submit?url={url}&title={title}
//  http://friendfeed.com/share?url={url}&title={title}
//  http://technorati.com/faves/?add={url}
//  http://twitter.com/home?status={url}
//  
//  http://myjeeves.ask.com/mysearch/BookmarkIt?v=1.2&t=webpages&url={url}&title={title}
//http://www.backflip.com/add_page_pop.ihtml?url={url}&title={title}
//http://ballhype.com/post/url/?url={url}&title={title}
//http://bebo.com/c/share?Url={url}&Title={title}
//http://www.blinklist.com/index.php?Action=Blink/addblink.php&Url={url}&Title={title}
//http://blogmarks.net/my/new.php?mini=1&simple=1&url={url}&title={title}
//http://del.icio.us/post?v=4&partner=[partner]&noui&url={url}&title={title}
//http://digg.com/submit?phase=2&partner=[partner]&url={url}&title={title}
//http://www.diigo.com/post?url={url}&title={title}
//http://www.facebook.com/sharer.php?u={url}&t={title}
//http://cgi.fark.com/cgi/fark/submit.pl?new_url={url}&new_comment={title}
//http://bluedot.us/Authoring.aspx?u={url}&t={title}
//http://feedmelinks.com/categorize?from=toolbar&op=submit&url={url}&name={title}
//http://friendfeed.com/share?url={url}&title={title}
//http://www.furl.net/savedialog.jsp?p=1&u={url}&t={title}&r=&v=1&c=
//http://www.google.com/bookmarks/mark?op=add&bkmk={url}&title={title}
//http://www.kaboodle.com/grab/addItemWithUrl?url={url}&pidOrRid=pid=&redirectToKPage=true
//http://www.linkagogo.com/go/AddNoPopup?url={url}&title={title}
//http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&ro=false&summary=&source=
//https://favorites.live.com/quickadd.aspx?marklet=1&mkt=en-us&url={url}&title={title}&top=1
//http://ma.gnolia.com/bookmarklet/add?url={url}&title={title}
//http://www.mister-wong.com/index.php?action=addurl&bm_url={url}&bm_description={title}
//http://www.mixx.com/submit?page_url={url}
//http://multiply.com/gus/journal/compose/?body=&url={url}&subject={title}
//http://favorites.my.aol.com/ffclient/AddBookmark?url={url}&title={title}&favelet=true
//http://www.myspace.com/Modules/PostTo/Pages/?u={url}&t={title}&c=%20
//http://netvouz.com/action/submitBookmark?url={url}&title={title}&popup=no
//http://www.newsvine.com/_tools/seed&save?u={url}&h={title}
//http://www.propeller.com/submit/?U={url}&T={title}
//http://reddit.com/submit?url={url}&title={title}
//http://segnalo.com/post.html.php?url={url}&title={title}
//http://www.simpy.com/simpy/LinkAdd.do?href={url}&title={title}
//http://slashdot.org/bookmark.pl?url={url}
//http://www.spurl.net/spurl.php?url={url}&title={title}
//http://www.stumbleupon.com/submit?url={url}&title={title}
//http://tailrank.com/share/?link_href={url}&title={title}
//http://technorati.com/faves/?add={url}
//http://twitter.com/home?status={url}
//http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&u={url}&t={title}
//http://buzz.yahoo.com/submit?submitUrl={url}&submitHeadline={title}
//http://myweb2.search.yahoo.com/myresults/bookmarklet?u={url}&t={title}
//http://www.yardbarker.com/author/new/?pUrl={url}


//http://del.icio.us/post ?v=4&partner=[partner]&noui&url={url}&title={title}
//http://digg.com/submit  ?phase=2&partner=[partner]&url={url}&title={title}
//http://www.facebook.com/sharer.php  ?u={url}&t={title}
//http://www.stumbleupon.com/submit ?url={url}&title={title}
//http://reddit.com/submit  ?url={url}&title={title}

//http://mark.koli.ch/2009/02/howto-make-your-own-addthis-social-bookmarking-sharing-widget-thing.html


