// usage: log('inside coolFunc', this, arguments);
// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
  log.history = log.history || [];   // store logs to an array for reference
  log.history.push(arguments);
  if(this.console) {
    arguments.callee = arguments.callee.caller;
    var newarr = [].slice.call(arguments);
    (typeof console.log === 'object' ? log.apply.call(console.log, console, newarr) : console.log.apply(console, newarr));
  }
};

// make it safe to use console.log always
(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try
{console.log();return window.console;}catch(err){return window.console={};}})());


/* ---------------------------------------->>> EXTERNAL PLUG-INS <<<------------------------------------------ */

/**
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @author    Brian Cherne <brian@cherne.net>
*/
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:50,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}if(p==this){return false;}var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);


/**
 * jQuery Color Animations
 * Copyright 2007 John Resig
 * Released under the MIT and GPL licenses.
 */
(function(jQuery){jQuery.each(['backgroundColor','borderBottomColor','borderLeftColor','borderRightColor','borderTopColor','color','outlineColor'],function(i,attr){jQuery.fx.step[attr]=function(fx){if(fx.state==0){fx.start=getColor(fx.elem,attr);fx.end=getRGB(fx.end)}fx.elem.style[attr]="rgb("+[Math.max(Math.min(parseInt((fx.pos*(fx.end[0]-fx.start[0]))+fx.start[0]),255),0),Math.max(Math.min(parseInt((fx.pos*(fx.end[1]-fx.start[1]))+fx.start[1]),255),0),Math.max(Math.min(parseInt((fx.pos*(fx.end[2]-fx.start[2]))+fx.start[2]),255),0)].join(",")+")"}});function getRGB(color){var result;if(color&&color.constructor==Array&&color.length==3)return color;if(result=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))return[parseInt(result[1]),parseInt(result[2]),parseInt(result[3])];if(result=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))return[parseFloat(result[1])*2.55,parseFloat(result[2])*2.55,parseFloat(result[3])*2.55];if(result=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))return[parseInt(result[1],16),parseInt(result[2],16),parseInt(result[3],16)];if(result=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))return[parseInt(result[1]+result[1],16),parseInt(result[2]+result[2],16),parseInt(result[3]+result[3],16)];return colors[jQuery.trim(color).toLowerCase()]}function getColor(elem,attr){var color;do{color=jQuery.curCSS(elem,attr);if(color!=''&&color!='transparent'||jQuery.nodeName(elem,"body"))break;attr="backgroundColor"}while(elem=elem.parentNode);return getRGB(color)};var colors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);


// JSON parser
(function($){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},s={'array':function(x){var a=['['],b,f,i,l=x.length,v;for(i=0;i<l;i+=1){v=x[i];f=s[typeof v];if(f){v=f(v);if(typeof v=='string'){if(b){a[a.length]=','}a[a.length]=v;b=true}}}a[a.length]=']';return a.join('')},'boolean':function(x){return String(x)},'null':function(x){return"null"},'number':function(x){return isFinite(x)?String(x):'null'},'object':function(x){if(x){if(x instanceof Array){return s.array(x)}var a=['{'],b,f,i,v;for(i in x){v=x[i];f=s[typeof v];if(f){v=f(v);if(typeof v=='string'){if(b){a[a.length]=','}a.push(s.string(i),':',v);b=true}}}a[a.length]='}';return a.join('')}return'null'},'string':function(x){if(/["\\\x00-\x1f]/.test(x)){x=x.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c}c=b.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16)})}return'"'+x+'"'}};$.toJSON=function(v){var f=isNaN(v)?s[typeof v]:s['number'];if(f)return f(v)};$.parseJSON=function(v,safe){if(safe===undefined)safe=$.parseJSON.safe;if(safe&&!/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(v))return undefined;return eval('('+v+')')};$.parseJSON.safe=false})(jQuery);


// IE needs special treatment, once again
if (!Array.indexOf) {
    Array.prototype.indexOf = function (obj) {
        for (var i = 0; i < this.length; i++) {
            if (this[i] == obj) { return i; }
        } return -1;
    }
}

/* " */

/* ---------------------------------------->>> OWN PLUG-INS <<<------------------------------------------ */

// CSS Parser
// replace with jQuery UI class transitions as soon as they work in Safari (probably next release after 1.7)
(function ($) {
    $.fn.cssparser = function (e, opts) {
        var settings = jQuery.extend({
             title: '', // no title: search all files
             props_animate: [ 'width', 'height', 'top', 'left', 'right' ],
             props_static: [ 'z-index' ]
        }, opts);

        var regexp = new RegExp('(^|,)\\s*\\' + e + '\\s*(,|$)'),
            styles_animate = {}, styles_animate_arr = [ ], styles_static = {}, styles_static_arr = [ ],
            sheets = document.styleSheets;

        if (sheets.length == 0) return;

        for (var i = 0; i<sheets.length; i++) { // $.each not working properly in IE
            if (settings.title && (document.styleSheets[i].title != settings.title)) {
                continue;
            }
            $.each(document.styleSheets[i].cssRules || document.styleSheets[i].rules, function () {
                if (regexp.test(this.selectorText)) {
                    var prop = this.style.cssText.toLowerCase();
                    var props = prop.split(';');

                    $.each(props, function () {
                        if ($.inArray(this.split(':')[0].replace(/ /g, ''), settings.props_animate) != -1) { // check if property has to be animated
                            styles_animate_arr.push(this);
                        } else { // check if property has to be set
                            var checkprop = this;
                            $.each(settings.props_static, function () { // check each possible notation
                                if (checkprop.indexOf(this) >= 0) {
                                    styles_static_arr.push(checkprop);
                                }
                            })
                        }
                    });
                }
            });
        }

        $.fn.format = function (arg, opt) {
            var arr = [ ];
            $.each(arg, function () {
                var prop = '\'' + this.split(':')[0].replace(/ /g, '') + '\':\'' + this.split(':')[1];
                if (opt != 'static') {
                    prop = prop.replace(/ /g, '');
                }
                prop = prop + '\'';
                arr.push(prop);
            });

            var string =  '{' + arr.join(',') + '}';
            if (opt != 'static') {
                styles_animate = $.parseJSON(string);
            } else {
                styles_static = $.parseJSON(string);
            }
        }

        $.fn.format(styles_animate_arr);
        $.fn.format(styles_static_arr, 'static');

        styles = [ styles_animate, styles_static ];

        return styles;
    };
})(jQuery);


// hash operations (the hash component of the URL becomes a GET-style parameter list)
(function ($) {
    $.fn.hasher = function (operation, key, value, options) {
        if (operation == 'set' && !value) {
            operation = 'del';
        }
        var keyValueSeparator = '-';
        var assignmentSeparator = '.';
        var hashString;
        if (!(hashString = options.hashString)) {
            hashString = $.fn.hasher.hashString
            var hashStringFromLocation = $(location).attr('hash').replace(new RegExp('^\#?[' + assignmentSeparator + ']*'), '');
            if (hashStringFromLocation != hashString && decodeURIComponent(hashString) != hashStringFromLocation) {
                hashString = hashStringFromLocation;
            }
        }
        var hashAssignments = hashString ? hashString.split(assignmentSeparator) : [ ];
        var valueFound = false;
        var keyValueAssignment = key + keyValueSeparator + value;
        var keyAssignmentPattern = new RegExp('^' + key + '[' + keyValueSeparator + '](.*)');

        if (hashAssignments.length > 0) {
            switch (operation) {
            case 'set':
                for (var i = 0; i < hashAssignments.length; ++i) {
                    var hashAssignment = hashAssignments[i];
                    if (keyAssignmentPattern.exec(hashAssignment)) {
                        if (valueFound) {
                            hashAssignments.splice(i--, 1);
                        } else {
                            hashAssignments[i] = keyValueAssignment;
                            valueFound = true;
                        }
                    }
                }
                if (!valueFound) {
                    hashAssignments.push(keyValueAssignment)
                }
                var newHash = hashAssignments.join(assignmentSeparator);
                if (options.noLocationChange) {
                    return newHash;
                } else {
                    $.fn.hasher.setHash(newHash);
                }
                break;
            case 'del':
                for (var i = 0; i < hashAssignments.length; ++i) {
                    var hashAssignment = hashAssignments[i];
                    if (keyAssignmentPattern.exec(hashAssignment)) {
                        hashAssignments.splice(i--, 1);
                    }
                }
                var newHash = hashAssignments.join(assignmentSeparator);
                if (options.noLocationChange) {
                    return newHash;
                } else {
                    $.fn.hasher.setHash(newHash);
                }
                break;
            case 'get':
                var result = options.collect ? [ ] : value;
                var match;
                $.each(hashAssignments, function (i, hashAssignment) {
                    if ((match = keyAssignmentPattern.exec(hashAssignment))) {
                        if (options.collect) {
                            result.push(match[1]);
                        } else {
                            result = match[1];
                        }
                        return options.collect;
                    }
                });
                return result;
            }
        } else {
            switch (operation) {
            case 'set':
                if (options.noLocationChange) {
                    return keyValueAssignment;
                } else {
                    $.fn.hasher.setHash(keyValueAssignment);
                }
                break;
            case 'get':
                return options.collect ? [ ] : '';
            }
        }
    }
    $.fn.hasher.setHash = function (newHashString) {
        $.fn.hasher.hashString = newHashString;
        $(location).attr('hash', newHashString);
    }

    $.fn.hashSet = function (key, value, noLocationChange) {
        return $.fn.hasher('set', key, value, { noLocationChange: noLocationChange });
    }

    $.fn.hashSetAll = function (key, values, noLocationChange) {
        var keyValueSeparator = '-';
        var assignmentSeparator = '.';
        var separator = '', combinedValue = '';
        $.each(values, function (i, value) {
            combinedValue += separator;
            combinedValue += value;
            separator = assignmentSeparator + key + keyValueSeparator;
        });
        return $.fn.hasher('set', key, combinedValue, { noLocationChange: noLocationChange });
    }

    $.fn.hashGet = function (key, defaultValue, hashString) {
        return $.fn.hasher('get', key, defaultValue, { hashString: hashString });
    }

    $.fn.hashGetAll = function (key, hashString) {
        return $.fn.hasher('get', key, null, { hashString: hashString, collect: true });
    }

    $.fn.hashDel = function (key, noLocationChange) {
        return $.fn.hasher('del', key, null, { noLocationChange: noLocationChange });
    }
})(jQuery);


// References filter
(function ($) {
    // attach click handler to pager links
    $.fn.pager = function (currentPage) {
        var currentStartIndex = $.fn.references.startIndex;
        $('a', $.fn.references.elements.pager).bind('click', function (event) {
            var startIndexFromQuery = this.href.replace(new RegExp('^[^#]*[?](?:.*&)?' + startIndexSelector + '=([0-9]+)(?:&.*)?'), '$1');
            var hashString = this.href.replace(/^.*?#/, '');
            var startIndex = parseInt($.fn.hashGet(startIndexSelector, startIndexFromQuery, hashString), 10) || 1;
            $.fn.references.startIndex = startIndex;
            $.fn.executeFilter();
            $.fn.hashSet('start', startIndex);
            event.preventDefault();
        });
    };

    $.fn.executeFilter = function () {
        // if references data not there yet, get data and repeat this function when it's there
        if (!$.fn.references.cachedReferencesData) {
            $.getJSON(referencesUrl, function (referencesData) {
                $.fn.references.cachedReferencesData = referencesData;
                $.fn.executeFilter();
            });
            return;
        }
        // do the actual filtering if not done yet
        if (!$.fn.references.included) {
            $.fn.filterReferencesData();
        }
        // show the results
        $.fn.displayFilteredReferences();
    };

    $.fn.filterReferencesData = function () {
        var chosenTags = $.fn.references.chosenTags;

        // reset all activated filters optically
        $.fn.references.elements.filters.find('li.current').removeClass('current');

        // structure chosen tags
        var chosenTagsGroupedByCategory = { };
        var chosenTagNames = [ ];
        $.each(chosenTags, function (i, chosenTag) {
            if (chosenTag) {
                var filterLink = $.fn.references.filterLinks[chosenTag];
                if (!filterLink) {
                    return true;
                }
                // arrange filter array
                var categoryIndex = $.fn.references.elements.filters.index(filterLink.parents('ul'));
                if (!chosenTagsGroupedByCategory[categoryIndex]) {
                    chosenTagsGroupedByCategory[categoryIndex] = [ ];
                }
                chosenTagsGroupedByCategory[categoryIndex].push(chosenTag);
                // show selected filters
                filterLink.parent('li').addClass('current');
                // create string with selected filters
                chosenTagNames.push($.trim(filterLink.text()));
            }
        });

        // show filters on page and change hash
        var filterDisplayText = chosenTagNames.slice(0, maxDisplayedTags).join(filterDisplaySeparator);
        $.fn.references.elements.filterDisplay.text(filterDisplayText);
        if (chosenTagNames.length > maxDisplayedTags) {
            $.fn.references.elements.filterDisplay
                .append(filterDisplaySeparator + moreTagsIndicator);
        }
        $.fn.hashSetAll('tag', $.map(chosenTags, $.fn.encode));

        // toggle reset link
        if (chosenTagNames.length > 0) {
            $.fn.references.elements.resetContainer.removeClass('hide');
        } else {
            $.fn.references.elements.resetContainer.addClass('hide');
        }

        // evaluate the filter to find which references are included
        var referencesData = $.fn.references.cachedReferencesData;
        var excluded = { };
        // loop trough items and add to excluded if filter critera are not fulfilled
        $.each(referencesData.items, function (referenceIndex, referenceData) {
            $.each(chosenTagsGroupedByCategory, function (categoryIndex, chosenTagsInCategory) {
                if (chosenTagsInCategory.length) {
                    var noCategoryTagsFound = true;
                    $.each(chosenTagsInCategory, function (tagIndex, tag) {
                        if ((referenceData.tags[categoryIndex].indexOf(tag) >= 0)) {
                            noCategoryTagsFound = false;
                            return false;
                        }
                    });
                    if (noCategoryTagsFound) {
                        excluded[referenceIndex] = true;
                    }
                }
            });
        });
        // collect all not-excluded references
        var included = [ ];
        $.each(referencesData.items, function (referenceIndex, referenceData) {
            if (!excluded[referenceIndex]) {
                included.push(referenceIndex);
            }
        });
        $.fn.references.included = included;
    };

    $.fn.displayFilteredReferences = function (calledViaTimer) {
        if (!calledViaTimer) {
            if (!$.fn.displayFilteredReferences.timer) {
                $.fn.references.elements.progressBar.animate(
                    { width: "100%" },
                    {
                        queue: true,
                        duration: $.fn.references.progressBarDelay,
                        complete: function () {
                                $.fn.references.elements.progressBar.css("width", "0");
                            }
                    });
                $.fn.displayFilteredReferences.timer = setTimeout(function () {
                    $.fn.displayFilteredReferences(true);
                }, $.fn.references.progressBarDelay - 1);
            }
            return;
        }

        var startIndex = $.fn.references.startIndex;

        // clear references display area
        $.fn.references.elements.refs.html('');

        // create reference items
        var referencesData = $.fn.references.cachedReferencesData;
        var chosenTags = $.fn.references.chosenTags;
        var included = $.fn.references.included;
        var totalReferences = included.length;
        $.fn.references.referencesPerPage = itemsPerPage;
        startIndex = Math.max(1, Math.min(startIndex, totalReferences));
        var selectedPage = Math.ceil((startIndex - 1) / itemsPerPage) + 1;
        var maxPage = selectedPage + Math.floor((totalReferences - startIndex) / itemsPerPage);
        var endIndex = Math.min(startIndex + itemsPerPage - 1, totalReferences);

        var colCounter = 0, cssClass;

        if (totalReferences) {
            $.each(included.slice(startIndex - 1), function (refCounter, referenceIndex) {
                if (refCounter >= itemsPerPage) {
                    return false;
                }
                var referenceData = referencesData.items[referenceIndex];
    
                // render item
                var href = referenceData.url;
                var tagParameters = [ resetTagsSelector ];
                $.each(chosenTags, function (i, chosenTag) {
                    tagParameters.push(tagSelector + "=" + $.fn.encode(chosenTag));
                });
                href = href + (tagParameters.length ? '?' + tagParameters.join('&') : '');
                        
                $('<li class="col c20" id="el' + referenceIndex + '"><a href="' + href + '"></a></li>')
                    .appendTo($.fn.references.elements.refs);
    
                var el = $('#el' + referenceIndex + ' a');
                // render image, title and description
                if (referenceData.img) {
                    $('<img/>').attr('src', referenceData.img)
                        .appendTo(el);
                }
                var spanEl = $('<span/>');
                spanEl.appendTo(el);
                $('<span class="title"/>').text(/*itemNumber + 1 + ': ' + */ $.fn.normalizeDashes(referenceData.brand))
                    .appendTo(spanEl);
                $('<span class="small"/>').text($.fn.normalizeDashes(referenceData.desc))
                    .appendTo(spanEl);
            });
        } else {
            $('<p>' + text_noResults + '</p>').appendTo($.fn.references.elements.refs);
        }

        // create pager links
        $.fn.references.elements.pager.html('');
        if (maxPage > 1) {
            if (selectedPage > 1) {
                var hashValue = $.fn.hashSet('start', Math.max(startIndex - itemsPerPage, 1), true);
            }
            for (var pageNumber = 1; pageNumber <= maxPage; ++pageNumber) {
                if (pageNumber == selectedPage) {
                    $('<li><span>' + pageNumber + '<\/span><\/li>')
                        .appendTo($.fn.references.elements.pager);
                } else {
                    var hashValue = $.fn.hashSet('start', Math.max(startIndex + (pageNumber - selectedPage) * itemsPerPage, 1), true);
                    $('<li><a href="#' + hashValue + '">' + pageNumber + '<\/a><\/li>')
                        .appendTo($.fn.references.elements.pager);
                }
            }
        }
        $.fn.pager(selectedPage);
        $.fn.references.elements.progressBar.stop(false, true);
        $.fn.displayFilteredReferences.timer = null;
    };

    $.fn.getCSSClass = function (i) {
        var mod = i % 4, cssClass;
        switch (mod) {
        case 0:
            cssClass = 'contl';
            break;
        case 1:
            cssClass = 'contml';
            break;
        case 2:
            cssClass = 'contmr';
            break;
        default:
            cssClass = 'contr';
            break;
        }
        return cssClass;
    };

    $.fn.getTagFromLink = function (link) {
        var tag = null;
        $.each($(link.attr('class').split(/\s+/)), function (i, className) {
            if ((tag = $.fn.getTagFromSelector(className))) {
                return false;
            }
        });
        return tag;
    };

    $.fn.getTagFromSelector = function (tagAsSelector) {
        var match;
        if ((match = tagAsSelector.match(new RegExp("^" + tagSelector + "-(.+)")))) {
            return $.fn.decode(match[1]);
        } else {
            return null;
        }
    }

    $.fn.normalizeDashes = function (text) {
        return text.replace(/(\s|\n|<br>)-(\s|\n|<br>)/g, "$1\u2013$2");
    };

    $.fn.decode = function (text) {
        var decoded = decodeURIComponent(text.replace(/[+]/g, ' '));
        if (decoded.match(/%[0-9A-F]{2}/)) {
            decoded = decodeURIComponent(decoded.replace(/[+]/g, ' '));
        }
        return decoded;
    }

    $.fn.HEX_DIGITS = '0123456789ABCDEF';
    $.fn.encode = function (text) {
        var result = '';
        for (var i = 0; i < text.length; ++i) {
            var c = text.charAt(i);
            switch (c) {
            case '.':
            case ':':
            case '-':
            case '+':
            case '%':
            case '/':
            case '#':
            case '?':
            case '"':
            case '\'':
                result += '%';
                result += "25";
                c = c.charCodeAt(0);
                result += $.fn.HEX_DIGITS.charAt((c >> 4) & 0xF);
                result += $.fn.HEX_DIGITS.charAt(c & 0xF);
                break;
            case ' ':
                result += '+';
                break;
            default:
                result += c;
                break;
            }
        }
        return result;
    }

    $.fn.references = function () {
        $.fn.references.elements = {
            refs: $('#refs ul'),
            pager: $('#pager'),
            filters: $('#filter ul'),
            filterDisplay: $('#filterDisplay'),
            resetLink: $('#resetLink'),
            resetContainer: $('#resetCols'),
            progressBar: $('#progress')
        };
        $.fn.references.progressBarDelay = 200;

        // check if we need to filter
        var chosenTags = $.map($.fn.hashGetAll('tag'), $.fn.decode);
        var startIndex = parseInt($.fn.hashGet(startIndexSelector), 10);
        var filterVisibility = $.fn.hashGet(filterVisibilitySelector);

        $.fn.references.referencesPerPage = itemsPerPage;
        $.fn.references.chosenTags = chosenTags;
        $.fn.references.startIndex = startIndex || 1;

        if (chosenTags.length || startIndex || filterVisibility) {
            $.fn.executeFilter();
        } else {
            $.fn.pager(1);
        }

        // tabulate filter links by tag and attach click handlers
        $.fn.references.filterLinks = { };
        $.each($('a', $.fn.references.elements.filters), function (i, filterLink) {
            filterLink = $(filterLink);
            var tag = $.fn.getTagFromLink(filterLink);
            $.fn.references.filterLinks[tag] = filterLink;
            filterLink.bind('click', function (event) {
                var thisFilterLink = $(this);
                var linkTag = $.fn.getTagFromLink(thisFilterLink);
                var text = thisFilterLink.text();
                var chosenTags = $.fn.references.chosenTags;
                var chosenTagIndex;
                if ((chosenTagIndex = chosenTags.indexOf(linkTag)) >= 0) {
                    chosenTags.splice(chosenTagIndex, 1);
                    // remove blue text colour - Mantis 25196
                    thisFilterLink.blur();
                } else {
                    chosenTags.push(linkTag);
                }
                $.fn.references.included = null;
                $.fn.references.startIndex = 1;
                $.fn.hashDel(startIndexSelector);
                $.fn.executeFilter();
                event.preventDefault();
            });
        });

        // attach click handler to reset link
        $.fn.references.elements.resetLink.bind('click', function (event) {
            $.fn.references.elements.resetContainer.addClass('hide');
            $.fn.references.chosenTags = [ ];
            $.fn.references.included = null;
            $.fn.references.startIndex = 1;
            $.fn.executeFilter();
            event.preventDefault();
        });

        // hide/show filter and set text for toggle filter link
        if (!filterVisibility) {
            filterVisibility = 'hidden';
        }
        $('#filter').attr('class', filterVisibility);
        switch (filterVisibility) {
        case 'hidden':
            $('#toggle').removeClass("expanded").html(text_show + "<span></span>");
            break;
        case 'expanded':
            $('#toggle').addClass("expanded").html(text_hide + "<span></span>");
            break;
        }

        // attach click handler to toggle filter link
        $('#toggle').click(function (event) {
            if (!$(this).hasClass('expanded')) {
                $(this).addClass('expanded').html(text_hide + "<span></span>");
                $('#filter').stop(false,true).slideDown();
                $.fn.hashSet(filterVisibilitySelector, 'expanded');
                if (!$.fn.hashGet('tag')) {
                    $.fn.executeFilter();
                }
            } else {
                $(this).removeClass('expanded').html(text_show + "<span></span>");
                $('#filter').stop(false,true).slideUp();
                $.fn.hashSet(filterVisibilitySelector, 'hidden');
            }
            event.preventDefault();
        });

        // prefetch references data
        $.getJSON(referencesUrl, function (referencesData) {
            $.fn.references.cachedReferencesData = referencesData;
/* preload images? Better not, we need the first page to be ready quickly
            $.each(referencesData.items, function (referenceIndex, referenceData) {
                var preloadedImage = new Image();
                preloadedImage.src = referenceData.img;
            });
*/
        });
    };
})(jQuery);


/* ---------------------------------------->>> EXECUTE WHEN READY <<<------------------------------------------ */

$(function () { //document ready

    // ---------------------------------------------------------------------- //
    // META NAVIGATION
    
    /*if (jQuery.browser.msie && jQuery.browser.version < 7) {
        $('#meta-countries, #meta-search label').bind("customHoverClick", function(){
            $(this).toggleClass('hover');
        }).bind("click", function(){
            $(this).trigger("customHoverClick");
        });
    }*/

    // Search
    
    /*
    //hide search field on load
    $('#meta-search div').hide();

    // show field
    $.fn.showsearch = function (e) {
        $('#meta-search div').show();
        $('#meta-search label').hide();
        if (e.attr('type') != 'text') {
            $('#meta-search input[type=text]').focus();
        }
    }
    $('#meta-search input').focus(function () {
        $.fn.showsearch($(this));
    });*/

    // toggle field
    /*
    $(document).bind('click', function (e) {
        var el = $(e.target);
        
        if(!$('#meta-search div').is(':hidden')){
            if (!(el.parents().is('#meta-search') || el.parents().is('ul.skip'))) {
                $('#meta-search div').hide();
                $('#meta-search label').show();
            }
        }
        if ((el.is('#meta-search label') || el.parents().is('ul.skip'))) {
            $.fn.showsearch($(this));
        }
    });
  */
  
    // Countries
  /*
    if (jQuery.browser.msie && jQuery.browser.version < 7) {
        $('#nav-meta li').hover(function () {
            $(this).addClass('hover');
        }, function () {
            $(this).removeClass('hover');
        });
    }
  */
  
  /*
    // ---------------------------------------------------------------------- //
    // OVERLAYS

    // IE and FF2 aren't capable of animating alpha-transparency properly

    if (!((jQuery.browser.msie && jQuery.browser.version < 9) || (jQuery.browser.mozilla && parseFloat(jQuery.browser.version) < 1.9))) {
        $('a.overlay').addClass('overlay-js');
        $('a.overlay-js').hoverIntent(function () {
                $('.overlay', this).fadeIn(200);
                $('span', this).animate({'color': '#2FA4FF'}, 200);
                setTimeout(function () { $('span', this).css({ 'color': '#2FA4FF' }); }, 200);
            }, function () {
                $('.overlay', this).fadeOut(200);
                $('span', this).animate({ 'color': '#333' }, 200);
                setTimeout(function () { $('span', this).css({'color':'#333'}); }, 200);
        });
    }
    */

    // ---------------------------------------------------------------------- //
    // CONTENT

    // References
    if ($('#refs').length) {
        $.fn.references();
    }

    // Slideshow
    //$('.slideshow').slideshow();

    // ---------------------------------------------------------------------- //
    // LOCATION OVERVIEW
    var locations = {
            elements: [],
            c: 0,
            row: -1,
            height: 0
        }
        
    // Get highest element by group
    $('#locations div.location').each(function(){
        if (locations.c % 3 == 0) {
            locations.c = 0;
            locations.height = 0;
            locations.row++;
        }
        var el = $(this),
            height = el.height();
        
        if (height > locations.height) {
            locations.height = height;
        }
        
        if (!locations.elements[locations.row]) {
            locations.elements[locations.row] = [];
        }
        locations.elements[locations.row]['height'] = locations.height;
        if (!locations.elements[locations.row]['elements']) {
            locations.elements[locations.row]['elements'] = [];
        }
        locations.elements[locations.row]['elements'].push(el);
        
        locations.c++;  
    });

    // Change heights accordingly
    $.each(locations.elements, function(i, row){
        var height = row['height'];
        $.each(row['elements'], function(){
            $(this).height(height);
        });
    });
    

    // ---------------------------------------------------------------------- //
    // TABS
    $('.tabs').each(function(){
        var el = $(this),
            nav = el.find('.tabs-nav'),
            links = nav.find('a'),
            content = el.find('.tab-content'),
            current = content.index($('.tab-content.current')),
            isRoute = el.is("#route");
        
        if(isRoute) {
          content.hide()
        }
        
        links.click(function(e){
          e.preventDefault();
          
          
            var link = $(this),
                i = links.index(link);
      if (!isRoute){
            if (i == current) return false;
            
            el.find('.current').removeClass('current');
            link.parent().addClass('current');
            
            content.hide().removeClass('current');
            $(content.get(i)).show().addClass('current');
            }else{
               link.parent().toggleClass("current");
               content.hide().removeClass("current");
               $(content.get(i)).toggle().toggleClass("current");
            }
            current = i;
        });
    });
    
    
    /*---------------------------------------------------------------------------------------
    NeB, 2011-11-14
    prev/next links of slider on home page:
    position is adjusted according to window width
    ---------------------------------------------------------------------------------------*/
    
    /* Adjust position */
    function adjustArrows(width) {
      width = parseInt(width);
      if(width > 1028){
        var d = (-1)*(width-965)/4;
        $('a.controls.prev').css('left', Math.round(d));
        $('a.controls.next').css('right', Math.round(d));
      }
      return true;
  }
  
    /*---------------------------------------------------------------------------------------
    RoW, 2012-01-11
    footer on the homepage:
    position is adjusted according to window width (for small displays)
    ---------------------------------------------------------------------------------------*/
  function adjustKeyVisual(height, $wrapper) {
    // If there is enough space, move keyVisual bottom
    if (height > $wrapper.outerHeight())
    {
      var margin = (height - $wrapper.outerHeight()) * 0.4;
      console.log(margin);
      $("#keyvisual.home").css('margin-top', Math.round(margin));
    }
    // If there is not enough space, move keyVisual top
    else
    {
      $("#keyvisual.home").css('margin-top', 0);
    }
    
    return true;
  }
  
    function getMaxCallToActionOffset() {
      var maxCallToActionOffset = 0;
    $("#keyvisual.home li").each(function() {
      var $li = $(this);
      
      var isVisible = $li.is(":visible");
      if(!isVisible)
        $li.show();
      
      var $button = $li.find(".callToAction");
      var topOffset = $button.offset().top + $button.height() + 20; // ButtonOffset + ButtonHeight + Margin
      if(topOffset > maxCallToActionOffset)
        maxCallToActionOffset = topOffset;
      
      if(isVisible)
        $li.hide();
    });
    
    return maxCallToActionOffset;
    }
    
  function adjustFooterPosition(height, $wrapper, maxPadding, maxCallToActionOffset) {
    var constFooterVisibility = 20; // Must be visible if possible
    
    var currentPadding = parseInt($wrapper.css("padding-bottom"), 10);

    // if there is not enough space, move footer more to top until maxCallToActionOffset is reached
    if(height - $("#footer").offset().top < constFooterVisibility -1 && $("#teaserBadge").offset().top > maxCallToActionOffset)
    {
      var difference = $("#teaserBadge").offset().top - maxCallToActionOffset;
      if(difference > constFooterVisibility - (height - $("#footer").offset().top))
        difference = constFooterVisibility - (height - $("#footer").offset().top);
      var newPadding = currentPadding - difference;

      $wrapper.css("padding-bottom", Math.round(newPadding));
    }
    // if there is enough space, move footer more to bottom
    else if(currentPadding < maxPadding && height - $("#footer").offset().top > constFooterVisibility)
    {
      var newPadding = currentPadding + (height - $("#footer").offset().top - constFooterVisibility);
      if(newPadding > maxPadding)
        newPadding = maxPadding;
      
      $wrapper.css("padding-bottom", Math.round(newPadding));
    }
    
    return true;
  }
  
  /* Trigger on load and on resize */
  $(function() {
      var $wrapper = $("#wrapper > .wrapper");
      var maxPadding = parseInt($wrapper.css("padding-bottom"), 10);
      var maxCallToActionOffset = getMaxCallToActionOffset();
      var height = $(window).height();

      adjustArrows($(window).width());
      if($("#teaserBadge").length)
      {
        adjustKeyVisual(height, $wrapper);
        adjustFooterPosition(height, $wrapper, maxPadding, maxCallToActionOffset);
      }

      $(window).resize(function() {
          adjustArrows($(this).width());
          if($("#teaserBadge").length)
          {
            adjustKeyVisual($(this).height(), $wrapper);
            adjustFooterPosition($(this).height(), $wrapper, maxPadding, maxCallToActionOffset);
          }
      });
  });
  
    
});


//home slider

(function($){
  if ($("#keyvisual.home").length) {
    var $slider, $slides, slideTotal, $activeSlide, $next, $prev, gogogo;
    
    $slider = $("#keyvisual.home").find("ul");
    $slides = $slider.find("li");
    $activeSlide = $slides.eq(0);
    
    slideTotal = $slides.length;
    
    $next = $("a.controls.next");
    $prev = $("a.controls.prev");
    
    $slides.not($activeSlide).hide();
    
    $slides.each(function(i){
      $(this).css("z-index", $slides.length - i);
    });
    
    gogogo = function(e){
      e.preventDefault();
      var $upcoming;
      
      var $that = $(this);
      if ($that.is(".next")) {
        $upcoming = $activeSlide.next().length ? $activeSlide.next() : $slides.eq(0);
      } else {
        $upcoming = $activeSlide.prev().length ? $activeSlide.prev() : $slides.last();
      }
      
      $activeSlide.stop(false, true).fadeOut(800);
      $upcoming.stop(false, true).fadeIn(800);
      
      $activeSlide = $upcoming;
    };
  
    $next.click(gogogo);
    $prev.click(gogogo);
  }
})(jQuery);


// toggle box
(function($) {
    $(function() {
        $('.togglebox-container > .togglebox-link').click(function() {
            $(this).hide();
            $(this).next('.togglebox-content').toggle();
        });
    });
//IE
if( $.browser.msie && $.browser.version.substring(0, 2) == "8." ) {
  $("body").addClass("ie8")
}

})(jQuery);
