/*!
 * Unister Frontend-Core plugins.js
 * http://www.unister.de/
 *
 * Copyright 2011, Unister GmbH
 * All rights reserved
 *
 * Date: Mon Feb 21 00:00:00 2011 -0500
 *
 * @todo Allgemeine, standardisierte Struktur für alle Plugins schaffen und umsetzen
 * @todo Pluginmethoden strenger aufsplitten für einfachere Erweiterung
 */

(function($) {
    /*
     * Schriftglättungserkennung bei Layout-Problemen unter XP, Vista, Win7 ... bitte mit Bedacht und nur im Notfall nutzen!
     * adaptiert von http://www.useragentman.com/blog/2009/11/29/how-to-detect-font-smoothing-using-javascript/
     * Initialisierung mit $.typeHelpers.insertClasses(); -> fügt body-Klassen ein
     * Test mit $.typeHelpers.hasSmoothing(); -> Boolean, Schriftglättung aktiv (auch true bei XP, wenn cleartype an)
     */
    $.typeHelpers = {
        hasSmoothing : function(){
            // IE has screen.fontSmoothingEnabled - sweet!
            if (typeof(screen.fontSmoothingEnabled) !== "undefined") {
                return screen.fontSmoothingEnabled;
            } else {
                try {
                    // Create a 35x35 Canvas block.
                    var canvasNode = document.createElement('canvas');
                    canvasNode.width = "35";
                    canvasNode.height = "35";

                    // We must put this node into the body, otherwise
                    // Safari Windows does not report correctly.
                    $(canvasNode).hide();
                    $.portal.body[0].appendChild(canvasNode);
                    var ctx = canvasNode.getContext('2d');

                    // draw a black letter 'O', 32px Arial.
                    ctx.textBaseline = "top";
                    ctx.font = "32px Arial";
                    ctx.fillStyle = "black";
                    ctx.strokeStyle = "black";

                    ctx.fillText("O", 0, 0);

                    // start at (8,1) and search the canvas from left to right,
                    // top to bottom to see if we can find a non-black pixel.  If
                    // so we return true.
                    var imageData = ctx.getImageData(0, 0, canvasNode.width, canvasNode.height);

                    for (var x = 8; x <= 32; x++) {
                        for (var y = 1; y <= 32; y++) {

                            var idx = (x + y * imageData.width) * 4;
                            var alpha = imageData.data[idx + 3];

                            if (alpha !== 255 && alpha !== 0) {
                                return true; // font-smoothing must be on.
                            }
                        }
                    }

                    // didn't find any non-black pixels - return false.
                    return false;
                }
                catch (ex) {
                    // Something went wrong (for example, Opera cannot use the
                    // canvas fillText() method.  Return null (unknown).
                    return null;
                }
            }
        },

        insertClasses : function(){
            var result = this.hasSmoothing(),
                body = $.portal.body;

            if (result === true) {
                body.addClass("hasFontSmoothingTrue");
            } else if (result === false) {
                body.addClass("hasFontSmoothingFalse");
            } else { // result == null
                body.addClass("hasFontSmoothingUnknown");
            }
        }

    };

    /*
     * Allgemeine Popupfunktion für popups und popunders mit oder ohne focus
     * Popup beim Laden der Seite mit $(window).popFn(...);, sonst $(element).popFn(...);
     * Optionen siehe Code
     * @todo focus true oder false in defaults? centered: left = (screen.availWidth - width) / 2;
            top = (screen.availHeight - height) / 2;
     */
    $.fn.popFn = function( options ){
	 var defaults = {
            url : this.href || 'http://www.unister.de', //href oder Standardurl ;)
            title : 'popup', //Titel des neuen Fensters 
            params : null,  //Weitere Fensterparameter
            focus : false, //Soll popup fokussiert werden?
            under : false //oder soll's ein popunder sein?
         };
         var settings = {};

        return this.each(function(){
            settings = $.extend({}, defaults, options);
            var win = window.open( settings.url, settings.title, settings.params ); //neues Popup erzeugen

            //focussieren
            if( settings.focus === true ){
                win.focus();
            }
            //popunder
            if( settings.under === true && $.portal.doesPopunder === true){
                win.blur();
            }
        });
    };
	
    /*
     * Inputs bei focus leeren, bei blur wieder befuellen,
     * übernimmt angegebenen value der inputs: $(element).clear();
     */
    $.fn.clear = function() {
        return this.each(function() {
            $(this)
                .addClass("idleField")
                .bind('focusin focusout', function(e) {
                    var el = this;
                    //Klassen umschalten bei focusin und focusout
                    $(el).toggleClass("focusField idleField");
                    if (e.type === 'focusin' && el.value === el.defaultValue) {
                        //beim reinklicken leeren, falls nichts eingegeben wurde
                        el.value = '';
                    } else {
                        if ($.trim(el.value) === ''){
                            //ist die Eingabe leer, defaultvalue setzen
                            el.value = el.defaultValue;
                        } else {
                            //Leerzeichen vor und nach String entfernen
                            el.value = $.trim(el.value);
                        }
                    }
            });
        });
    };
     
    /*
     * Setzt Inputfelder auf disabled, beispielhaft für ein einfaches Plugin
     */
    $.fn.disable = function() {
        if(this.disabled == null){
            return this.each(function() {
                this.disabled = true;
            });
        }
    };
    
    /* 
     * Erzeugt Tabs, erwartet das tabumgebende Element als übergebenen Selektor
     * und eine Liste mit Links, deren ID ein div referenziert: <a href="#auctions"> -> <div id="auctions">
     * Alle genannten Elemente müssen in dem umgebenden Element liegen!
     * $(element).tabtastic(); -> Optionen siehe Code
     */
    $.fn.tabtastic = function( options ) {

        var defaults = { 
            tabs : 'ul.tabs',
            tabContent : 'div.tabContent',
            current : 'active',
            animated : true,
            rotated : false
        };
        var settings = {};
        
        return this.each(function() {
            //Elemente in Box suchen, Inhalte verstecken, erstes Tab aktivieren
            settings = $.extend({}, defaults, options);
            var $this = $(this),
                tabs = $this.find( settings.tabs ),
                tl = tabs.find('a'),
                tc = $this.find( settings.tabContent );
               
                //erstes tab aktivieren, andere verstecken, wenn Container nicht die closed-Klasse hat
                if( !$this.hasClass(settings.closed) ){
                    tl.first().addClass(settings.current);
                    tc.not(':first').hide();
                }

            //Tabrotation
            if(settings.rotated){
                var x = x || 0,
                    timeOut,
                    rotation = function(){
                        x = (x === tl.length-1) ? 0 : x+1;

                        $(tl[x]).click();
                        timeOut = window.setTimeout(rotation, 3000);
                    };
                timeOut = window.setTimeout(rotation, 3000);

                tabs
                    .bind({
                        'mouseenter' : function(){
                            window.clearTimeout(timeOut);
                    },
                        'mouseleave' : function(){
                            timeOut = window.setTimeout(rotation, 3000);
                    }
                });
            }

            //Eventhandler an Links anhängen
            tl.bind('click', function(e) {
                var $this = $(this),
                    tabLink = '#' + this.href.split('#')[1];
                
                //Ist Tab schon aktiv und das dazugehörige Element sichtbar, dann hier abbrechen
                if( $this.hasClass( settings.current ) && $(tabLink).is(':visible') ){
                    return false;
                }
                  
                //Aktivklassen entfernen
                tl.removeClass( settings.current );
                //Geklicktes Tab bekommt Aktivklasse
                $this.addClass( settings.current );

                //Content wird gezeigt, animiert oder nicht
                if(settings.animated){
                    tc.slideUp().filter( tabLink ).slideDown();
                }else{
                    tc.hide().filter( tabLink ).show();
                }
                e.preventDefault();
            });

            
          
        });

    };
    
  /*
   * Scrollt zu einem angegebenen Element oder zum Anfang der Seite
   * Gewünschtes Element kann als target übergeben werden, Geschwindigkeit kann mit speed festgelegt werden.
   * $(element).scrollTo( ... );
   */
   $.fn.scrollTo = function( options ) {
        var defaults = {
            speed : 1000,
            target : 0
        };
        var settings = {};
        return this.each(function() {
            settings = $.extend({}, defaults, options);
            var target = $(settings.target);
            //Firefox und IE nutzen body im quirks mode, aber html im standards mode.
            $('html, body').animate({
                //zu Element oder nach oben scrollen
                scrollTop: (target.length) ? target.offset().top : settings.target
            }, settings.speed);
        });
   };
    
    
   /*
    * Erstellt einfache Tooltips aus dem title-Attribut der übergebenen Elemente
    * Der tooltip kann durch stylen von <div id="toolTipper" class="ttContainer"> per CSS angepasst werden,
    * dieses div benötigt unbedingt position:absolute!!!
    * -> @todo update Methode verwenden?, Optionen anbieten, erweitern ohne title, ajax?, Klassenübergabe ermöglichen für Styling
    */
    $.fn.toolTipper = function( method ) {
        var defaults = {
            xOffset : 10,
            yOffset : 20,
            width : 170
        };
		
        var settings = {};
		
        var methods = {
            init : function( options ) {
                settings = $.extend({}, defaults, options);
				
                var toolTip = $('<div />', {
                        id : 'toolTipper',
                        style : 'display:none',
                        text : 'Tooltip'
                    })
                    .addClass('ttContainer')
                    .appendTo($.portal.body);

                return this.each(function(){

                    var $this = $(this),
                    data = $this.data('tooltip');
				
                    if ( ! data ) {
                        // wenn das plugin noch nicht initialisiert wurde
                        $this.data('tooltip', {
                            target : $this,
                            toolTip : toolTip,
                            title : this.title
                        });

                    }

                    //$(window).bind('resize.tooltip', methods.reposition)
                    $this.bind('mouseover.toolTip', methods.show)
                        .bind('mouseout.toolTip', methods.hide)
                        .bind("mousemove.toolTip", methods.reposition);
                });
            },
            destroy : function( ) {

                return this.each(function(){

                    var $this = $(this),
                    data = $this.data('tooltip');

                    // Namespacing FTW- Namespace löschen
                    $(window).unbind('.tooltip');
                    data.toolTip.remove();
                    $this.removeData('tooltip');

                });

            },
            reposition : function( e ) {
                var $this = $(this),
                data = $this.data('tooltip');

                data.toolTip
                    .css({
                        "top" : (e.pageY + settings.yOffset ) + "px",
                        "left" : (e.pageX + settings.xOffset ) + "px"
                    });

            },
            show : function( e ) {
                var $this = $(this),
                data = $this.data('tooltip'),
                title = data.title;

                data.toolTip
                    .html(title)
                    .css({
                        "top" : ( e.pageY + settings.yOffset) + "px",
                        "left" : ( e.pageX + settings.xOffset) + "px"
                    })
                    .stop(true,true)
                    .fadeIn("fast");

                //reset title to none
                this.title = null;

            },
            hide : function( e ) {
                var $this = $(this),
                    data = $this.data('tooltip');
                    
                this.title = data.title;
                data.toolTip
                    .stop(true,true)
                    .fadeOut("fast");
            },
            update : function( content ) {
                //log('update');
            }
        };


        if ( methods[method] ) {
          return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
          return methods.init.apply( this, arguments );
        } else {
          $.error( 'Methode ' +  method + ' existert nicht für toolTipper' );
        }

    };

    /*
     * Erzeugt eine Liste anhand der Bookmarking-Fähigkeit der Browser
     * IE: "Zur Startseite machen" und "Als Lesezeichen hinzufügen"
     * Mozilla-Browser und Firefox: "Als Lesezeichen hinzufügen"
     * @todo window.external.AddSearchProvider("http://mysite.org/odd.xml") -> Schnellsuche auch einbauen?
     * @todo Callback für alle Browser, die diese Funktionen nicht unterstützen?? :(
    */
    $.fn.bookMarker = function( options ) {
        var defaults = {
                          pageTitle : document.title, //Title für bookmarks
                          pageUrl : $.portal.win[0].location.href, //Url für bookmarks
                          listClasses : 'addThis', //Klassen der bookmarkliste
                          bookMark : 'Diese Seite als Lesezeichen hinzufügen',
                          startPage : 'Zur  Startseite machen',
                          ffBookmark : $.portal.win[0].sidebar || false,
                          ieBookmark : ($.portal.win[0].external && $.portal.isIE) || false,
                          oBookmark : ($.portal.win[0].opera && $.portal.win[0].print) || false,
                          ffCallback : function(){
                              alert('Bitte drücken Sie STRG + D, um für diese Seite ein Lesezeichen anzulegen.');
                          }
                        };
        var settings = {};
            settings = $.extend({}, defaults, options);
        return this.each(function(){

            if ( !settings.ieBookmark && !settings.ffBookmark && !settings.oBookmark ) {
                    //wird nichts unterstützt, dann raus hier!
                    return false;
            }


            var $this = $(this),
                makeFav = function(e) {

                    if ( settings.ffBookmark && typeof settings.ffCallback === "function") { // Mozilla Firefox Bookmark
                       //Lesezeichen hinzufügen, welches sich in der Sidebar öffnet. Andere Lösung nicht möglich: https://bugzilla.mozilla.org/show_bug.cgi?id=214530
                       //$.portal.win[0].sidebar.addPanel( settings.pageTitle, settings.pageUrl,  "" );
                       settings.ffCallback();
                       e.preventDefault();
                    } else if ( settings.ieBookmark ) { // IE Favorite
                       $.portal.win[0].external.AddFavorite( settings.pageUrl, settings.pageTitle );
                       e.preventDefault();
                    } else if ( settings.oBookmark ) { // Opera Hotlist
                       return true;
                    }
                };

                //create listelement for links
                var addThis = $('<ul />', {
                        'class' : settings.listClasses
                    }).appendTo( $this ),

                    //add to favourites for FF && Opera
                    toFavourites = $('<a />', {
                        rel :   'sidebar',
                        href :  settings.pageUrl,
                        title : settings.pageTitle,
                        html :  settings.bookMark,
                        click : makeFav
                    }),
                    asStartpage;

                    //Startseite machen, nur IE. Braucht portal!!!
                    if ( $.portal.isIE ){ //IE
                        asStartpage = $('<a />', {
                            href :  settings.pageUrl,
                            title : settings.pageTitle,
                            html :  settings.startPage,
                            click : function(e) {
                                var el = this;
                                el.style.behavior = 'url(#default#homepage)';
                                el.setHomePage( settings.pageUrl );
                                e.preventDefault();
                            }
                        });
                    }

                    toFavourites
                        .add(asStartpage)
                        .each(function() {
                            $(this)
                                .wrap('<li />')
                                .parent()
                                .appendTo( addThis );
                    });

        });
    };

    /*
     * Elemente durch Klick anzeigen oder verstecken
     * Optionen siehe defaults
     * @todo Refactoring, Verbessern, erweitern?
     */
    $.fn.showHide = function( options ){
        var defaults = {
            toggleEl : 'div', //nachfolgende Elemente, die getoggled werden sollen
            toggleCl : 'trigger', //Klasse, die toggle Köpfe für zusätzliches Styling bekommen
            openCl : 'openToggler', //Klasse, die vergeben wird für toggler, wenn Element sichtbar
            speed : 'fast',
            textToggle : false,
            accordion : false,
            accordionCl : 'accordion'
        };
        var settings = {};
            settings = $.extend({}, defaults, options);
            
        return this.each(function() {
            //für reinen Text, z.B. Seotexte
            if(settings.textToggle === true){
		$('<a />',{
                    href : '#more',
                    text : 'mehr ...'
                })
                .toggle(function(e){
                        $(this)
                            .text('Schließen')
                            .prev(settings.toggleEl)
                            .show();
                        e.preventDefault();
                    },
                    function(e){
                        $(this)
                            .text('mehr ...')
                            .prev(settings.toggleEl)
                            .hide();
                        e.preventDefault();
                    }
		)
                .appendTo($(this));
			
            }else{
                //für das ersetzen von Elementen durch Links, die nachfolgendes Element togglen
                $(this)
                    .replaceWith(function() {	
                    var linkText = $(this).text(),
                        wrapped = $('<a />', {
                                href : '#toggle',
                                text : linkText
                            })
                            .addClass(settings.toggleCl)
                            .addClass(settings.accordion === true ? settings.accordionCl : null)
                            .click(function(e){
                                var $this = $(this),
                                    content = $this.next(settings.toggleEl);
                                
                                if( content.is(':visible') ){
                                    $this.removeClass(settings.openCl);
                                    content.hide(settings.speed);
                                } else {
                                    if(settings.accordion === true){
                                        //alle Inhaltsbereiche verstecken, wenn Akkordeon gewünscht
                                        $('a.' + settings.accordionCl)
                                            .removeClass(settings.openCl)
                                            .next()
                                            .stop(true,true)
                                            .hide(settings.speed);
                                    }
                                    $this.addClass(settings.openCl);
                                    content.stop(true,true).show(settings.speed);
                                }
                            });
                            

                            return wrapped;
					});
            }   
        });
			
    };

    /*
     * simpleSlide - einfache SlideShow
     */
    $.fn.simpleSlide = function(method) {

        var defaults = {
            time: 5000
        };

        var settings = {};

        var methods = {

            init : function(options) {
                settings = $.extend({}, defaults, options);
                return this.each(function() {
                    var $this = $(this);
                    $this.addClass('simpleSlide');
					$('img:gt(0)', $this).hide();
                    methods.setTimer($this);
                });
            },

            setTimer: function(el) {
                var $this = el;
                $(':first-child', $this).fadeOut()
                    .next('img')
                    .fadeIn()
                    .end()
                    .appendTo($this);
                setTimeout(function(){methods.setTimer($this);}, settings.time );
            }

        };


        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error( 'Methode "' +  method + '" existiert nicht in simpleSlide plugin!');
        }

    };
    
    /*  Scroll to action - Man muss erst scrollen, damit eine Checkbox aktiv wird. Im Moment noch rudimentär
     *  und nur auf einem Element nutzbar.
     *  @todo: Erweitern!
    */
    $.fn.scrollFirst = function(method) {

        var defaults = {
            inner : "div.inner", //Kindelement, was scrollbar ist
            checkbox : "#iReadIt"
        };

        var settings = {};

        var methods = {

            init : function(options) {
                settings = $.extend({}, defaults, options);
                
                return this.each(function() {
                    var
                        $this = $(this),
                        el = this,
                        data = $this.data('scrollFirst'),
                        inner = $(settings.inner);
                    
                    //Elemente zurücksetzen
                    inner.scrollTop();
                    $(settings.checkbox).attr('checked', false).disable();
                    
                    //Alle Messdaten in das Element schreiben
                    if ( !data ){
                        $this.data('scrollFirst', {
                            inner : $(inner, $this),
                            innerOuterHeight : inner.outerHeight(),
                            boxHeight : $this.height(),
                            boxOffsetTop : $this.offset().top
                        });
                    }
                     
                    //Binde eventhandler
                    $this.bind('scroll.scrollFirst', methods.scrollHandler);
                });
            },

            scrollHandler: function() {
                //Caching und Berechnung
                var $this = $(this),
                    data = $this.data('scrollFirst'),
                    scrollPos = Math.ceil(data.boxHeight - data.inner.offset().top + data.boxOffsetTop); //Scrollposition berechnen
                    
                //Wenn Scrollende erreicht ist
                if ( scrollPos >= data.innerOuterHeight ) {
                    var box = $(settings.checkbox);
                    box
                        .removeAttr("disabled") //checkbox aktivieren
                        .removeClass('invalid') //Klasse von Checkbox entfernen
                        .next('label[for="' + box[0].id + '"]') //Suche nach dem zugehörigen label
                        .removeClass('invalid'); //Klasse vom Label entfernen
                }
            }

        };

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error( 'Methode "' +  method + '" existiert nicht in scrollFirst plugin!');
        }

    };


})(jQuery);


	


