/*  ==========================================================================================================  */
/*  target="_blank" per Javascript anfuegen
/*  ==========================================================================================================  */

function externalLinks() {
    var anchors = $$('a[rel=external], #twitter_div a');

    anchors.each(function(a) {
        a.target = "_blank";
    });
}

/*  ==========================================================================================================  */
/*  Input fields: value toggling
/*  ==========================================================================================================  */

var inputValueHash = new Hash();

function init_input_toggle() {
    var fields = $$('input.toggle'); /* @TODO: Doesnt work in IE */

    fields.each(function(feld) {
        if (feld.value == '') {return false;}
        inputValueHash.set(feld.id, feld.value);
        feld.observe('focus', inputFocus);
        feld.observe('blur', inputBlur);
    });
}
function inputFocus(event) {
    if (this.value == inputValueHash.get(this.id)) {
        this.value = '';
    }
}
function inputBlur(event) {
    if (this.value == '') {
        this.value = inputValueHash.get(this.id);
    }
}

/*  ==========================================================================================================  */
/*  Add Social Bookmarks
/*  ==========================================================================================================  */

function socialize(container) {
    var url = location.href;
    var title = document.title;

    Element.insert(container, '<li><a target="_blank" title="Technorati" class="sbm-technorati" href="http://www.technorati.com/faves?add='+ url +'">Link auf Technorati teilen</a></li>');
    Element.insert(container, '<li><a target="_blank" title="Delicious" class="sbm-delicious" href="http://del.icio.us/post?url='+ url +'&amp;title='+ title +'">Link auf Delicious teilen</a></li>');
    Element.insert(container, '<li><a target="_blank" title="Linkarena" class="sbm-linkarena" href="http://linkarena.com/bookmarks/addlink/?url='+ url +'&title='+ title +'">Link auf Linkarena teilen</a></li>');
    Element.insert(container, '<li><a target="_blank" title="Mr. Wong" class="sbm-wong" href="http://www.mister-wong.de/index.php?action=addurl&bm_url='+ url +'&amp;bm_description='+ title +'">Link auf Mr.Wong teilen</a></li>');
    Element.insert(container, '<li><a target="_blank" title="Facebook" class="sbm-facebook" href="http://www.facebook.com/sharer.php?u='+ url +'&amp;title='+ title +'">Link auf Facebook teilen</a></li>');
    Element.insert(container, '<li><a target="_blank" title="Digg" class="sbm-digg" href="http://digg.com/submit?phase=2&url='+ url +'&amp;title='+ title +'">Link auf Digg teilen</a></li>');
    Element.insert(container, '<li><a target="_blank" title="Google Bookmarks" class="sbm-google" href="http://www.google.com/bookmarks/mark?op=add&hl=de&amp;bkmk='+ url +'&title='+ title +'">Link auf Google teilen</a></li>');
    Element.insert(container, '<li><a target="_blank" title="Stumble Upon" class="sbm-stumble" href="http://www.stumbleupon.com/submit?url='+ url +'&amp;title='+ title +'">Link auf StumbleUpon teilen</a></li>');
}

/*  ==========================================================================================================  */
/*  Some handy animation functions
/*  ==========================================================================================================  */

function slideDown(element, duration) {
    if (Prototype.Browser.IE) {
        Element.show(element);
        return;
    }
  new Effect.BlindDown(element, {
        duration: duration,
        transition: Effect.Transitions.sinoidal,
        queue: {position: 'end', scope: 'anims', limit: 2}
    });
}
function slideUp(element, duration) {
  if (Prototype.Browser.IE) {
        Element.hide(element);
        return;
    }
  new Effect.BlindUp(element, {
        duration: duration,
        transition: Effect.Transitions.sinoidal,
        queue: {position: 'end', scope: 'anims', limit: 2}
    });
}
function appear(element, time) {
    var t = 1.5;
    if (time) {
        t = time;
    }
    new Effect.Appear(element, {duration:t});
}
function fade(element, time) {
    var t = 1;
    if (time) {
        t = time;
    }
    new Effect.Fade(element, {duration:t});
}

/*  ==========================================================================================================  */
/*  Toggle boxes
/*  ==========================================================================================================  */

function expand_collapse_menus(event) {
    var trigger = this;
    var target;
    if (trigger.id == 'login-btn') {
        target = $('login-form');
    } else {
        target = trigger.next();
    }

    if (target.style.display == 'none') {
        slideDown(target, 0.6);
        trigger.addClassName('open');
    } else {
        slideUp(target, 0.6);
        trigger.removeClassName('open');
    }
}

/*  ==========================================================================================================  */
/*  Character countdown for input fields
/*  ==========================================================================================================  */

function countDown(event) {
    var max             = this.getAttribute('maxlength');
    var msgContainer    = this.next('p');
    var count_target    = msgContainer.select('span')[0];
    var current_size    = this.value.length;

    count_target.innerHTML = max - current_size;
    if (max - current_size < 16 && !(count_target.hasClassName('warning'))) {
        count_target.addClassName('warning');
    }
    if (max - current_size > 15 && count_target.hasClassName('warning')) {
        count_target.removeClassName('warning');
    }
}

/*  ==========================================================================================================  */
/*  Form validation
/*  ==========================================================================================================  */

// This has some requirements to work properly:
// * The <form> needs an ID AND class="validate" applied
// * All mandatory fields must be within a container with class="mandatory" applied

function validateEmail(email) {
    var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
    var address = email;
    if (reg.test(address) == false) {
        return false;
    } else {
        return true;
    }
}

function validateForm(event) {

    var errorElements   = [];

    // In Case this is the second+ time we're validating this form, kill all error-indicators
    $$('#' + this.id + ' .error').invoke('removeClassName', 'error');
    if ($$('#errormessage > p').length >= 1) {
        $$('#errormessage > p').invoke('remove');
    }

    // Get all mandatory fields - this requires an ID set on the form AND use of class="mandatory" on <li> elements
    var mandatoryLabels = $$('#' + this.id + ' .mandatory input, #' + this.id + ' .mandatory select, #' + this.id + ' .mandatory textarea');

    // check for empty elements
    mandatoryLabels.each(function(field) {
        if (field.value == '') {
            errorElements.push(field);
        }
        // check for invalid email fields
        if (field.hasClassName('mail') && field.value != '') {
            if (validateEmail(field.value)) return false;
            errorElements.push(field);
        }
        // Special cases ==============================================
        if (field.id == 'rating' && field.value == 0) {
            errorElements.push(field);
        }
        // @TODO: Generische Abfrage für checkboxen und radiobuttons anfügen
        if (field.id == 'optin' && field.checked == false) {
            errorElements.push(field);
        }
    });

    // Check if the error array contains at least one element. If not, submit...
    if (errorElements.first() === undefined) {
        this.submit();
    // if so, generate error messages
    } else {
        var genericError = new Element('p').update('Es fehlt noch etwas. Bitte fülle die markierten Felder aus:');

        Element.insert($('errormessage'), genericError);
        $('errormessage').show();

        // Highlight error elements
        errorElements.each(function(err) {
            $(err).up('li').addClassName('error');
        });
    }
}

/*  ==========================================================================================================  */
/*  ibSlider
/*  ==========================================================================================================  */

    var SlidingBox = Class.create({

        _offset: null,
        increments: 1,  // want to change default increments?
        itemCount: '',

        // Don't like the CSS classnames? Change'em here...
        classNames : {
            slider          : 'slider',         //
            slideLeft       : 'slide-left',     //
            slideRight      : 'slide-right',    //
            slideContent    : 'slide-content'   //
        },

        getContainer: function(sbox) {
            var container = sbox.down('.'+this.classNames.slideContent);
            return container;
        },

        getItems: function(container) {
            itemCount = container.select('li').size();
            return itemCount;
        },

        initialize: function(sbox) {
            var container   = this.getContainer(sbox);
            increments      = this.getIncrements(sbox);
            var itemCount   = this.getItems(container);
            this.setSlidingContainer(sbox);
            $$('.'+this.classNames.slideLeft).invoke('addClassName', 'inactive');   // hide left scroll links
            // @TODO: if there's no move-x class, this will not work
            if (itemCount <= increments) {
                $$('.'+this.classNames.slideRight).invoke('addClassName', 'inactive');
            }
        },

        setSlidingContainer: function(sbox) {
            // get all vars...
            var container       = sbox.down('.'+this.classNames.slideContent);
            var itemCount       = container.select('li').size();
            this._offset        = this.getScrollOffset(sbox); // get total width of child element
            var containerWidth  = (this._offset / increments) * itemCount;
            // ... and set container width
            container.setStyle({
                left: 0,
                width: containerWidth + 'px'
            });
            // now, bind event handler to the box
            sbox.observe('click', this.slideBoxEvents.bindAsEventListener(this));
        },

        // how many items to move at a time
        getIncrements: function(box) {
            var value = box.classNames().inspect(); // get all the applied classnames
            if (value.indexOf('move-') != -1) {
                inc = parseInt(value.split('-')[1]);
                this.increments = inc;
            }
            return this.increments;
        },

        getScrollOffset: function(box) {
            if (!box.hasClassName(this.classNames.slider)) {
                box = box.up('.'+this.classNames.slider);
            }
            var con         = box.down('.'+this.classNames.slideContent);
            var items       = con.childElements('li'); // get children
            var obj         = items.first();
            this._offset    = parseInt(obj.getWidth()) + parseInt(obj.getStyle('margin-right')) + parseInt(obj.getStyle('margin-left'));
            increments      = this.getIncrements(box);

            return this._offset * increments;
        },

        // figure out which element was clicked and say what happens next
        slideBoxEvents: function(event) {
            trigger = event.element();
            // ... this is a scroll trigger...
            if ((trigger.match('.'+this.classNames.slideLeft) || trigger.match('.'+this.classNames.slideRight)) && !trigger.hasClassName('inactive') ) {
                this.horizontal_slider(trigger);
            // ... or nothing
            } else {
                return false;
            }
        },

        horizontal_slider: function(trigger) {
            var actual_position, max_position, scroll_target;
                scroll_offset = this.getScrollOffset(trigger);
            // Slide right
            if (trigger.hasClassName(this.classNames.slideRight)) {
                scroll_target   = trigger.previous().firstDescendant(); // container element to scroll
                var maskSize    = parseInt(scroll_target.up().getWidth());
                actual_position = (Math.abs(parseFloat(scroll_target.style.left)));
                max_position    = parseInt(scroll_target.getStyle('width')) - actual_position; // stop scrolling at this point.
                var lastMargin  = parseInt(scroll_target.firstDescendant().getStyle('margin-right'));
                // scroll inner element to the end and back to the start
                if (trigger.hasClassName('endpoint')) {
                    new Effect.Move(scroll_target, {
                        x: 0,
                        y: 0,
                        mode: 'absolute',
                        queue: {position: 'end', scope: 'anims', limit: 1},
                        afterFinish: function() {
                            trigger.removeClassName('endpoint');
                            triggerLeft.addClassName('inactive');
                        }
                    });
                }
                if (max_position > maskSize) {
                    new Effect.Move(scroll_target, {
                        x: -(scroll_offset),
                        y: 0,
                        mode: 'relative',
                        queue: {position: 'end', scope: 'anims', limit: 1}
                    });

                    max_position = max_position - scroll_offset - lastMargin;
                    // toggle triggers inactive-state
                    if (max_position <= maskSize) {
                        trigger.addClassName('endpoint');
                    }
                    triggerLeft = trigger.previous(1);
                    triggerLeft.removeClassName('inactive');
                }
            // Slide left
            } else if (trigger.hasClassName(this.classNames.slideLeft)) {
                scroll_target = trigger.next().firstDescendant(); // inner element to scroll
                actual_position = (Math.abs(parseFloat(scroll_target.getStyle('left'))));
                // scroll inner element and stop at max value
                if (actual_position != '0') {
                    new Effect.Move(scroll_target, {
                        x: scroll_offset,
                        y: 0,
                        mode: 'relative',
                        queue: {position: 'end', scope: 'anims', limit: 1}
                    });
                    // toggle triggers inactive-state
                    actual_position = parseInt(scroll_target.getStyle('left')) + (scroll_offset);
                    if (actual_position >= 0) {
                        trigger.addClassName('inactive');
                    }
                    var triggerRight = trigger.next(1);
                    triggerRight.removeClassName('inactive').removeClassName('endpoint');
                }
            }
        }
    });

/*  ==========================================================================================================  */
/*  Twitter
/*  ==========================================================================================================  */

function loadTwitter() {

    var a = new Element('script', { type: 'text/javascript', src: 'http://twitter.com/javascripts/blogger.js' });
    var b = new Element('script', { type: 'text/javascript', src: 'http://twitter.com/statuses/user_timeline/PAN_Verlag.json?callback=twitterCallback2&count=2' });
    
    document.body.appendChild(a);
    document.body.appendChild(b);
}

/*  ==========================================================================================================  */
/*  Some more goodies
/*  ==========================================================================================================  */

//  Fading notifications -------------------------------------------------------------------------------------
function fadeNotes() {
    var notes = $$('.notice');

    notes.each(function(note) {
        slideUp.delay(5, note, 1);
        fade.delay(5, note, 1);
    });
}

//  Load details page for "special"-book featured in Flash ---------------------------------------------------
function loadBookDetail() {
    parent.document.location.href = 'http://www.pan-verlag.de/buch/ALTERRA/978-3-426-28300-4';
}

/*  ==========================================================================================================  */
/*  ==========================================================================================================  */
//  Call all functions
/*  ==========================================================================================================  */

function init() {
    // Load Twitter Scripts to the end of document, due to an IE problem
    if ($('twitter_div')) { loadTwitter(); }
    // input fields: value toggling
    init_input_toggle()
    // Add Social Bookmarks
    if ($('socialbookmarks')) {
        socialize($('socialbookmarks'));
    }
    // Toggle boxes
    if ($$('.expandable').size() >= 1) {
        if (!(Prototype.Browser.IE && (typeof window.XMLHttpRequest == "undefined"))) { // problems with IE7.js
        $$('.expandable').invoke('observe', 'click', expand_collapse_menus);
        $$('.expandable').each(function(a) {a.next().hide();});
        }
    }
    // Login-Box
    if ($('login-btn')) {
        if (!(Prototype.Browser.IE && (typeof window.XMLHttpRequest == "undefined"))) { // problems with IE7.js
        $('login-btn').observe('click', expand_collapse_menus);
        $('login-form').hide();
        }
    }
    // Slider
    if ($$('.slider').length >= 1) {
        $$('.slider').each(function(sbox) {
            new SlidingBox(sbox);
        });
    }
    // Character countdown (Leserstimmen)
    if ($('heading')) {
        $('heading').observe('keyup', countDown);
    }
    // Form validation
    if ($$('.validate').length >= 1) {
        $$('.validate').each(function(f) {
            Element.insert(f, { top: '<div id="errormessage" style="display:none;"></div>' });
            f.observe('submit', validateForm);
            f.onsubmit = function() {return false;};
        });
    }
    // Fading notifications
    if ($$('.notice').length >= 1) {
        fadeNotes()
    }
    // Target BLank
    if ($$('a[rel=external]').length >= 1) {
        externalLinks.delay(2); // Wait for Twitter content to be loaded
    }
}

// Initialisierung nach Event DOMContentLoaded
document.observe("dom:loaded", init);
