/**
 *  Script lazy loader 0.5 - Modified By Web2ajaX
 *  Copyright (c) 2008 Bob Matsuoka
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  Lazyloader updated for a jQuery implementation and appendChild in context
 *  not only in document.body
 *  Add script remove on callback to clean space.
 *
 */

var LazyLoader = {}; //namespace
LazyLoader.timer = {};  // contains timers for scripts
LazyLoader.scripts = [];  // contains called script references
LazyLoader.load = function(url, context, callback) {
        // handle object or path
        var classname = null;
        var properties = null;
        try {

            // make sure we only load once
            // note that we loaded already
            LazyLoader.scripts.push(url);
            var script = document.createElement("script");
            script.src = url;
            script.type = "text/javascript";
            context.get(0).appendChild(script);  // add script tag to head element

            // was a callback requested
            if (callback) {
                // test for onreadystatechange to trigger callback
                script.onreadystatechange = function () {
                    if (script.readyState == 'loaded' || script.readyState == 'complete') {
                        callback();
                        $(script).remove() ;
                    }
                }
                // test for onload to trigger callback
                script.onload = function () {
                    callback();
                    $(script).remove() ;
                    return;
                }
                // safari doesn't support either onload or readystate, create a timer
                // only way to do this in safari
				try {
					if (($.browser.webkit && !navigator.userAgent.match(/Version\/3/)) || $.browser.opera) { // sniff
						LazyLoader.timer[url] = setInterval(function() {
							if (/loaded|complete/.test(document.readyState)) {
								clearInterval(LazyLoader.timer[url]);
								callback(); // call the callback handler
							}
						}, 10);
					}
				} catch(e) { }
            }
        } catch (e) {
            alert(e);
        }
} ;




/* 

    Defer Advertisement loading and load only if the ad is in the visible part of
    the page like lazyLoad for pictures.
    -> Highly improve general page load
    -> Improve cpu load of visitor in case of displaying flash banners (only displayed if necessary)
    –> Compatibility with AdSense and many other advertisers
    -> Cross Browser suupprt (IE5.5+, Firefox, Opera, Chrome, Safari)

    A big thanks to Mika Tuupola for the Lazy load part
    -> http://www.appelsiini.net/projects/lazyload

    Another big thanks to Thomas Aylott and his MooTools based document.write replacement
    -> http://SubtleGradient.com/

*/

(function($) {

	$.lazyLoadAdRunning = false ;
	$.lazyLoadAdTimers = [] ;

    $.fn.lazyLoadAd = function(options) {
        var settings = {
            threshold    : 0,
            failurelimit : 1,
            forceLoad	 : false,
            event        : "scroll",
            viewport	 : window,
            placeholder	 : false,		// Can specify a picture to replace media while loading
            onLoad		 : false,
            onComplete	 : false,
            timeout		 : 1500,
            debug		 : false
        };

        if(options) {
            $.extend(settings, options);
        }

        /* Write logs if possible in console */
        function _debug() {
        	if ( typeof console != 'undefined' && settings.debug ) {
        		var args = [] ;
        		for ( var i = 0 ; i < arguments.length ; i++ ) args.push(arguments[i]) ;
        		try {console.log('LazyLoadAD |', args) ;} catch(e) {} ;
        	}
        }

        /* Fire one scroll event per scroll. Not one scroll event per image. */
        var elements = this;
        $(settings.viewport).bind("checkLazyLoadAd", function() {
        	var counter = 0;
        	elements.each(function() {
        		if ( $.lazyLoadAdRunning ) {
        			if ( $.lazyLoadAdTimers['runTimeOut'] ) clearTimeout( $.lazyLoadAdTimers['runTimeOut'] ) ;
        			 $.lazyLoadAdTimers['runTimeOut'] = setTimeout(function() {
        				$(settings.viewport).trigger("checkLazyLoadAd") ;
        			}, 300) ;
        			return false ;
        		} else if ( settings.forceLoad == true ) {
        			$(this).trigger("load");
        		} else if (!$.belowthefold(this, settings) && !$.abovethetop(this, settings)) {
        	        $(this).trigger("load");
        	    } else {
        	        if (counter++ > settings.failurelimit) {
        	            return false;
        	        }
        	    }
        	});
        	/* Remove element from array so it is not looped next time. */
        	var temp = $.grep(elements, function(element) {
        	    return ! (($(element).data('loaded') == 'true') ? true : false) ;
        	});
        	elements = $(temp);
        }) ;



        // -- Bind each element
        this.each(function(_index, _value) {
            var self = $(this);

            /* Save original only if it is not defined in HTML. */
            if (undefined == self.attr("original")) {
                self.attr("original", self.attr("src"));
            }

            /* Test if element is loaded */
            self.isLoaded = function() {return ((self.data('loaded') == 'true') ? true : false)  ;} ;

            /* Trigger Debug Display */
            self.bind("debug", function(e, status) {

            	status = status || 'start' ;


            	// -- Change border color of ad frame
	            if ( settings.debug ) {
	            	if ( status == 'start') self.css({border: '3px solid orange'}) ;
	            	else if ( status == 'error' ) self.css({border: '3px solid red'}) ;
	            	else if ( status == 'complete' ) self.css({border: '3px solid green'}) ;
            	}

            });

            /* On ad Load successful */
            self.one('onComplete', function() {

            	_debug('---> lazyLoadComplete') ;

            	// -- Remove original attr
            	$(self).removeAttr("original") ;

            	// -- Set as loaded
            	$.lazyLoadAdRunning = false ;
            	self.data('loaded', 'true') ;

            	// -- Mark debug
            	self.trigger('debug', 'complete') ;

            	if ( typeof settings.onComplete == 'function') {
            		try {settings.onComplete()} catch(e) {} ;
            	}
            }) ;


            /* Launch the makina !! */
            self.stack = [] ;
            self.makinaBlock = false ;
            self.bind('makina_go', function() {

            	if ( self.makinaBlock ) return false ;

            	if ( self.stack.length > 0 ) {
            		var el = self.stack.shift() ;

                        var wrapAd = self.find('.wrapAd') ;
                        if ( ! wrapAd.length ) {
                                wrapAd = $('<div class="wrapAd"></div>').clone() ;
                                wrapAd.appendTo(self) ;
                        }

                        var wrap = $('<div>').clone().appendTo(wrapAd) ;

            		if ( typeof el == 'string' ) {
            			wrap.replaceWith(el);
            		} else if ( typeof el == 'object' ) {
            			if ( el.is('script') ) {

            				// -- Load JS and block makina until script is loaded
            				if ( el.attr('src') ) {
	            				_debug('JS to load !! --> ' +  el.attr('src') ) ;
	            				//self.makinaBlock = true ;
	            				LazyLoader.load(el.attr('src'), self, function(){
	            				    self.makinaBlock = false ;
	            				    _debug('JS to load !! ++> ' +  el.attr('src') ) ;
	            				    self.trigger('makina_go') ;
	            				});
            				}

            				// -- Write JS code in wrapper
            				else {
            					wrap.replaceWith(el);
            				}
            			} else {
            				wrap.replaceWith(el);
            			}
            		}

            		self.trigger('makina_go') ;
            	} else {
            		if ( $.lazyLoadAdTimers.loadJS ) clearTimeout($.lazyLoadAdTimers.loadJS) ;
            		$.lazyLoadAdTimers.loadJS = setTimeout(function() {
            			self.trigger('onComplete') ;
            		}, settings.timeout) ;
            	}

            }) ;

            /* Write directly in DOM : tag is html valid */
            self.bind('docWrite_direct', function(e, html) {
                //Carstart Mirando Fix
                var mirandoRandom = Math.round(Math.random()*99999);
                //$(html).replaceText('frame','tuerke');
            	html = html.replace('<iframe src="about:blank"','<iframe src="about:blank" id="mir_' + mirandoRandom + '"' );
                html = html.replace("var frame = frames[frames.length - 1];","var frame = document.getElementById('mir_" + mirandoRandom + "');");
                //End Carstart Mirando Fix

                var el = $(html) ;
            	_debug('Fragment Direct Write : ', el, el.length) ;
            	$.each(el, function() {self.stack.push($(this)) ;}) ;
            	self.trigger('makina_go') ;
            }) ;

            /* Write directly in DOM : tag is html valid */
            self.bind('docWrite_delayed', function(e, html) {
            	_debug('Fragment Delayed Write : ', html) ;

            	self.numWrappers-- ;
            	_debug("Fragment append : ", self.numWrappers, html);
            	self.docHtmlCurrent += html;
            	if ( self.numWrappers == 0 ) {
            		html = self.docHtmlCurrent ;
            		self.docHtmlCurrent = '' ;
            		setTimeout(function() {
            			self.stack.push(html) ;
            			self.docHtmlCurrent = '';
            			self.trigger('makina_go') ;
            		}, 0);
            	}
            }) ;



            /* Overload the default document.write */
            self.numWrappers = 0 ;
            self.docHtmlCurrent = '' ;
            self.bind('docWrite_overload', function() {

            	// -- Overload default document.write function
            	document._writeOriginal = document.write;
            	document.write = document.writeln = function(){

            		var args = arguments, id = null ;
            		var html='';for(var i=0;i<args.length;i++) html+=args[i] ;

            		// -- Check if html to write is valid
            		var testHTML = '',
            			directWrite = false ;

            		try {
            			testHTML = $(html) ;
            			directWrite = ( ( testHTML.is('div') || testHTML.is('script') ) ? true : false ) ;
            		} catch(e) { } ;

            		self.history[self.fragmentId] = self.history[self.fragmentId] || {} ;
            		if ( self.history[self.fragmentId][html] == undefined ) {
            			self.history[self.fragmentId][html] = true ;
            			if ( directWrite ) {
            				self.trigger('docWrite_direct', html) ;
            			} else {
            				self.numWrappers++ ;
            				setTimeout(function() {
	            				self.trigger('docWrite_delayed', html) ;
	            			}, 0) ;

            			}
            		}
            	};
            }) ;


            /* Eval Script into <code> tags */
            self.bind('evalCode', function() {
	            var scripts = [],
	            	script,
	            	regexp = /<code[^>]*>([\s\S]*?)<\/code>/gi;

	            while ((script = regexp.exec(self.html()))) {
	            	var _s = script[1] ;
	            	_s = _s.replace('<!--//<![CDATA[', '').replace('//]]>-->','').replace('<!--', '').replace('//-->', '') ;
	            	_s = _s.replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<') ;
	            	scripts.push($.trim(_s));
	            }

	            // -- Eval param code before calling ad script
	            try {
	            	scripts = ( scripts.length ? scripts.join('\n') : '' ) ;
	            	_debug('Script to eval : ', scripts) ;
	            	if ( scripts != '' ) eval(scripts);
	            } catch(e) { } ;
            });


            /* Load a JS and wait for callback */
            self.bind('loadJS', function(e, js2load) {

            	var callback = null, script = null ;
            	if ( js2load.src ) {
            		callback = js2load.callback || null ;
            		js2load = js2load.src ;
            	}

            	// Add an anticache
            	if ( js2load.indexOf('?') == -1 ) {
            		js2load += '?_='+ (new Date().getTime()) ;
            	} else {
            		js2load += '&_='+ (new Date().getTime()) ;
            	}

            	_debug('loadJS :: ', js2load) ;

				// Request JS
            	LazyLoader.load(js2load, self, function(){
            	    _debug('loadJS COMPLETE :: ' + js2load) ;
            	    if ( callback ) {
            	    	callback() ;
            	    } else {
            	    	$.lazyLoadAdTimers.loadJS = setTimeout(function() {
            	    		self.trigger('onComplete') ;
            	    	}, settings.timeout) ;
            	    }
            	});

            }) ;


            /* When appear is triggered load ad. */
            self.one("load", function() {

            	// Detect if element is already loaded
                if (! self.isLoaded() ) {

                	// Lock other adverts load
                	$.lazyLoadAdRunning = true ;

                	// Have to load the current ad...
                	self.data('loading', 'true') ;
                	self.trigger('debug', 'start') ;

                	// Get original source to load
                	var srcOriginal = $(self).attr("original") ;

                	// Set fragmentId
                	self.history = {} ;

                	// -- Call script and let's dance
                	_debug('------------------------------  Lazy Load Ad CALL ----') ;
                	_debug('Context : ', self ) ;

                	// Bind document.write overload
                	self.trigger('docWrite_overload') ;

                	// Eval code
                	self.trigger('evalCode') ;

                	// Eval attached script
                	if ( srcOriginal ) {
                		self.trigger('loadJS', srcOriginal) ;
                	}

                };
            });
        });

        /* Force initial check if images should appear. */
        $(settings.viewport).trigger('checkLazyLoadAd');

        return this;

    };

    /* Convenience methods in jQuery namespace.           */
    /* Use as  $.belowthefold(element, {threshold : 100, container : window}) */

    $.belowthefold = function(element, settings) {
        if (settings.viewport === undefined || settings.viewport === window) {
            var fold = $(window).height() + $(window).scrollTop();
        } else {
            var fold = $(settings.viewport).offset().top + $(settings.viewport).height();
        }
        return fold <= $(element).offset().top - settings.threshold;
    };

    $.abovethetop = function(element, settings) {
        if (settings.viewport === undefined || settings.viewport === window) {
            var fold = $(window).scrollTop();
        } else {
            var fold = $(settings.viewport).offset().top;
        }
        return fold >= $(element).offset().top + settings.threshold  + $(element).height();
    };

})(jQuery);
