if(typeof console == 'undefined')
{
    var console = {
            log : function(){return null;},
            dir : function(){return null;}
        };
}

$.ajaxSetup({timeout:5000});
var jboxmap = {};
var jbox_queries = {};
var jboxHistoryQueue = {};
var veil = null;
$(function(){
    if(!$("#jbox-veil").length)
    {
        veil = $("<div/>");
        veil.prependTo("body");
        veil.css({
            'display':'none',
            'width':'100%',
            'height':'100%',
            'position':'fixed',
            'top':'0',
            'left':'0',
            'z-index':'999',
            'opacity':'0.82',
            'background'    : '#1c324d'
        });
        veil.attr('id','jbox-veil');
        // direkte jBoxKinder
    }
    else
    {
        veil = $("#jbox-veil");
    }

});
var veilActive = false;

var CustomEvent = function(owner) {
	// function to call on event fire
	var eventAction = null;

	// subscribe a function to the event
	this.subscribe = function(fn) {
		eventAction = fn;
	};

	// fire the event
	this.fire = function(eventArgs) {
		if (eventAction !== null) {
			eventAction(owner, eventArgs);
		} else {
			// alert('There was no function subscribed to the ' + mEventName + '
			// event!');
		}
	};
};

Array.prototype.inArray = function(search) {
	for ( var key in this) {
		if (search == this[key])
        {
			return key;
        }
	}
	return false;
};
var jboxInstance = function(id, options) {
    
    if(typeof jbox[id] != 'undefined')
    {
        return jbox[id];
    }
    
	// Variables
	this.id = id;
    timeout = null;
    this.containerID = id;
	this.settings = {};
    this.loading = false;
	this.contents = [];
	this.loadingState = "start";
    this.eventsReady = false;
    this.preloader = null;
    this.overlay = {
        container:null,
        context : this,
        contentBackup : null
    };
    this.overrideQuery = null;
    this.readyQueue = [];
    this.scroll = {
        up      : null,
        down    : null,
        context : this,
        visible_y : false,
        visible_x : false
    };
    this.newWidth = this.newHeight = this.oldWidth = this.oldHeight = 0;

	// Functions
	// this.prev, this.next, this.first, this.last, this.loadID, this.loadIndex,
	// this.loadAjax, this.play, this.stop, this.init, this.addContent,
	// this.set,

	// Events
	// this.ContentLoaded, this.Play,

	// EventHandlers
	// this.onContentLoaded,

	// Defaults
	this.defaults = {
		slideShow : false,
		slideShowSpeed : 5000,
		transition : 'none',
		transitionSpeed : 300,
		preloading : false, // Preload "next()" Content in some hidden div
        pipeForm : null,
        loaderID : 'dw-jbox-loader',
        overlay : false,
        scroll_y : false,
        scroll_x : false,
        activateID : null,
        activateClass : null,
        stretch     : false,
        overlayClose: false,
        overlayCancel:false,
        iframeHeight:null,
        iframeWidth:null,
        status:null,
        query:null,
        history:false
	};

	// Initialize Box, apply settings
	this.init = function() {
        if(typeof jbox_queries[id] == "undefined")
        {
            jbox_queries[id] = [];
        }
		if (typeof jbox[id] == 'undefined') {
			jbox[id] = this;
            var i = null;
			for (i in this.defaults) {
				this.settings[i] = this.defaults[i];
			}
			for (i in options) {
				this.settings[i] = options[i];
                if(i == 'overlay')
                    this.overlay.init();
			}

            this.preloader = "jbox-ajaxpreloader-"+id;
//			var tmp = $("<div id='jbox-ajaxpreloader-" + id + "' style='display:none;'></div>");

            //using clone for correct size calculations in preloader
            var tmp = $("#"+id).clone(false)
            tmp.attr("id",this.preloader).css({'display':'none'});
            tmp.appendTo("body");
		}
        this.ContentLoaded.fire();
		return this;
	};

	// Handling for Event: contentLoaded
	this.onContentLoaded = function(owner, eventArgs) {
        if(owner.settings.inputMode != 'stack')
        {
            owner.settings.slideShow = false;
        }
		if (owner.settings && owner.settings.slideShow) {
            clearTimeout(owner.timeout);
			owner.timeout = setTimeout("jbox['" + owner.id + "'].next('slideshow')",owner.settings.slideShowSpeed);
		}
        jbox_ready(owner.id);
        
        // Jetzt BoxMap aktualisieren!
        // Content Durchsuchen/ child-jboxes finden
        jboxmap[owner.id] = {children:[],query:jbox[owner.id].settings.query};
        
        // Alle jBoxKinder
        $("#"+owner.id).find('.isjbox').each(function(){
            jboxmap[owner.id].children.push(this.id);
        });
        
        // direkte jBoxKinder
        $("#"+owner.id).find('.isjbox').filter(function(){
            return $(this).parents('.isjbox').get(0) == $("#"+owner.id).get(0);
        }).each(function(){
            if(typeof jbox[this.id].overrideQuery == 'function')
            {
                //console.log("%s activating %s",owner.id,this.id);
                
                // if theres jboxes in the currently loaded jbox, and if theres queries to execute for them: do so
                var fn = jbox[this.id].overrideQuery;
                fn();
                jbox[this.id].overrideQuery = null;
            }
        });
        
        if(owner.readyQueue.length)
        {
            var fn,persistent;
            var tmpQueue = owner.readyQueue;
            owner.readyQueue = [];
            for(var i in tmpQueue)
            {
                fn = tmpQueue[i].fn;
                if(typeof fn == 'function')
                    fn();
                if(tmpQueue[i].persistent === true)
                {
                    owner.readyQueue.push(tmpQueue[i]);
                }
            }
            delete tmpQueue;
        }
        
        if(owner.settings.history && owner.settings.query !== null && owner.settings.inputMode != 'pipe')
        {
            var d = new Date();
            dhtmlHistory.add(owner.id+":"+d.getTime(), {query:owner.settings.query});
        }
//        if(typeof console != 'undefined')
//        {
//            console.dir(jboxmap);
//            console.log(owner.id);
//        }
	};
	this.ContentLoaded = new CustomEvent(this);
	this.ContentLoaded.subscribe(this.onContentLoaded);
	this.Play = new CustomEvent(this);
	this.Play.subscribe(this.onContentLoaded); // vorerst gleiche routine

	// Change some Settings
	this.set = function(modi) {
		for ( var i in modi) {
            if(i == 'overlay' && modi[i])
                this.overlay.init();
            if(i == 'activateID')
            {
                if(this.settings.activateID !== null && this.settings.activateClass !== null && $("#"+this.settings.activateID).length)
                {
                    $("#"+this.settings.activateID).removeClass(this.settings.activateClass);
                    this.settings.activateClass = null;
                }
            }
			this.settings[i] = modi[i];
            if(i == 'scroll_x' && modi[i])
                this.scroll.init();
            if(i == 'scroll_y' && modi[i])
                this.scroll.init();
		}
		return this;
	};

    this.scroll.init = function(){
        var box = $("#"+this.context.id);
        if($("#jbox-container-"+this.context.id).length == 0)
        {
            box.css({'overflow':'hidden','position':'relative','top':'0px','left':'0px'});
            var container = $('<div/>');
            container.css({'position':'absolute','left':'0','top':'0'});
            container.attr("id","jbox-container-"+this.context.id);
            container.addClass('jbox-scroll-container');
            //box.wrapInner(container); IE BUG !! using:
            var temp = box.children().remove();
            box.append(container.append(temp));

            this.context.containerID = "jbox-container-"+this.context.id;

        }

        // scroll Y
        if(this.context.settings.scroll_y && !$("#jbox-scrollup-"+this.context.id).length && !$("#jbox-scrolldown-"+this.context.id).length)
        {
            var ytmp = $("<div/>");
            ytmp.css({'position':'absolute'});
            var ytmplink = $("<a/>");
            ytmplink.attr('href','javascript:void(0);').css({'display':'block','width':'100%','height':'100%'});
            ytmp.append(ytmplink);

            this.up = ytmp.clone(false);
            this.down = ytmp.clone(false);

            this.up.css({'left':'0','top':"-50px"}).attr("id","jbox-scrollup-"+this.context.id);
            this.down.css({'left':'0','bottom':"-50px"}).attr("id","jbox-scrolldown-"+this.context.id);

            this.up.addClass('jbox-scroll-up jbox-scroll-control');
            this.down.addClass('jbox-scroll-down jbox-scroll-control');

            box.prepend(this.up);
            box.append(this.down);
        }

        // scroll X
        if(this.context.settings.scroll_x && !$("#jbox-scrollleft-"+this.context.id).length && !$("#jbox-scrollright-"+this.context.id).length)
        {
            var xtmp = $("<div/>");
            xtmp.css({'position':'absolute'});
            var xtmplink = $("<a/>");
            xtmplink.attr('href','javascript:void(0);').css({'display':'block','width':'100%','height':'100%'});
            xtmp.append(xtmplink);

            this.left = xtmp.clone(false);
            this.right = xtmp.clone(false);

            this.left.css({'left':"-50px",'top':'0'}).attr("id","jbox-scrollleft-"+this.context.id);
            this.right.css({'right':"-50px",'top':'0'}).attr("id","jbox-scrollright-"+this.context.id);

            this.left.addClass('jbox-scroll-left jbox-scroll-control');
            this.right.addClass('jbox-scroll-right jbox-scroll-control');

            box.prepend(this.left);
            box.append(this.right);
        }

    };
    this.overlay.init = function(){
        if($("#" + this.context.id).parent().length && $("#" + this.context.id).parent().hasClass("jbox-overlay-container"))
        {
            this.container = $("#jbox-overlay-" + this.context.id);
            return null;
        }

        console.log("init overlay for: %s",this.context.id);
        
        this.container = $('<div class="jbox-overlay-wrapper"><div class="jbox-overlay-container" style="position: relative;"></div></div>');

        this.container.attr("id","jbox-overlay-" + this.context.id);
        if($("#"+this.context.id).length > 1)
        {
            console.log("WARNING! found %s objects for ID: %s",$("#"+this.context.id).length,this.context.id);
        }
        $("#"+this.context.id).wrap(this.container);
        this.container = $("#jbox-overlay-" + this.context.id);

        if(this.context.settings.overlayClose == 'default')
        {
            var close = $("<div/>").addClass("jbox-overlay-close");
            var closelink = $("<a/>").attr("href","javascript:void(0);").addClass("jbox-overlay-closelink").text("close");
            close.append(closelink);
            this.container.prepend(close);
        }
        if(this.context.settings.overlayCancel == 'default')
        {
            //not done yet
        }

        // modify z-index of scroll-elements if found
        $("#"+this.context.id).find(".jbox-scroll-control").css('z-index',3000);
        $("#"+this.context.id).find(".jbox-scroll-container").css('z-index',2500);

    };

    this.overlay.initEvents = function(){
        var scope = this;
        var close = $("#jbox-overlay-" + this.context.id).find(".jbox-overlay-closelink:first");
        if(close.length && !close.get(0).hasCloseEvent)
        {
            close.click(function(){
                scope.close();
                this.hasCloseEvent = true;
            });
        }
    };

    this.overlay.open = function(){
        if(this.context.settings.overlay === true)
        {
            // muss ich nochmal holen, warum?
            this.container = $("#jbox-overlay-" + this.context.id);
            var scope = this.context;

            this.contentBackup = $("#"+this.context.containerID).children().clone(true);
            var tb = this.contentBackup.find(":input").each(function(idx){
                var tmp = null;
                if(this.type == 'textarea')
                {
                    tmp = $("#"+scope.containerID).children().find(":input").eq(idx).get(0);
                    if(tmp.type == 'textarea')
                        this.value = tmp.value;
                    return true;
                }
                if(this.type == 'select')
                {
                    // yet to code, bug in FF/Chrome/Safari predicted
                }
            });

            if(!veilActive)
            {
                var scope = this;
                veil.fadeIn("fast",function(){
                    scope.container.fadeIn("fast");
                });

                veilActive = true;
            }
        }
    };
    this.overlay.close = function(cancel){
        if(this.context.settings.overlay && veilActive)
        {
            if(typeof cancel != 'undefined' && cancel)
            {
                // cancel
                // alte werte rueckspeichern
                if(this.contentBackup.length)
                {
                    $("#" + this.context.containerID).empty();
                    this.contentBackup.appendTo($("#" + this.context.activeID).empty());
                }
            }
            else
            {
                // ok
                $("#" + this.context.containerID).children().appendTo($("#" + this.context.activeID).empty());
                this.context.activeID = null;
            }
            $("#jbox-overlay-" + this.context.id).fadeOut("fast");
            veil.fadeOut("fast");
            veilActive = false;
        }
    };

	this.loadAjax = function(query, pipe) {
        if(typeof jboxHistoryQueue[this.id] != 'undefined' && jboxHistoryQueue[this.id].length)
        {
            var qry = Base64.decode(jboxHistoryQueue[this.id]);
            delete jboxHistoryQueue[this.id];
            $(function(){
                setTimeout(qry,200);
            });
            
            return this;
        }
        if(this.loading)
        {
            return this;
        }
        else
        {
            this.loading = true;
        }
        if(veilActive && this.settings.overlay !== true)
        {
            veil.fadeOut("fast");
            veilActive = false;
        }
        pipe['is_jbox_request'] = ['true'];
        // loading-tween here
        if(this.settings.pipeForm !== null)
        {
            $("#"+this.settings.pipeForm+" :input").each(function (){
                DOMFFInputFix(this);
            });
            var currPipe = pipe;
            var formVals = $("#"+this.settings.pipeForm).formToArray();
            var currElement;
            for(var i=0;i<formVals.length;i=i+1)
            {
                currElement = formVals[i];
                if(currElement.value.length == 0)
                    currElement.value = '';
                if((typeof(currPipe[currElement.name]) == 'undefined' || currPipe[currElement.name] == null) && currElement.name.length > 0)
                {
                    currPipe[currElement.name] = [currElement.value];
                }
                else if(currElement.name.substr(currElement.name.length-2,2) == '[]')
                {
                    currPipe[currElement.name].push(currElement.value);
                }
            }
            pipe = currPipe;
        }
		this.loadingState = "out";
		var context = this;
		this.transition(function() {

//            $("#"+context.containerID).empty();
            $("#"+context.containerID).find("[id]").each(function(){
                this.id = '';
            });
            var fn = function() {
                if(context.settings.loaderID !== null && $("#"+context.settings.loaderID).length)
                {
                    $("#"+context.settings.loaderID).fadeOut("fast",function(){
                        context.loadID("jbox-ajaxpreloader-" + context.id,'ajax');
                        $("#jbox-ajaxpreloader-" + context.id).empty();
                        context.prepareForms(context);
                    });
                }
                else
                {
                    context.loadID("jbox-ajaxpreloader-" + context.id,'ajax');
                    $("#jbox-ajaxpreloader-" + context.id).empty();
                    context.prepareForms(context);
                }
            };
            
            if(context.settings.iframe)
            {
                var IFpipe = '';
                if(query.indexOf('?') == -1)
                 IFpipe = '?';
                else
                    IFpipe = '&';
                for(var v in pipe)
                {
                    IFpipe += v+"="+pipe[v]+"&";
                }
                var iframe = $('<iframe id="jbox-iframe-' + context.id + '"/>');
                iframe.css({
                    'border':'0',
                    'margin':'0',
                    'padding':'0',
                    'width':'100%',
                    'height':'100%'
                }).attr("src",query+IFpipe);
                
                if(context.settings.iframeHeight !== null)
                {
                    if(context.settings.iframeHeight.indexOf('px') == -1)
                        context.settings.iframeHeight += "px";
                    iframe.css('height',context.settings.iframeHeight);
                }
                if(context.settings.iframeWidth !== null)
                {
                    if(context.settings.iframeWidth.indexOf('px') == -1)
                        context.settings.iframeWidth += "px";
                    iframe.css('width',context.settings.iframeWidth);
                }

                context.settings.iframeHeight = null;
                context.settings.iframeWidth = null;
                
                $("#jbox-ajaxpreloader-" + context.id).empty().append(iframe);
//                iframe = $("#jbox-iframe-"+context.id)
//                var innerDoc = (iframe.get(0).contentDocument) ? iframe.get(0).contentDocument : iframe.get(0).contentWindow.document;
//                iframe.height(innerDoc.body.scrollHeight + 35);
                iframe.load(function(){
//                    var innerDoc = (this.contentDocument) ? this.contentDocument : this.contentWindow.document;
//                    if(this.contentDocument){
//                        this.height = this.contentDocument.body.offsetHeight + 35;
//                        this.width = this.contentDocument.body.offsetWidth + 35;
//                    } else {
//                        this.height = this.contentWindow.document.body.scrollHeight;
//                        this.width = this.contentWindow.document.body.scrollWidth;
//                    }
//                    $(this).height(innerDoc.body.scrollHeight + 35);
//                    $(this).width(innerDoc.body.scrollWidth + 35);
                    
//                    console.log("offset: %sx%s; scroll: %sx%s",innerDoc.body.offsetWidth,innerDoc.body.offsetHeight,innerDoc.body.scrollWidth,innerDoc.body.scrollHeight)
                    
                    context.scroll.resize();
                });
                fn();
            }
            else
            {
                $("#jbox-ajaxpreloader-" + context.id).load(query, pipe,fn);
            }
        });

        return this;
	};

    this.prepareForms = function(context){
        // adjust forms to work the jbox-way
        var forms = $("#" + context.id).children().find("form");
        if(context.settings.pipeForm !== null)
        {
            forms = forms.add("#"+context.settings.pipeForm);
        }
        forms.each(function(){
            // if id empty, create one
            if(!$(this).attr("id").length)
            {
                var ranNum=0;
                while($("#"+context.id+"-sub-"+ranNum).length)
                {
                    ranNum = Math.floor(Math.random()*1001);
                }
                $(this).attr("id",context.id+"-sub-"+ranNum);
            }

            var formID = $(this).attr("id");
            var formQuery = $(this).attr("action");

            // avoid javascript:void(0); or other malformed urls
            var evil = formQuery.match(/[;\(\)]+/);
            if(evil && evil.length >=1)
            {
                formQuery = '/netautor/napro4/appl/na_professional/parse.php';
            }

            this.action = "javascript:void(0);";

            if(typeof this.hasJboxSubmit == 'undefined' || !this.hasJboxSubmit)
            {
                this.submit = function(){
                    context.set({pipeForm:formID}).loadAjax(formQuery,{});
                }
                this.hasJboxSubmit = true;
            }
        });
    };

	// Add new Content-Divs to the Collection
	this.addContent = function(contentID) {
		if (!this.contents.inArray(contentID)) {
			this.contents.push(contentID);
			if (false && this.contents.inArray(contentID) === 0) {
				// load first
				this.loadID(contentID);
			}
		} else {
			// Error-Handling?
		}
		return this;
	};

	// Called before and after new Content is loaded
	this.transition = function(callback) {
        var context = this;
        var containerFade = 0.001;
		if (this.loadingState == "content" || this.loadingState == "loading") {
			callback(this);
            return;
		} else if (this.loadingState == "out") {
			this.loadingState = "loading";
			if (this.settings.transition == "fade") {
                if($("#" + this.containerID).find(".transition").length)
                {
                    $("#" + this.containerID).find(".transition").fadeTo(this.settings.transitionSpeed,0.001);
                    containerFade = 0.8;
                }
                $("#" + this.containerID).fadeTo(this.settings.transitionSpeed,containerFade,function() {
                        callback(context);
                        return;
                    });

			} else {
				callback(this);
                return;
			}
		} else if (this.loadingState == "start" || this.loadingState == "in") {
			this.loadingState = "content";
            var diff = Math.abs(parseInt(context.newWidth)-parseInt(context.oldWidth)) + Math.abs(parseInt(context.newHeight)-parseInt(context.oldHeight));
            if(context.settings.overlay && (diff > 0 || $("#jbox-overlay-" + context.id).height() != context.newHeight))
            {
                var container = $("#jbox-overlay-" + context.id);
                var height = context.newHeight;
                var width = context.newWidth;
                var left = ($(window).width() - width - 60)/2;
                var top = ($(window).height() - height -60)/2;
                container.children(".jbox-overlay-container").animate({'width':width+"px",'height':height+"px"},"normal");
                container.animate({'left':left+"px",'top':top+"px"},"normal",false,function(){
                    if(context.settings.transition == "fade") {
                        if($("#" + context.containerID).find(".transition").length)
                        {
                            $("#" + context.containerID).find(".transition").css("opacity",0);
                            $("#" + context.containerID).find(".transition").fadeTo(context.settings.transitionSpeed,1);
                        }
                        $("#" + context.containerID).fadeTo(context.settings.transitionSpeed,1,function() {
                                callback(context);
                                return;
                            });
                    } else {
                        callback(context);
                        return;
                    }
                });
            }
			else if(this.settings.transition == "fade") {
                if($("#" + this.containerID).find(".transition").length)
                {
                    $("#" + this.containerID).find(".transition").css("opacity",0);
                    $("#" + this.containerID).find(".transition").fadeTo(this.settings.transitionSpeed,1);
                }
                $("#" + this.containerID).fadeTo(this.settings.transitionSpeed,1,function() {
                        callback(context);
                        return;
                    });
			} else {
				callback(context);
                return;
			}
		} else {
			callback(context);
            return;
		}
	};

    this.scroll.resize = function(){
        // SCROLLING
        var ptop = 0;
        var pleft = 0;
        if(this.context.settings.scroll_y === true)
        {
            var up = $("#jbox-scrollup-"+this.context.id);
            var down = $("#jbox-scrolldown-"+this.context.id);

            //vscroll in
            if($("#"+this.context.containerID).outerHeight() > $("#"+this.context.id).height() && !this.visible_y)
            {
                up.animate({'top':'0px','opacity':1},"slow",'easeOutExpo');
                down.animate({'bottom':'0px','opacity':1},"slow",'easeOutExpo');
                this.visible_y = true;
            }

            //vscroll out
            if($("#"+this.context.containerID).outerHeight() <= $("#"+this.context.id).height() && this.visible_y)
            {
                up.animate({'top':"-"+parseInt(up.outerHeight())+"px",'opacity':0.01},"slow",'easeOutExpo');
                down.animate({'bottom':"-"+parseInt(down.outerHeight())+"px",'opacity':0.01},"slow",'easeOutExpo');
                this.visible_y = false;
            }
            if(this.visible_y)
                ptop = up.outerHeight();
        }
        if(this.context.settings.scroll_x === true)
        {
            var left = $("#jbox-scrollleft-"+this.context.id);
            var right = $("#jbox-scrollright-"+this.context.id);

            //hscroll in
            if($("#"+this.context.containerID).outerWidth() > $("#"+this.context.id).width() )
            {
                left.animate({'left':'0px','opacity':1},"slow",'easeOutExpo');
                right.animate({'right':'0px','opacity':1},"slow",'easeOutExpo');
                this.visible_x = true;
            }

            //hscroll out
            if($("#"+this.context.containerID).outerWidth() <= $("#"+this.context.id).width() )
            {
                left.animate({'left':"-"+parseInt(left.outerWidth())+'px','opacity':0.01},"slow",'easeOutExpo');
                right.animate({'right':"-"+parseInt(right.outerWidth())+'px','opacity':0.01},"slow",'easeOutExpo');
                this.visible_x = false;
            }
            if(this.visible_x)
                pleft = left.outerWidth();
            if(pleft === null)
                pleft = 20;
        }
        $("#"+this.context.containerID).animate({'top':parseInt(ptop)+'px','left':parseInt(pleft)+'px'},"slow",'easeOutExpo');
    };

    this.scroll.initEvents = function(){
        var scope = this.context;
        var scroll = this;


        var easing = 'easeOutExpo';
        var duration = 'slow';
        if(scope.settings.scroll_y === true && $("#"+scope.id).height() > 0)
        {
            var up = $("#jbox-scrollup-"+scope.id);
            var down = $("#jbox-scrolldown-"+scope.id);

            // MouseScroll
            hookEvent(this.context.id, 'mousewheel', function(e){
                var up = $("#jbox-scrollup-"+scope.id);
                var down = $("#jbox-scrolldown-"+scope.id);

                if(!scroll.visible_y)
                    return cancelEvent(e);

                e = e ? e : window.event;
                var normal = e.detail ? e.detail * -1 : e.wheelDelta / 40;
                cnt = $("#"+scope.containerID);
                var step;
                var content = $("#"+scope.containerID);

                if(normal < 0)
                {
                    step = -50;
                    if((parseInt(content.css('top')) + parseInt(step)) < $("#"+scope.id).height() - content.outerHeight() - down.outerHeight())
                    {
                        step = -(parseInt(content.css('top')) - $("#"+scope.id).height() + content.outerHeight() + down.outerHeight());
                    }
                }
                else
                {
                    step = 50;
                    if((parseInt(content.css("top"))+parseInt(step)) > up.outerHeight())
                    {
                        step = -parseInt(content.css("top")) + up.outerHeight();
                    }
                }

                cnt.css('top',(parseInt(cnt.css('top'))+step)+'px');

                return cancelEvent(e);
            });

            if(up.height() > 0 && !up.get(0).hasScrollEvent)
            {
                up.click(function(e){
                    var step = ($("#"+scope.id).height()-2*up.outerHeight())*0.9;
                    var content = $("#"+scope.containerID);
                    if(content.outerHeight() < $("#"+scope.id).height() - up.outerHeight() - down.outerHeight())
                    {
                        return false;
                    }
                    if((parseInt(content.css("top"))+parseInt(step)) > up.outerHeight())
                    {
                        step = -parseInt(content.css("top")) + up.outerHeight();
                    }

                    content.animate({top:"+="+step+"px"},duration,easing,function(){
                        if((parseInt(content.css("top"))) > up.outerHeight())
                        {
                            step = -parseInt(content.css("top")) + up.outerHeight();
                            content.animate({top:"+="+step+"px"},duration);
                        }
                    });
                });
                up.get(0).hasScrollEvent = true;
            }
            if(down.height() > 0 && !down.get(0).hasScrollEvent)
            {
                down.click(function(e){
                    var step = ($("#"+scope.id).height()-2*down.outerHeight())*0.9;
                    var content = $("#"+scope.containerID);
                    if(content.height() < $("#"+scope.id).height() - up.outerHeight() - down.outerHeight())
                    {
                        return false;
                    }
                    if((parseInt(content.css('top')) - step) < $("#"+scope.id).height() - content.outerHeight() - down.outerHeight())
                    {
                        step = parseInt(content.css('top')) - $("#"+scope.id).height() + content.outerHeight() + down.outerHeight();
                    }
                    content.animate({'top':"-="+step+"px"},duration,easing,function(){
                        if((parseInt(content.css('top'))) < $("#"+scope.id).height() - content.outerHeight() - down.outerHeight())
                        {
                            step = parseInt(content.css('top')) - $("#"+scope.id).height() + content.outerHeight() + down.outerHeight();
                            content.animate({'top':"-="+step+"px"},duration);
                        }
                    });
                });
                down.get(0).hasScrollEvent = true;
            }
        }
        if(scope.settings.scroll_x === true && $("#"+scope.id).width() > 0)
        {
            var left = $("#jbox-scrollleft-"+scope.id);
            var right = $("#jbox-scrollright-"+scope.id);

            if(left.width() > 0 && !left.get(0).hasScrollEvent)
            {

                left.click(function(e){
                    var step = ($("#"+scope.id).width()-2*left.outerWidth())*0.9;
                    var content = $("#"+scope.containerID);
                    if(content.outerWidth() < $("#"+scope.id).width() - left.outerWidth() - right.outerWidth())
                    {
                        return false;
                    }
                    if((parseInt(content.css("left"))+parseInt(step)) > left.outerWidth())
                    {
                        step = -parseInt(content.css("left")) + left.outerWidth();
                    }

                    content.animate({left:"+="+step+"px"},duration,easing,function(){
                        if(parseInt(content.css("left")) > left.outerWidth())
                        {
                            step = -parseInt(content.css("left")) + left.outerWidth();
                            content.animate({'left':"+="+step+"px"},duration);
                        }
                    });
                });
                left.get(0).hasScrollEvent = true;
            }
            if(right.width() > 0 && !right.get(0).hasScrollEvent)
            {
                right.click(function(e){
                    var step = ($("#"+scope.id).width()-2*right.outerWidth())*0.9;
                    var content = $("#"+scope.containerID);
                    if(content.width() < $("#"+scope.id).width() - left.outerWidth() - right.outerWidth())
                    {
                        return false;
                    }
                    if((parseInt(content.css('left')) - step) < $("#"+scope.id).width() - content.outerWidth() - right.outerWidth())
                    {
                        step = parseInt(content.css('left')) - $("#"+scope.id).width() + content.outerWidth() + right.outerWidth();
                    }
                    content.animate({left:"-="+step+"px"},duration,easing,function(){
                        if(parseInt(content.css('left')) < $("#"+scope.id).width() - content.outerWidth() - right.outerWidth())
                        {
                            step = parseInt(content.css('left')) - $("#"+scope.id).width() + content.outerWidth() + right.outerWidth();
                            content.animate({'left':"-="+step+"px"},duration);
                        }
                    });
                });
                right.get(0).hasScrollEvent = true;
            }
        }
    };

	// Display new Content
	this.loadID = function(contentID) {
        console.log("%s loading from %s.",this.id,contentID);
        if(typeof jboxHistoryQueue[this.id] != 'undefined' && jboxHistoryQueue[this.id].length)
        {
            $("#"+contentID).find("[id]").each(function(){
                this.id = '';
            });
            var qry = Base64.decode(jboxHistoryQueue[this.id]);
            delete jboxHistoryQueue[this.id];
            $(function(){
                setTimeout(qry,100);
            });
            
            return this;
        }
        var modeAjax = false;
        if(arguments[1] == 'ajax')
            modeAjax = true;
		var idx = this.contents.inArray(contentID);
		if (true || idx || (typeof arguments[1] != 'undefined' || arguments[1] == 'ajax'))
        {
            if(veilActive && this.settings.overlay !== true)
            {
                veil.fadeOut("fast");
                veilActive = false;
            }
// save back

            
			// copy currently Displayed Content back to this.activeID
			if (this.activeID != this.preloader && $("#" + this.activeID).length && jQuery.trim($("#" + this.containerID).html()).length && jQuery.trim($("#" + this.containerID).html()) !== '')
            {
                // ID-PROBLEM LEFT TO FIX
                $("#" + this.containerID).contents().replaceWith("<div style='width:2px; height: "+this.newHeight+"px;'/>").appendTo($("#" + this.activeID).empty());
			}

			if (this.loadingState != "loading") {
				this.loadingState = "out";
			}

			// Whatever transition is defined, execute it, load new content,
			// execute it again
			var context = this;
			this.transition(function() {

					// Set new "current"
					context.activeIndex = idx;
					context.activeID = contentID;

				// actually LOAD the content (jquery,..)
                    context.oldWidth    = context.newWidth;
                    context.oldHeight   = context.newHeight;
                    context.newWidth    = $("#" + contentID).outerWidth();
                    context.newHeight   = $("#" + contentID).outerHeight();
// load content

                    
                    $("#" + contentID).contents().appendTo($("#" + context.containerID).empty());
                    
                    if(context.settings.activateID !== null && context.settings.activateClass !== null && $("#"+context.settings.activateID).length)
                    {
                        $("#"+context.settings.activateID).addClass(context.settings.activateClass);
                    }

                    if(context.settings.overlay === true)
                    {
                        context.overlay.open();
                    }


					context.loadingState = "in";

					context.transition(function() {
                        context.ContentLoaded.fire();
                        context.loading = false;
                        if(context.settings.stretch != false)
                        {
                            var stretch = context.settings.stretch;
                            var pos = $("#"+context.id).offset();
                            var stretchHeight = null;
                            var stretchWidth  = null;
                            if(stretch == 'bottom')
                            {
//                                stefan hat hier document in window umgeändet ;-)
//                                stretchHeight = $(document).height() - pos.top-20;
//                                    console.log("document: %s, window: %s, body: %s",$(document).scrollTop(),$(window).scrollTop(),$("body").scrollTop());
                                stretchHeight = $(window).height() - (pos.top - $(window).scrollTop())-20;
                                $("#"+context.id).css({'height':stretchHeight+"px"});
//                                $("#"+context.id).animate({'height':stretchHeight+"px"},"slow","easeOutExpo");
                            }
                        }
                        if(context.settings.scroll_y === true || context.settings.scroll_x === true)
                        {
                            context.scroll.initEvents();
                            context.scroll.resize();
                        }

                        if(context.settings.overlay === true)
                        {
                            context.overlay.initEvents();
                        }


                        // Workaround weil boxen in ajaxboxen zu frueh geladen werden anscheinend
                        if(modeAjax)
                        {
                            

//                            for(var box in jbox)
//                            {
//                                if($("#"+context.containerID).find("#"+box).length)
//                                {
//                                    if(!jbox[box].settings.overlay && typeof jbox[box].activeIndex != 'undefined' && jbox[box].activeIndex !== null && jbox[box].activeIndex !== false)
//                                        jbox[box].loadIndex(jbox[box].activeIndex);
//                                }
//                            }
                        }
					});
				});
		} else {
            if(typeof console != 'undefined' && typeof console.log == 'function')
            {
                console.log("ID '%s' not found in jBox '%s'",contentID,this.id);
            }
			// Error-Handling?
		}

		return this;
	};


	// Wrapper for convenient access
	this.loadIndex = function(index) {
		if (typeof this.contents[index] != 'undefined') {
			this.loadID(this.contents[index]);
		} else {
			// Error-Handling?
		}

		return this;
	};

	// Display next Content in Collection
	this.next = function() {
		// Slideshow already stopped
		if (arguments.length == 1 && arguments[0] == 'slideshow' && !this.settings.slideShow)
        {
			return this;
        }
        
        if(jbox_queries[this.id].length && this.settings.inputMode == 'stack')
        {
            var qidx = jbox_queries[this.id].inArray(this.settings.query);
            if(qidx === false)
            {
                qidx = 0;
                if(jbox_queries[this.id].length > 1)
                {
                    qidx = 1;
                }
                
            }else if(qidx == (jbox_queries[this.id].length - 1))
            {
                qidx = 0;
            }
            else
            {
                qidx = parseInt(qidx) + 1;
            }
            
            this.settings.query = jbox_queries[this.id][qidx];
            eval(Base64.decode(jbox_queries[this.id][qidx]));
        }
        else
        {
            var nextIndex;
            nextIndex = parseInt(this.activeIndex) + 1;

            if (nextIndex == this.contents.length) {
                nextIndex = 0;
            }
            return this.loadIndex(parseInt(nextIndex));
        }

//		if (nextIndex == this.contents.length) {
//			nextIndex = 0;
//		}
		return this; //.loadIndex(parseInt(nextIndex));
	};

	// Display Last Content in Collection
	this.last = function() {
		if (!this.contents.length)
        {
			return false;
        }
		var lastIndex = parseInt(this.contents.length) - 1;
		return this.loadIndex(parseInt(lastIndex));
	};

	// Display First Content in Collection
	this.first = function() {
		var firstIndex = 0;
		return this.loadIndex(parseInt(firstIndex));
	};

	// Display previous Content in Collection
	this.prev = function() {
		var prevIndex;
		prevIndex = parseInt(this.activeIndex) - 1;
		if (prevIndex == -1) {
			prevIndex += parseInt(this.contents.length);
		}
		return this.loadIndex(parseInt(prevIndex));
	};

	// Start Slideshow
	this.play = function() {
        if(!this.settings.slideShow)
        {
            this.settings.slideShow = true;
            this.settings.inputMode = 'stack';
            this.Play.fire();
            console.log("%s now playing",this.id);
        }
		return this;
	};

	// Stop Slideshow
	this.stop = function() {
		this.settings.slideShow = false;
		return this;
	};
    
    this.overrideNextQuery = function(fn){
        if(typeof fn == 'function')
        {
            this.overrideQuery = fn;
        }
    };
    
    this.ready = function(fn,persistent){
        if(typeof persistent == 'undefined' || persistent !== true)
            persistent = false;
            
        if(typeof fn == 'function')
        {
            this.readyQueue.push({'fn':fn,'persistent':persistent});
        }
    };
    this.inactivateIDs = function(){
        $("#"+this.containerID).find("[id]").filter(function(){
                return this.id.indexOf("-inactive") == -1;
            }).each(function(){
                this.id = this.id+"-inactive";
        });
        return this;
    };
    
    this.activateIDs = function(){
        $("#"+this.containerID).find("[id*='-inactive']").each(function(){
                this.id = this.id.split('-inactive').join('');
        });
        return this;
    };

	// "Constructor"

	return this.init();
};
function hookEvent(element, eventName, callback)
{
  if(typeof(element) == "string")
    element = document.getElementById(element);
  if(element == null)
    return;
  if(element.addEventListener)
  {
    if(eventName == 'mousewheel')
      element.addEventListener('DOMMouseScroll', callback, false);
    element.addEventListener(eventName, callback, false);
  }
  else if(element.attachEvent)
    element.attachEvent("on" + eventName, callback);
}

function cancelEvent(e)
{
  e = e ? e : window.event;
  if(e.stopPropagation)
    e.stopPropagation();
  if(e.preventDefault)
    e.preventDefault();
  e.cancelBubble = true;
  e.cancel = true;
  e.returnValue = false;
  return false;
}


function DOMFFInputFix(inputField) {
    // if the inputField ID string has been passed in, get the inputField object
    if (typeof inputField == "string") {
        inputField = document.getElementById(inputField);
    }
    if (inputField.type == "select-one") {
        for (var i=0; i<inputField.options.length; i++) {
            if (i == inputField.selectedIndex) {
                inputField.options[inputField.selectedIndex].setAttribute("selected","selected");
            }
        }
    } else if (inputField.type == "text") {
        inputField.setAttribute("value",inputField.value);
    } else if (inputField.type == "textarea") {
        inputField.setAttribute("value",inputField.value);
    } else if ((inputField.type == "checkbox") || (inputField.type == "radio")) {
        if (inputField.checked) {
            inputField.setAttribute("checked","checked");
        } else {
            inputField.removeAttribute("checked");
        }
    }
}

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
 
var Base64 = {
 
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
 
	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = Base64._utf8_encode(input);
 
		while (i < input.length) {
 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
 
		}
 
		return output;
	},
 
	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) {
 
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
 
		}
 
		output = Base64._utf8_decode(output);
 
		return output;
 
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	}
 
}
function jbox_ready(id)
{
    $("#"+id).find(".jclickinput").each(function(){

        var input = $(this).css('display', 'none');
        var classes = input.attr('class').toString().replace('/jclickinput/','');
        var link = $("<a href='javascript:void(0);'/>").text(input.val()).css('float','left').css('display','block');
        link.attr("class",classes);
        input.after(link);

        // toInput
        link.click(function(e){
            var lnk = $(e.target);
            var inp = lnk.prev("input");
            lnk.fadeOut("fast",function(){
                inp.val(lnk.text()).fadeIn("fast",function(){
                    inp.focus();
                });
            });
        });
        // toLink
        input.blur(function(e){
            var inp = $(e.target);
            var lnk = inp.next("a");
            inp.fadeOut("fast",function(){
                var occupier = $("#"+id).find("input.jclickinput.unique").filter(function(){
                    return (this != inp.get(0) && $(this).val() == inp.val());
                }).eq(0);
                if(inp.hasClass("unique") && occupier.length)
                {
                    var tmpBg = occupier.parent().css("background-color");
                    var tmpPar = occupier.parent();
                    while(!tmpBg.length || tmpBg == 'transparent')
                    {
                        tmpPar = tmpPar.parent();
                        tmpBg = tmpPar.css("background-color");
                    }
                    occupier.parent().animate({'backgroundColor' : 'red'},"fast",false,function(){
                        occupier.parent().animate({'backgroundColor': tmpBg},"slow");
                    });
                    inp.val(lnk.text());
                }
                else
                {
                    lnk.text(inp.val());
                }
                lnk.fadeIn("fast");
            });
        });
        input.keydown(function(e){
            if(e.keyCode == 13)
            {
                $(this).blur();
            }
        });
    });
    $("#"+id).find(".jclickselect").each(function(){

        var select = $(this);
        var input = $('<input/>').addClass("inp").addClass("inp3").css("display", "none");
        select.after(input);
        select.change(function(){
            var selval = select.find("option:selected").val();
            if(selval == 'jclick-new')
            {

                select.fadeOut("fast",function(){
                    input.val("").fadeIn("fast",function(){
                        input.focus();
                    });
                });
            }
        });
        input.blur(function(){
            var newVal = jQuery.trim(input.val());
            if(newVal !== '' && !select.find("option[value='"+newVal+"']").length)
            {
                var newOp = $("<option/>").val(newVal).text(newVal);
                select.append(newOp);
                select.get(0).selectedIndex = select.find("option").length-1;
            }
            else
            {
                select.get(0).selectedIndex = 0;
            }
            input.fadeOut("fast",function(){
                select.fadeIn("fast");
            });
        });
        input.keydown(function(e){
            if(e.keyCode == 13)
            {
                $(this).blur();
            }
        });
    });

    $("#"+id).find(".jclickmultiple").each(function(){

        var select = $(this);

        var input = $('<input/>').addClass("inp").addClass("inp3").css("display", "none");
        select.after(input);

        var cont = $("<div/>");
        cont.css({float: 'left', clear: 'both', 'margin-top' : '5px'});
        var prot = $("<div/>");

        input.after(cont);
        var options = [];
        var curr_opts = select.find("option:selected");

        select.get(0).multiple = null;
        var selName = select.get(0).name;
        select.get(0).name = null;

        var addOption = function(option)
        {
            var existing = cont.find("div:contains('"+option+"')");
            if(!existing.length)
            {
                var newOp = $("<div/>");
                newOp.addClass("clipbox");
                newOp.css('display','none');
                var remove = $("<a/>").attr("href","javascript:void(0);").text("x");
                var hidden = $('<input type="hidden" name="'+selName+'"/>');
                hidden.val(option);

                newOp.append(option).append(remove).append(hidden);
                newOp.fadeIn("fast");

                remove.click(function(){
                    $(this).parent().fadeOut("fast",function(){
                        $(this).remove();
                    });
                });
                cont.append(newOp);
            }
            else
            {
                var tmpBg = existing.css("background-color");
                var tmpPar = existing;
                while(!tmpBg.length || tmpBg == 'transparent')
                {
                    tmpPar = tmpPar.parent();
                    tmpBg = tmpPar.css("background-color");
                }
                existing.animate({'backgroundColor' : 'red'},"fast",false,function(){
                    existing.animate({'backgroundColor' : tmpBg},"slow");
                });
            }
        }

        // existing selections
        curr_opts.each(function(){
            addOption($(this).val());
        });

        input.blur(function(){
            var newVal = jQuery.trim(input.val());
            if(newVal !== '' )
            {
                if(!select.find("option[value='"+newVal+"']").length)
                {
                    var newOp = $("<option/>").val(newVal).text(newVal);
                    select.append(newOp);
                }
                addOption(newVal);
            }
            select.get(0).selectedIndex = 0;
            input.fadeOut("fast",function(){
                select.fadeIn("fast");
            });
        });
        input.keydown(function(e){
            if(e.keyCode == 13)
            {
                $(this).blur();
            }
        });
        select.change(function(){
            var selval = select.find("option:selected").val();
            if(selval == 'jclick-new')
            {
                select.fadeOut("fast",function(){
                    input.val("").fadeIn("fast",function(){
                        input.focus();
                    });
                });
            }
            else if(selval.length > 0)
            {
                addOption(selval);
                this.selectedIndex = 0;
            }
        });

    });

    $('div.fragment').mouseover(function() {
        var height = ($(this).children('.todo').html() !== '') ? $(this).height() - 19 : $(this).height() - 2;
        height = (height > 25) ? height : 25;
        $(this).addClass('active');
        $(this).find('.overlay').height(height).css('overflow', 'hidden');
    }).mouseout(function(){
        $(this).removeClass('active');
        $(this).find('.overlay').removeAttr('style');
    });

    if (id == 'mainedit')
    {
        initSortable();
    }
}
var RSHjBoxListener = function(newLocation, historyData) {
    var debug = window.historyStorage.debugMode;
        
    if(typeof historyData == 'undefined' || historyData === null || typeof historyData.query == 'undefined' || !jQuery.trim(historyData.query).length)
    {
        if(debug)
            alert('no query found: going back in history');
        history.back();
    }
    else
    {
        var hash = newLocation.split(':');
        var targetBox = hash[0];
        if(debug)
            alert('query found for box: '+targetBox);
        $(function(){
            if(typeof jbox != 'undefined' && typeof jbox[targetBox] != 'undefined' && $("#"+targetBox).length)
            {
                if(typeof historyData.query != 'undefined' && jQuery.trim(historyData.query).length)
                {
                    if(debug)
                        alert('box '+targetBox+' found: executing query');
                    // Execute query
                    eval(Base64.decode(historyData.query));
                }
            }
            else
            {
                if(debug)
                    alert('box '+targetBox+' not found: pushing to querystack');
                jboxHistoryQueue[targetBox] = historyData.query;
            }
        });
    }
}
