var TNTCORP = (function () {

    var CONSTANTS = {
        // CSS selectors and classes
        MAP_SELECT_SELECTOR : 'select.tt_map-select',
        MULTI_SELECT_SELECTOR : 'select.tt_multi-select',
        SUBMIT_SELECTOR : 'input.tt_submit',
        LANDING_PAGE_SLIDE_SELECTOR : 'ul.tt_landing-page-slides',
        LANDING_PAGE_ACTIVE_CLASS : 'tt_active-item',
        LANDING_PAGE_CTA_ROW_SELECTOR : 'div.tt_landing-page-cta-row',
        CTA_SELECTOR : 'div.tt_cta',
        CTA_IMAGE_SELECTOR : 'div.tt_cta-image',
        // Text nodes
        OPTION_STATE_OR_AREA : 'State or Area',
        // World map coordinates
        MAP_COORDINATES_SCALED : {},
        MAP_MARKER_SIZE : 8,
        MAP_MARKER_SCALED_SIZE : 6,
        MAP_SCALE_FACTOR : 0.627
    };

    /**
     * Application code. No string literals (other than object property names) and magic numbers.
     *
     * @author eric@techtribe.nl
     */

    var DOC = document;

    /**
     * Get the fragment identifier (if any) from an URI reference.
     *
     * @param {String} uriReference
     *     URI reference.
     * @returns {String}
     *     Returns the fragment identifier on success or the empty string on failure.
     */
    function getFragmentIdentifier(uriReference) {
        var parts = uriReference.split('#');
        return (2 == parts.length) ? parts[1] : '';
    }

    function getCtaBoxLink(element) {
        var heading,
            link,
            href;
        heading = element.getElementsByTagName('H2');
        if (1 == heading.length) {
            link = heading[0].getElementsByTagName('A');
            if (1 == link.length) {
                href = link[0].href;
                if (href) {
                    return href;
                }
            }
        }
        return '';
    }

    /**
     * Make a CTA clickable if its heading contains a link.
     */
    function setCtaBoxLink() {
        var href = getCtaBoxLink(this);
        if (href) {
            window.location = href;
        }
    }

    // document ready handler
    jQuery(document).ready(function () {

        /**
         * Generate the coordinates for the small map.
         */
        if (TNTCORP['MAP_COORDINATES']) {
            (function () {
                var data = TNTCORP['MAP_COORDINATES'],
                    key,
                    coordinates,
                    factor,
                    offset,
                    item;
                if ('string' == typeof data) {
                    factor = CONSTANTS['MAP_SCALE_FACTOR'];
                    coordinates = jQuery.parseJSON(data);
                    offset = (CONSTANTS['MAP_MARKER_SCALED_SIZE'] / 2);
                    for (key in coordinates) {
                        if (coordinates.hasOwnProperty(key)) {
                            item = coordinates[key];
                            CONSTANTS['MAP_COORDINATES_SCALED'][key] = [
                                Math.round((item[0] * factor) - offset),
                                Math.round((item[1] * factor) - offset)
                            ];
                        }
                    }
                    offset = (CONSTANTS['MAP_MARKER_SIZE'] / 2);
                    for (key in coordinates) {
                        if (coordinates.hasOwnProperty(key)) {
                            item = coordinates[key];
                            coordinates[key] = [
                                Math.round(item[0] - offset),
                                Math.round(item[1] - offset)
                            ];
                        }
                    }
                    CONSTANTS['MAP_COORDINATES'] = coordinates;
                }
            }());
        }

        /**
         * Homepage tabs (from scratch).
         */
        jQuery(CONSTANTS['LANDING_PAGE_SLIDE_SELECTOR']).each(function () {
                        var links = this.getElementsByTagName('A'),
                length = links.length,
                trigger,
                map = {},
                counter = 0,
                locationFragment = getFragmentIdentifier(window.location.href),
                fragment,
                rel,
                currentSlide,
                currentTrigger,
                currentTriggerClass = CONSTANTS['LANDING_PAGE_ACTIVE_CLASS'],
                defaultSlide,
                defaultTrigger;
            while (length--) {
                trigger = links[length];
                fragment = getFragmentIdentifier(trigger.href);
                if (fragment) {
                    rel = DOC.getElementById(fragment);
                    if (rel) {
                        defaultTrigger = jQuery(trigger.parentNode);
                        defaultSlide = rel.style;
                        defaultSlide.display = 'none';
                        map[fragment] = {
                            trigger : defaultTrigger,
                            target : defaultSlide
                        };
                        trigger.onclick = function (e) {
                             
                            var item = map[getFragmentIdentifier(this.href)];
                            if(e)e.preventDefault();
                            currentSlide.display = 'none';
                            currentSlide = item.target;
                            currentSlide.display = '';
                            currentTrigger.removeClass(currentTriggerClass);
                            currentTrigger = item.trigger;
                            currentTrigger.addClass(currentTriggerClass);
                         return false;
                        };
                        counter++;
                    }
                }
            }
            if (locationFragment) {
                if (map.hasOwnProperty(locationFragment)) {
                    currentSlide = map[locationFragment].target;
                    currentTrigger = map[locationFragment].trigger;
                }
            }
            if (!locationFragment || !currentSlide) {
                currentSlide = defaultSlide;
                currentTrigger = defaultTrigger;
            }
            currentSlide.display = '';
            currentTrigger.addClass(currentTriggerClass);
        });

        /**
         * Initialize CTAs:
         * - unify height of CTAs in same row
         * - make whole CTA clickable if the heading contains a link
         */
        jQuery(CONSTANTS['LANDING_PAGE_CTA_ROW_SELECTOR']).each(function () {
            var ctas = jQuery(this).find(CONSTANTS['CTA_SELECTOR']),
                images = ctas.find(CONSTANTS['CTA_IMAGE_SELECTOR']);
            images.hide();
            ctas.each(function () {
                var href = getCtaBoxLink(this);
                if (href) {
                    this.style.cursor = 'pointer';
                    this.onclick = setCtaBoxLink;
                }
            });
            jQuery(window).load(function () {
                var height = 0;
                ctas.each(function () {
                    var cssHeight = jQuery(this).height();
                    if (cssHeight > height) {
                        height = cssHeight;
                    }
                });
                ctas.each(function () {
                    this.style.height = height + 'px';
                });
                images.show();
            });
        });

        /**
         * Pretty submit buttons.
         * Replaces INPUT elements of TYPE 'submit' with hyperlinks that submit the form onclick.
         * If the submit button has a NAME, a hidden INPUT field with the name/value pair of
         * the original button is appended to the form.
         */
        jQuery(CONSTANTS['SUBMIT_SELECTOR']).each(function () {
            var form = this.form,
                button = DOC.createElement('A'),
                text = DOC.createElement('SPAN'),
                value = this.value,
                name = this.name;
            text.appendChild(DOC.createTextNode(value));
            button.href = '#';
            button.className = this.className;
            button.appendChild(text);
            this.parentNode.replaceChild(button, this);
            button.onclick = function () {
                var field;
                if (name) {
                    field = DOC.createTextNode('INPUT');
                    field.type = 'hidden';
                    field.name = name;
                    field.value = value;
                    form.appendChild(field);
                }
                form.submit();
            };
        });

        /**
         * Generate world map highlighting from SELECT elements with
         * the CSS class defined in CONSTANTS['MAP_SELECT_CLASS'].
         */
        jQuery(CONSTANTS['MAP_SELECT_SELECTOR']).each(function () {
            var select = this,
                value = this.value,
                form = select.form,
                map = DOC.createElement('DIV'),
                marker = DOC.createElement('DIV'),
                markerStyle = marker.style,
                coordinates = CONSTANTS[
                    DOC.getElementById('content') ?
                        'MAP_COORDINATES_SCALED' :
                        'MAP_COORDINATES'
                    ];
            map.className = 'tt_world-map';
            if(coordinates[value][0]>0 || coordinates[value][0]>0)
            marker.className = 'tt_map-marker';
            else marker.className = '';
     
            markerStyle.left =  coordinates[value][0] + 'px';
            markerStyle.top = coordinates[value][1] + 'px';
            map.appendChild(marker);
            form.appendChild(map);

            select.onchange = function () {
                var value = this.value;
                if(coordinates[value][0]>0 || coordinates[value][0]>0)
                marker.className = 'tt_map-marker';
                else marker.className = '';
                    
                markerStyle.left = coordinates[value][0] + 'px';
                markerStyle.top = coordinates[value][1] + 'px';
            };
        });

        /**
         * Generate conditional SELECT elements from the OPTGROUP children
         * of master SELECT elements with the CSS class defined in
         * CONSTANTS['MULTI_SELECT_CLASS'].
         * All related SELECT elements inherit the form control NAME of the
         * master SELECT element, but only one of them will be successful
         * (i.e. has a non-empty NAME value and is not DISABLED).
         */
        jQuery(CONSTANTS['MULTI_SELECT_SELECTOR']).each(function () {
            var original = this,
                name = this.name,
                fragment = DOC.createDocumentFragment(),
                hash = {},
                relation;
            jQuery(this).children('optgroup').each(function () {
                var labelNode = DOC.createElement('LABEL'),
                    select = DOC.createElement('SELECT'),
                    defaultOption = DOC.createElement('OPTION'),
                    relatedOption = DOC.createElement('OPTION'),
                    selectedOption,
                    groupLabel;
                groupLabel = this.label;
                hash[groupLabel] = select;
                select.name = original.name;
                defaultOption.appendChild(DOC.createTextNode(CONSTANTS['OPTION_STATE_OR_AREA']));
                defaultOption.value = '';
                select.appendChild(defaultOption);
                labelNode.appendChild(select);
                relatedOption.appendChild(DOC.createTextNode(groupLabel));
                relatedOption.value = groupLabel;
                fragment.appendChild(labelNode);
                original.replaceChild(relatedOption, this);
                jQuery(this).find('option').each(function () {
                    select.appendChild(this);
                    if (this.selected) {
                        selectedOption = relatedOption;
                    }
                });
                if (selectedOption == relatedOption) {
                    relatedOption.selected = true;
                    relation = select;
                } else {
                    select.parentNode.style.display = 'none';
                    select.disabled = true;
                }

            });
            this.parentNode.parentNode.insertBefore(fragment, this.parentNode.nextSibling);
            this.onchange = function () {
                var contextNode = hash[this.value];
                if (relation) {
                    relation.parentNode.style.display = 'none';
                    relation.disabled = true;
                }
                if (contextNode) {
                    contextNode.parentNode.style.display = '';
                    contextNode.disabled = false;
                    relation = contextNode;
                    original.name = '';
                } else {
                    original.name = name;
                }
            };
        });

    });

    return {};

}());

