var BoxControl = (function () {
    var thisObj             = this;
    var activeBoxes         = new Object();
    var additionalBoxParser = new Array();
    var preloader           = false;
    var preloaderConfig     = null;

    function addActiveContainer (element) {
        /*
                      * sollte sich der Kind Container noch nicht im Array befinden fügen wir ihn noch hinzu
                      * des weiteren das Object welches den Zustand des aktuellen Containers beschreibt füllen
                      */
        if(!activeBoxes[element.getAttribute('container')]) {
            activeBoxes[element.getAttribute('container')] = {
                loading:false,
                loadObject:null,
                childBoxes:new Array,
                childsLoading:false,
                preloadContainer:{}
            }
        }          
        /* 
                       * preload Container für das Preload Object in das spezifische Box Object speichern
                       * um es später bei gewünschten Preloader direkt in der Box anzuzeigen
                       */
        Object.extend(activeBoxes[element.getAttribute('container')].preloadContainer,preloaderConfig);
        
        //prüfen ob es sich um ein Kind Object handelt 
        var object = Element.get(element.getAttribute('container'));
        
        while (object.offsetParent) {
            object = object.parentNode;
            // es handelt sich hierbei um ein Kindobject
            if(object.id != '' && activeBoxes[object.id]) {
                with(activeBoxes[object.id]) {
                    if(!childBoxes.inArray(element.getAttribute('container'))) {
                        activeBoxes[object.id].childBoxes.push(element.getAttribute('container'));
                    }
                }
            }
        }
    }
    
    function parseBox (boxObject) {
        var childContainers = new Array();
        var link_elements   = Element.getElements(boxObject,'a');
        var form_elements   = Element.getElements(boxObject,'form');
        
        /*
                      * Link Elemente parsen 
                      * load für lade weiteren Inhalt über Ajax
                      * close schliesse den Container 
                      * beide Zustände benötigen einen gültigen container welcher die ID der zu behandelnden Box beinhaltet
                      */ 
        for(var i = 0 ; i < link_elements.length;i++) {  
            if(link_elements[i].getAttribute('init') == 'load' ||
               link_elements[i].getAttribute('init') == 'close') {
                if(!link_elements[i].getAttribute('container')) 
                    alert('kein Container angegeben im Link inhalt kann weder'+ 
                          'geladen noch geschlossen werden');
                          
                addActiveContainer(link_elements[i]);
                Element.addEvent(link_elements[i],'click',captureEvents);
            }   
        }
        
        /*
                     * Formulare laden die über Ajax versendet werden können
                     */
        for(var i = 0 ; i < form_elements.length ; i++) {
            if(form_elements[i].getAttribute('init') == 'load') {
                if(!form_elements[i].getAttribute('container')) 
                    alert("formulare können leider nicht gesendet werden da kein"+
                          "gültiger Container angegeben wurde");
                          
                addActiveContainer(form_elements[i]);
                //senden des Formulares über den normalen weg  verhindern 
                form_elements[i].onsubmit = function(){return false;}
                            
                //alle Inputfelder und buttons einsammeln
                var inputfields = Element.getElements(form_elements[i],'input');
                var buttons     = Element.getElements(form_elements[i],'a');
                
                //Events auf die Inputfelder legen keydown
                //Events auf die Buttons legen A Tags 
                                    
                for(var j = 0 ; j < inputfields.length;j++) {
                    Element.addEvent(inputfields[j],'keydown',sendFormAjax);
                }
                
                for(var j = 0;j < buttons.length;j++)  {
                    if(buttons[j].className.match(/submit/gi)) {
                        Element.addEvent(buttons[j],'click',sendFormAjax)
                    }
                }
            }
        }
    }
    
    function parseImageFilesFromBox (boxContent,cb,boxObject) {
    
        var imagePattern =  /([^"]+\.)(?=(jpg|png|gif))([^"]+)/gi;
        var found = boxContent.match(imagePattern);
        var parsedContent = null;
        var loaded = false;
        
        if(found && found.length > 0) {
            if(preloader) {
                new Preloader.addPreload(new Load.imageFile(found),boxObject.preloadContainer,imagesLoaded);
            } else {
                var loader = new Load.imageFile(found);
                    loader.initLoad(null,imagesLoaded,null);
            }
        } else cb();
        
        function imagesLoaded () {
            cb();
        }
    }

    function captureEvents (event) {
        var evt = (event)?event:(window.event)?window.event:'';
        var tar = evt.target || evt.srcElement;
        
        if(evt.preventDefault) 
            evt.preventDefault();
        else 
            evt.returnValue = false;                      
        
        //den Link finden wo der Event liegt da ein anderes Element den Link ausgelöst haben könnte     
        while (tar.nodeName != 'A') tar = tar.parentNode;
        
        /*
                      * prüfen ob der Container eben am laden ist
                      * oder eines seiner Kinder
                      * wenn ja Preload abbrechen vom alten Element und Preload ausführen nun
                      */
        with(activeBoxes[tar.getAttribute('container')]) {
            checkBoxLoading(activeBoxes[tar.getAttribute('container')]);
   
            //neues Bild laden ? -> wenn ja laden href="bildpfad"
            var imgpattern = /.*?\.(jpg|gif|png)$/gi;
            if(tar.href.match(imgpattern)) {        
                preloadContainer.addTo = Element.get(tar.getAttribute('container'));
                loadObject = loadBoxContent(tar.href,activeBoxes[tar.getAttribute('container')],true);
                loading = true;
            } else {
             /*
                                    * den Link auseinander nehmen nach init suchen und container muss ja 
                                    * existieren wenn er hier an kommt
                                    */            
                if(tar.getAttribute('init') == 'load') {
                    var conf = {
                        path:tar.href+"&ajax=true",
                        method:'GET',
                        params:null
                    }
                    preloadContainer.addTo = Element.get(tar.getAttribute('container'));

                    loading    = true;
                    loadObject = loadBoxContent(conf,activeBoxes[tar.getAttribute('container')]);
                } else {
                    loading    = false;
                    closeBox(Element.get(tar.getAttribute('container')));
                }
            }                    
        }
    }
    
    /**
           * Methode zum senden von Formularen bereitet die Configuration für das Ajax Object vor 
           * und sendet es dann weiter an loadBoxContent
           */
    function sendFormAjax (evt) {
        var evt = (evt)?evt:(window.event)?window.event:'';
        
        //event wurde durch die Entertaste ausgelöst
        if(evt.type == 'keydown' && evt.keyCode != 13) {
            return;
        }
        //event wurde durch einen mausclick ausgelöst
        else if (evt.type == 'click') { 
            if(evt.preventDefault) 
                evt.preventDefault(); 
            else 
                evt.returnValue = false;
        }
        
        var tar = evt.srcElement || evt.target;
                
        while (tar.nodeName.toLowerCase() != 'form') {
            tar = tar.parentNode;   
        }
                
        var ajaxConf = (function(formobj) {
            var conf = {
                path:formobj.action,
                method:formobj.method.toUpperCase(),
                params:{}                
            };
            
            var fields = new Array();            
            /*
                                  * alle Felder sammeln die zu einen Formular gehören 
                                  * input , select felder und textareas und zu einen zusammen fügen
                                  */
            fields.merge(Element.getElements(tar,'input'),
                         Element.getElements(tar,'select'),
                         Element.getElements(tar,'textarea'));
                             
            for(var i = 0 ; i < fields.length;i++) {
                with(fields[i]) {
                    if(nodeName.toLowerCase() == 'input' &&  
                       (type.toLowerCase() == 'radio' || type.toLowerCase() == 'checkbox')) {
                        if(!checked) continue
                    }                    
                    conf.params[name] = value;
                }
            }
            return conf;  
        })(tar);        
        
        with(activeBoxes[tar.getAttribute('container')]) {
            checkBoxLoading(activeBoxes[tar.getAttribute('container')]);
            
            preloadContainer.addTo = Element.get(tar.getAttribute('container'));
            loadObject = loadBoxContent(ajaxConf,activeBoxes[tar.getAttribute('container')],false);
            loading = true;
        }
    }  
    
    function loadBoxContent (config,boxObject,imageLoad) {       
        with(boxObject) {
            if(preloader) {
                if(imageLoad) {
                    var load = new Preloader.addPreload(new Load.imageFile(config),
                                                            preloadContainer,
                                                            fillBoxImage,preloadContainer.addTo);
                } else {
                    var load = new Preloader.addPreload(new Load.ajaxContent(config),
                                                            preloadContainer,
                                                            fillBoxContent,preloadContainer.addTo);
                }
            } else {
                if(imageLoad) {
                    var load = new Load.imageFile(config)
                        load.initLoad(null,fillBoxImage,preloadContainer.addTo);
                } else {
                    var load = new Load.ajaxContent(config);
                        load.initLoad(null,fillBoxContent,preloadContainer.addTo);
                }
            }
        }
        return load;
    }
    
    function checkBoxLoading (object) {
        if(object.loading) {
            if(preloader)
                object.loadObject.cancelPreload()
            else 
                object.loadObject.cancelRequest();                    
            
            object.loadObject = null;
        }
        
        //prüfen ob die Kinder eben laden 
        for(var i = 0 ; i < object.childBoxes.length;i++) {      
            if(activeBoxes[object.childBoxes[i]].loading) {
                if(preloader)
                    activeBoxes[object.childBoxes[i]].loadObject.cancelPreload();
                else 
                    activeBoxes[object.childBoxes[i]].loadObject.cancelRequest();   
                 
                activeBoxes[object.childBoxes[i]].loading = false;               
                activeBoxes[object.childBoxes[i]].loadObject = null;
            }
            
            //Object des Kindobjectes gleich löschen da es nicht mehr benötigt wird vorerst
            activeBoxes = (
                function (objectName) {
                    var buffer = new Object();
                    var childB = activeBoxes[objectName].childBoxes;
                        
                    for(key in activeBoxes) {
                        if(key != objectName && !childB.inArray(key)) 
                            buffer[key] = activeBoxes[key];
                    }
                    return buffer;
                }
            )(object.childBoxes[i]);
            
            // Kind Element rauslöschen sowie die Objecte der Kindelement nun löschen 
            // da sie nicht mehr benötigt werden und der Inhalt neu geladen wird
            for(key in activeBoxes) {
                if(activeBoxes[key].childBoxes.inArray(object.childBoxes[i])) {
                    activeBoxes[key].childBoxes = activeBoxes[key].childBoxes.deleteValue(object.childBoxes[i]);
                }
            }
        }
    }
    
    function closeBox () {
    }
    
    function fillBoxContent (rv,container) {
        
        activeBoxes[container.id].loading = false;
        activeBoxes[container.id].loadObject = null;
        
        parseImageFilesFromBox(rv,subImagesLoaded,activeBoxes[container.id]);
        
        function subImagesLoaded () {
            container.innerHTML = rv;
            parseBox(container);
        }
    }
    
    function fillBoxImage (imgSrc,container) {
        container.innerHTML = '';
        activeBoxes[container.id].loading = false;
        activeBoxes[container.id].loadObject = null;
    
        var image = new Image();
            image.src = imgSrc;
            
        Element.bind(image,container);
    }
    
    return {
        enablePreloader:function(conf) {
            preloader = true;
            preloaderConfig = conf;
        },
        addBoxObject:function (object) {
            parseBox(object);
        },
        getActiveBoxes:function () {
            return activeBoxes;
        }
    }
})();