
   /* Class GUI, this is mainly a container which is based on */
   /* the following components: MessageLog, DebugDump,        */
   

   var GUI = Class.create();
   
   GUI.prototype = {
   
      initialize: function(messagelog, dump) {
         this.messagelog       = messagelog;
         this.dump             = dump;
         this.pagetitle_id     = "pagetitle";
         this.pageheadline_id  = "pageheadline";
         
         try {
            this.workingindicator = new WorkingIndicator('workingindicator');
         } catch(e) {
            alert("GUI: "+e);
         }
      },

      
      // handle Ajax Response, write to messagelog, popup error messages, etc.
      handleResponse: function(response) {
         
         // create Messagelog entries (display and logfile)
         if (response['message']) {
            if (response['error']) {
               this.messagelog.write(response['message'], response['error']);
            } else {
               this.messagelog.write(response['message']);
            }
         }
         
         // write debug response to debug dump area
         if (response['debug']) {
            this.dump.add(response['debug']);
         }
         
         // Display Error Message 
         // todo: use Mini-Window 
         if (response['error']) {
            if (response['message']) {
               alert(response['error']+"\r\r"+response['message']);
            } else {
               alert(response['error']);
            }
         }
         
      },
   
      // display form feedback, error messages, etc.
      handleFormMessages: function(response) {
         
         // clear all fields in form with class="form_error"
         $$('.form_error').each(function(el) {
            el.update('');
         });
         
         var tmpvar=0;
         
         // check if form fields need feedback, write to form field
         if (response['formErrors']) {
            $H(response['formErrors']).each(function(formerror) {
                  if(tmpvar==0) {
                     first_error = formerror[0];
                  }
                  dump.add(formerror[0]);
               try {
                  $(formerror[0]).update(formerror[1]);
               } catch(e) { }
               tmpvar++;
            });
            return first_error;
         }
         
      },
      
      
      // set a new page title, overwrites inner html
      setPageTitle: function(sTitle) {
         try {
            $(this.pagetitle_id).update(sTitle);
         } catch(e) { }
      },
      
      // set a new page headline, overwrites inner html
      setPageHeadline: function(sHeadline) {
         try {
            $(this.pageheadline_id).update(sHeadline);
         } catch(e) { }
      },


      
      disableArea: function(area) {
         
         var greyout = document.createElement('div');
         Element.extend(greyout);
         greyout.writeAttribute("id", area+"_modalframe");
         greyout.setStyle({
                              backgroundColor: '#eeeeee',
                              position: 'absolute',
                              top: '0px',
                              left: '0px',
                              width: '100%',
                              height: '100%',
                              opacity: '0.66',
                              overflow: 'hidden'
         });
         
         $(area).appendChild(greyout);         
      },
      
      enableArea: function(area) {
         if ($(area+"_modalframe")) {
            document.body.removeChild(document.getElementById(area+"_modalframe"));
         }
      },
      
      
      
      
      // centers a given dom object on screen, regarding page_wrapper     
      centerOnScreen: function(container_id) {
         
         var eltDims     = $(container_id).getDimensions();
         var wrapperDims = $('page_wrapper').getDimensions();

         var browserDims = document.viewport.getDimensions();
         
         var x = $('page_wrapper').getWidth() / 2 - eltDims.width / 2;
         var y  = (browserDims.height - eltDims.height) / 2;
 
         $(container_id).setStyle({position : 'absolute', top: y + 'px', left : x + 'px'});
         
         // alert('centeronscreen ready');
         // $(container_id).scrollTo();
         
         Effect.ScrollTo(container_id, { duration:1, offset:-60 });
                                       
      },
                           
                           
 


      // helper function: create div containers around given content
      
      _roundBox: function(content) {
         var wrapper = new Element('div', { className: 'roundBox' });
         var contentContainer = wrapper.appendChild(new Element('div'));
         contentContainer.insert(new Element('div', { className: 'top' }).update('<!-- round -->'));
         contentContainer.insert(new Element('div', { className: 'middle' }).update(content));
         contentContainer.insert(new Element('div', { className: 'bottom' }).update('<!-- round -->'));
         return wrapper;
      },
  

      
      // turns single title attribute into Prototip powered tooltip
      titleToTooltip: function(element) {
         /*
         if ( Prototype.Browser.IE6 ) {
            new Tip(element, this._roundBox(element.title), {
                        className: 'prototipSimpleTip',
                        effect: 'appear',
                        offset: {x:8, y:12},
                        fixed: true
            });
            element.removeAttribute('title');
         } else {
            */
            new Tip(element, element.title, {
               className: 'prototipSimpleTip',
               borderColor: '#FFEFBC',
               effect: 'appear',
               offset: {x:8, y:12} 
            });
            element.removeAttribute('title');   
         /* } */
         
      },
      
      
      
      // turns title attributes to Prototip powered tooltips
      // needs element_id (outer container) 
      // looks for elements matching classname within and adds tooltip
      
      titlesToTooltips: function(element_id, params) {
        
         var cssSelector = '#'+element_id;
         var className   = 'tooltip'; 
         
         if (params && params['class']) { 
            cssSelector += ' .'+params['class']; 
         } else {
            cssSelector += ' .'+className;
         }
        
         // add Prototip Tooltip to each matching element
         $$(cssSelector).each(function(element) {
              
            this.titleToTooltip(element);
            /*
            new Tip(element, this._roundBox(element.title), {
                  className: 'prototipSimpleTip',
                  effect: 'appear',
                  offset: {x:8, y:12} 
            });
            element.removeAttribute('title');
            */
         }.bind(this));
      },
      
      
      // adds Prototip Tooltips to form label elements matching class="tooltip"
      // tooltip content is derived from separate element named "helptext_"+form_element_name
      // with fallback to original title attribute of label.
      // Additionally a help icon [?] img tag with class="tooltip" and the same "for" attribute
      // will also be assigned the tooltip.
      
      formLabelsToTooltips: function(element_id) {
         
         $$('#content #'+element_id+' .tooltip').each(function(elem) {       
            
               
            var for_value = null;
            for_value = elem.readAttribute('for');
            // let IE use getAttribute 
            if (!for_value) {
               for_value = elem.getAttribute('for');
            }
               
            if (for_value && elem.tagName.toLowerCase()!="img") {
               
               var tooltipContent="<em>Eingabefeld für "+for_value+".</em>";
               
               try {
                  var tooltipContent = $('helptext_'+for_value).innerHTML;
               } catch(e) {
                  
                  if (elem.readAttribute('title')) {
                     var tooltipContent = elem.readAttribute('title');
                  } else {
                     alert("Error: Class tooltip given, but no tooltip content found for: " + for_value);
                  }
                  
               } finally {
                  
                  // if ( Prototype.Browser.IE6 || Prototype.Browser.IE7 ) ...
                     
                  new Tip(elem, tooltipContent, {
                     className: 'prototipSimpleTip',
                     borderColor: '#FFEFBC',
                     effect: 'appear',
                     offset: {x:8, y:12}
                  });
                  
                  // look for minihelp icon that has the same "for" value, assign the same tooltip                  
                  try {

                     var icon_minihelp = $$('#content #'+element_id+' img.tooltip[for='+for_value+']')[0];
                     
                     if (icon_minihelp) {
                        new Tip(icon_minihelp, tooltipContent, {
                              className: 'prototipSimpleTip',
                              borderColor: '#FFEFBC',
                              effect: 'appear',
                              offset: {x:8, y:12}
                        });
                     }
                     
                  } catch(e) {}
                  
                  elem.removeAttribute('title');
                  
               }
                            
            }
            
         }.bind(this));
         
      },
      
      
      // get info about user, render bubble info via ProtoTip
      // user_id needs to be given inside title attribute
      
      userBubbleTooltips: function(element_id) {
         
         // search for all elements with class 'userbubble' within given element_id
         $$('#'+element_id+' .userbubble').each(function(element){
               
            new Tip(element, {
                  ajax: {
                     url: 'ajax/user-infobubble.php',
                     options: {
                        parameters: {
                           user_id: element.title,
                           session_user: user.getId()
                        }
                     }
                  },
                  className: 'userbubble-small',
                  borderColor: '#E9F4F2',
                  border: 3,
                  radius: 3,
                  effect: 'blind',
                  offset: {x:8, y:12},
                  fixed: true
            });
            element.removeAttribute('title');
         }.bind(this));
         
      }
      
      
   }



   /* create a button GUI element thats binded to a given function(name) */
   var FunctionButton = Class.create();
   
   FunctionButton.prototype = {
   
      initialize: function(label, func, id) {
         this.label = label;
         this.func = func;
         if (id) {
            this.id = id;
         }
      },

      /* return HTML snippet that displays the button */
      renderHTML: function() {
         
         var htmlsnippet = "";
         htmlsnippet += '<input ';
         
         if (this.id) {
            htmlsnippet += 'id="'+this.id+'" ';
         }
         
         htmlsnippet += 'type="button" value="'+this.label+'" onclick="'+this.func+'" />';
         
         return htmlsnippet;
      }
      
   }
   
   
   
   /* invisible div on top of all other, playing "progress" animation */
   var WorkingIndicator = Class.create();
   
   WorkingIndicator.prototype = {
   
      initialize: function(id) {
         this.id = id;
      },
      
      switchOn: function() {
         $(this.id).addClassName('working');
      },
      
      switchOff: function() {
         $(this.id).update("");
         $(this.id).removeClassName('working');         
      },
      
      setPosition: function(x,y) {
         $(this.id).setStyle(
                  {
                     left: x+'px',
                     top: y+'px'
                  }
                  );
      },
      
      message: function(msg) {
         $(this.id).update("<p>"+msg+"</p>");
      }
      
   }
   
   
   
   /* BrowserWindow - real Browser popup windows */
   
   var BrowserWindow = Class.create();
   
   BrowserWindow.prototype = {
      
      initialize: function(window_id, url, parameter) {
         this.window_id = window_id;
         this.url = url;
         
         // default parameter values
         this.initialWidth = 400;
         this.initialHeight = 300;
         
         // optional parameter, overriding defaults
         if (parameter) { $H(parameter).each(function(p) {
               
            switch(p.key) {
               
               case 'mode'       : this.mode = p.value;  break;
               case 'width'      : this.initialWidth = p.value;  break;
               case 'height'     : this.initialHeight = p.value;  break;
               case 'x'          : this.xPos = p.value;  break;
               case 'y'          : this.yPos = p.value;  break;
               
            }

         }.bind(this)); }
        
         
         // prepare options for javascript window.open method
         var options = {
               width:  this.initialWidth,
               height: this.initialHeight
         };
         
         // make options a comma seperated list of key,value pairs
         this.options = $H(options).toQueryString().gsub('&',',');
      },
      
      
      
      // open a new browser window
      popUp: function() {
         this.popupwindow = window.open(this.url, this.window_id, this.options);
         this.popupwindow.focus();
      },
      
      
      // disables the caller window (grey out)
      makeModal: function() {
         
      }
      
   }
   
   

   
   /* MiniWindow */
   
   var MiniWindow = Class.create();

   MiniWindow.prototype = {
   
      initialize: function(container_id, title, parameter) {
      
         // internal attributes 
         this.container_id = container_id;
         this.content_id  = container_id+"Content";
         this.title = title;
         this.titlebarClassname = "titlebar";
         
         
         // default values for attributes
         this.initialWidth    = 200;
         this.initialHeight   = 200;
         this.parentObj       = 'page_wrapper';         
         this.mode            = 'normal';
         this.zIndex          = 3000;
         
         
         // optional parameter, overriding defaults
         if (parameter) { $H(parameter).each(function(p) {
               
            switch(p.key) {
               
               case 'mode'       : this.mode = p.value;  break;
               case 'width'      : this.initialWidth = p.value;  break;
               case 'height'     : this.initialHeight = p.value;  break;
               case 'parentObj'  : this.parentObj = p.value;  break;
               case 'zIndex'     : this.zIndex = p.value;  break;
               
            }

         }.bind(this)); }
         
         if(this.mode == 'teaserbox') {
            this.initialWidth    = 600;
            this.initialHeight   = 400;
         }
         
         // prepare the HTML code for a (still hidden) popup
         this.renderPopup();
         
         
         // customize for different modes (alert, question, etc.)
         switch(this.mode) {
            case "alert" : 
               this.addCloseButton(container_id);
               this.makeModal();
               this.center();
               break;
            case "teaserbox" :
               this.addCloseButton(container_id, "teaserbox");
               
               this.makeModal();
               this.center();
               
               this.addShadow('gfx/shadow600x400.png');
               break;
         }
         
      },
      
      
      getContentId: function() {
         return this.content_id;
      },
      
      addShadow: function(shadowImage) {
         var shadow = new Element("img", {
                           id: this.container_id+'_shadow',
                           src: shadowImage
         });
         
         shadow.setStyle({
            position: 'absolute',
            zIndex: 2
         });
         
         switch(this.mode) {
            case "teaserbox":
                  shadow.setStyle({
                              top: $(this.container_id).getStyle('top').slice(0,-2)-22+'px',
                              left: $(this.container_id).getStyle('left').slice(0,-2)-45+'px',
                              width: '690px',
                              height: '490px'
                  });
                  break;
         }
         
         document.body.appendChild(shadow);
         
         this.hasShadow = true;
         
      },
      
      renderPopup: function() {
         
         var container = new Element("div", { 
                           id: this.container_id,
                           'class': "nodechooserPopup"
         });
         
         switch(this.mode) {
            case "alert":
                  container.setStyle({
                              backgroundColor: '#fffdfa',
                              border: 'solid 1px #dc0000',
                              top: '200px',
                              left: '260px',
                              position: 'absolute',
                              zIndex: this.zIndex+1,
                              overflow: 'hidden',
                              display: 'none'
                  });
                  break;
            case "teaserbox" :
                  container.setStyle({
                              backgroundColor: 'white',
                              border: 'solid 1px #702080',
                              top: '200px',
                              left: '260px',
                              position: 'absolute',
                              zIndex: this.zIndex+1,
                              overflow: 'hidden',
                              display: 'none'
                  });
                  break;
         }


         var titlebar = new Element("div", {
                           'class': this.titlebarClassname
         });

         switch(this.mode) {
            case "alert":
                  titlebar.setStyle({
                              height: '16px',
                              paddingLeft: '4px',
                              backgroundColor: '#dc0000',
                              color: 'white',
                              fontWeight: 'bold'
                  });
                  break;
            case "teaserbox" :
                  titlebar.setStyle({
                              height: '17px',
                              width: this.initialWidth-4+'px',
                              paddingTop: '3px',
                              paddingLeft: '4px',
                              backgroundColor: '#702080',
                              color: 'white',
                              fontWeight: 'bold'
                  });
                  break;
         }
         
         titlebar.update(this.title);
           
         
         var content = new Element("div", { 
                           id: this.content_id
         });
         
         switch(this.mode) {
            case "alert":
                  content.setStyle({
                              padding: '8px',
                              width: this.initialWidth+'px',
                              height: this.initialHeight+'px',
                              overflow: 'auto'
                  });
                  break;
            case "teaserbox" :
                  content.setStyle({
                              padding: '0px',
                              width: this.initialWidth+'px',
                              height: this.initialHeight+'px',
                              position: 'relative',
                              overflow: 'hidden'
                  });
                  break;
         }
         

         container.appendChild(titlebar);
         container.appendChild(content);
         
         document.body.appendChild(container);
      },
      
      
      
    
      
      // adds a Close-button to the window div, that clears the content and closes the window
      // it calls a "close()" method of the given object instance, so its function can be 
      // overruled.
      addCloseButton: function(objname, type) {
         
         if (!objname) { 
            objname=this.container_id; 
         } 
         
         if (!type) { 
            type = "normal";
         } 
         
         var label = "close";
         
         
         closeButton = new Element('div', {
               id: this.container_id + "closeButton" 
         });
         
         Event.observe(closeButton, 'click', this.close.bindAsEventListener(this));
         
         switch(this.mode) {
            case "normal":
                  closeButton.setStyle({
                              backgroundColor: '#a00000',
                              border: 'solid 1px #ffffff',
                              position: 'absolute',
                              overflow: 'hidden',
                              zIndex: this.zIndex+2,
                              left: this.initialWidth-2+'px',
                              top: '3px',
                              width: '8px',
                              height: '8px'
                  });
                  break;
                  
            case "teaserbox" :
                  closeButton.setStyle({
                              zIndex: this.zIndex+2,
                              left: this.initialWidth-18+'px'
                  });
                  closeButton.addClassName('closetourbutton');
                  break;
         }
         
         $(this.container_id).insert(closeButton);
         
      },
      
      
      // adds a Close-button to the content div, that clears the content and closes the window
      addCloseButtonContent: function(objname, label, type) {
         
         if (!objname) { 
            objname=this.container_id; 
         }
         
         if (!label) { 
            label= "close"; 
         }
         
    
         
         var closeButton = new Element("input", {
               id: this.container_id + "closeButtonContent",
               type: "button",
               value: label
         });
         
         /*
         var script = objname+".close();";
         closeButton.observe('click', function(event){
           eval(script);
         });
         */

         Event.observe(closeButton, 'click', this.close.bindAsEventListener(this));

         if (type=="teaserbox") { 
            closeButton.writeAttribute("style", "padding:2px; background-color: #f4f6f8; border: solid 1px #702080; color: #702080; margin-left: -26px;"); 
         }
         
         // default behaviour (centered at bottom)
         var buttonWidth = 50;
         
         closeButton.setStyle({
                              position: 'absolute',
                              left: this.initialWidth/2-buttonWidth/2+'px',
                              bottom: '13px'
         });
                  
         $(this.content_id).appendChild(closeButton);
         
      },
      
      
      // append CloseButton after content
      appendCloseButtonContent: function(objname) {
         
         if (!objname) { objname=this.container_id; }
         
         var label = "close";
         var script = objname+".close();";
         
         var closeButton = document.createElement('input');
         Element.extend(closeButton);
         closeButton.writeAttribute("id", this.container_id + "closeButtonContent");
         closeButton.writeAttribute("type", "button");
         closeButton.writeAttribute("value", label);
         closeButton.writeAttribute("onclick", script);
                    
         var buttonWidth = 50;
            
         closeButton.setStyle({
                              position: 'relative',
                              left: this.initialWidth/2-buttonWidth/2+'px',
                              marginTop: '13px',
                              marginBottom: '13px'
         });
            
         $(this.content_id).appendChild(closeButton);
         
      },
      
      
      
      
      // toggles visibility of window ON
      show: function() {
         $(this.container_id).show();
      },
      
      // toggles visibility of window OFF
      hide: function() {
         $(this.container_id).hide();
      },
      
      // unhide window, make it dragabble
      popUp: function() {
         switch(this.mode) {
            case "alert" : 
               this.makeModal();
               break;
         }
         this.show();
         if(this.mode != 'teaserbox') {
            new Draggable(this.container_id, {handle: this.titlebarClassname});
         }
      },
      
      
      // closes the window, clears content first
      close: function() {
         
         if (this.modal) {
            $(this.container_id+"modalframe").remove();
         }
         
         if (this.hasShadow) {
            $(this.container_id+"_shadow").remove();
         }
         // this.clearContent(); 
         this.hide();
      },
      
      
      makeModal: function() {
         this.modal = true;
         var greyout = document.createElement('div');
         Element.extend(greyout);
         greyout.writeAttribute("id",this.container_id+"modalframe");
         greyout.setStyle({
                              backgroundColor: '#333333',
                              position: 'absolute',
                              top: '0px',
                              left: '0px',
                              width: '100%',
                              height: $(this.parentObj).getHeight()+'px',
                              opacity: '0.5',
                              zIndex: this.zIndex,
                              overflow: 'hidden'
         });
         
         document.body.appendChild(greyout);
         
      },
      
   
      // sets new x,y (left and top) css attributes
      setPosition: function(newleft, newtop) {

         var w = $(this.container_id);
         w.setStyle({
               left: newleft+'px',
               top: newtop+'px'
         });
         
      },
      
      // center window on screen (or inside parentObj if available)
      center: function() {
         
         var w = $(this.container_id);
         var width = w.getWidth();
         var height= w.getHeight();
         
         if (this.parentObj) {
            var page = $(this.parentObj);
            var pageWidth = page.getWidth();
            var pageHeight = page.getHeight();
            pageHeight = document.viewport.getHeight();
            var pagePos = Position.page(page);
            var pageLeft = pagePos[0];
         } else {
            var pageLeft = 0;
            var pageWidth = window.innerWidth;
            var pageHeight = window.innerHeight*0.9;
         }
         
         var newleft = pageWidth/2+pageLeft-width/2;
         var newtop = (pageHeight/2-height/2)*0.9;
         
         this.setPosition(newleft, newtop);
         
      },
      
      
      // replace content with new one
      setContent: function(newHTML) {
         $(this.content_id).update(newHTML);
      },

      
      // add content below existing one
      addContent: function(newHTML) {
         $(this.content_id).update($(this.content_id).innerHTML + newHTML);
      },

      
      // clears the content
      clearContent: function() {
         $(this.content_id).update("");
      },
      
      
      // replace content with template
      setContentFromTemplate: function(template) {
         
         var url = 'ajax/helpers-fetchtemplate.php';
         var pars = {
            template: template
         };
         
         new Ajax.Request(url, {
                  method: 'post',
                  parameters: $H(pars).toQueryString(),
                  onComplete: function(transport) {
                        var response = transport.responseJSON;
                        
                        if (response && response.html) { 
                           gui.handleResponse(response);
                           $(this.content_id).update(response.html);
                        } else {
                           $(this.content_id).update("Invalid response from ajax: "+url);                           
                        }
                        //this.addCloseButtonContent(this.container_id, "Fenster schliessen", "teaserbox");
                  }.bind(this)
         });
         
      }
   }
   


