/**
 *  Copyright 2006 - Programaria - Software per a Tothom       
 *  http://www.programaria.com    
 *   
 *  author: drh (dani@programaria.com)
 */

var mybox = new Object();

/******************************************************************************
 * Clase Point
 ******************************************************************************/

mybox.Point = function(x, y) {
    this.x = x;
    this.y = y;
}

mybox.Point.prototype = {
}

/******************************************************************************
 * Clase AjaxRequest
 ******************************************************************************/

mybox.AjaxRequest = function(httpMethod, url, params, onComplete) {
    this.httpMethod = httpMethod;
    this.url = url;
    this.params = params;
    this.onComplete = onComplete;
    this.req = null;
}
 
mybox.AjaxRequest.prototype = {   

    run : function() {
        var loader = this;
        this.req = this.getXMLHttpRequest();
        this.req.onreadystatechange = function() {
            loader.onReadyState.call(loader);
        };
        
        if (this.httpMethod == null)
            this.httpMethod = 'GET';
        
        if ('GET' == this.httpMethod) {
            var s = this.url;
            if (this.params != null)
                s += '?' + this.params;
            this.req.open("GET", s, true);
        } else {
            // POST No funciona !!!
            this.req.open("POST", this.url, true);
            this.req.setRequestHeader("Content-Type", "application/x-www-urlencoded");
        }
        this.req.send(this.params);            
    },

    onReadyState : function() {
        var req = this.req;
        if (req.readyState == 4) {
            if (req.status && req.status == 200) {
                if (this.onComplete && this.onComplete != null) {
                    this.onComplete.call(this);
                }
            } else {
                //alert('status: ' + req.status);
            }
        }        
    }
    ,
    getXMLHttpRequest : function() {
        if (window.XMLHttpRequest) {
            return new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            isIE = true;
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
}

/*******************************************************************************
 * Event
 ******************************************************************************/

mybox.getElement = function(id) {
    if (id)
        return document.getElementById(id);
}

mybox.addEvent = function(element, type, handler, eventCapture) {
    if (element.addEventhandler) {
        element.addEventhandler(type, handler, eventCapture); 
        return true;
    } else if (element.attachEvent) {
        var r = element.attachEvent('on' + type, handler);
        return r;
    } else {
        element['on' + type] = handler;
    }
}

mybox.cancelEvent = function(e) {
    if (window.event) {
        window.event.cancelBubble = true;
        window.event.returnValue = false;
    }
    if (e && e.stopPropagation) {
        e.stopPropagation();
    }
    if (e && e.preventDefault) {
        e.preventDefault();
    }
}

mybox.getTarget = function(e) {
    return e.target ? e.target : e.srcElement;    
}

mybox.getEvent = function(e) {
    return window.event ? window.event : e;
}

mybox.getLocation = function(el) {
    var p = new mybox.Point(0, 0);
    if (el.offsetParent) {
        do {
            p.x += el.offsetLeft;
            //p.y += el.offsetTop - el.scrollTop;
            p.y += el.offsetTop;
            el = el.offsetParent;            
        } while (el != null);        
    } else if (el.x) {
        if (el.x) 
            p.x += el.x;
        if (el.y)
            p.y += el.y;
    } else if (el.clientX) {
        p.x += el.clientX;
        p.y += el.clientY;
    }
    return p;
}

mybox.isIE = function() {
    return !window.opera && navigator.userAgent.indexOf('MSIE') != -1;
}

mybox.getMouseLocation = function(mouseEvent) {
   var e = mybox.getEvent(mouseEvent);
    var p = new mybox.Point(0, 0);
    
    if (e.pageX && e.pageY) {
        p.x = e.pageX;
        p.y = e.pageY;
    } else if (e.clientX && e.clientY) {
        p.x = e.clientX;
        p.y = e.clientY;
        if (mybox.isIE()) {            
            p.x += document.body.scrollLeft + document.documentElement.scrollLeft;
            p.y += document.body.scrollTop + document.documentElement.scrollTop;
        }
    }    
    return p;
}

mybox.geKeyCode = function(keyEvent) {
    return window.event ? keyEvent.keyCode : keyEvent.which;
}

mybox.cancelTimer = function(timerId) {
    clearTimeout(timerId);
}

mybox.disableSubmitOnEnter = function(el) {
    var ft = function(e) {
        var key = mybox.geKeyCode(e);
        if (key == 13) {
            mybox.cancelEvent(e);
            return false;
        } else
            return true;
    };
    mybox.addEvent(el, 'keypress', ft, true);
}

mybox.isOver = function(p, el) {
    var p0 = mybox.getLocation(el);
    var p1 = new mybox.Point(p0.x + el.offsetWidth, p0.y + el.offsetHeight);
    var b = p.x >= p0.x && p.y >= p0.y && p.x <= p1.x && p.y <= p1.y;
    return b;
}

/******************************************************************************
 * Iframes
 ******************************************************************************/

mybox.getIFrameDocument = function(iframe) {    
    var doc = iframe.contentDocument;
    if (doc == undefined || doc == null)
        doc = iframe.contentWindow.document;

    return doc;
}

/******************************************************************************
 * AjaxTypeAhead Class
 * 
 * scrollDiv: Parámetro opcional, si se especifica, el scroll del div se
 * tiene en cuenta par aposicionar el popup
 ******************************************************************************/

mybox.AjaxTypeAhead = function(tableClass, inputHidden, input, 
        div, forceSameWidth, url, paramName, scrollDiv, ieUseFrame, fixX, fixY) {

    if (input == null || inputHidden == null)
        return;
    
    if (ieUseFrame == null)
        ieUseFrame = true;
    
    this.fixX = fixX;
    this.fixY = fixY;
    this.inputHidden = inputHidden;
    this.input = input;
    this.url = url;
    this.paramName = paramName;
    this.div = div;
    this.forceSameWidth = forceSameWidth;

    this.timerId = null;
    this.keyTimerId = null;
    this.timeVisible = 5000;
    this.iframe = null;
    this.zIndex = 101;
    this.tableClass = tableClass;
    this.text = null;
    this.selected = -1;
    this.values = null;    
    this.request = null;
    this.keyEvent = null;
    this.mouseEvent = null;
    this.inputColor = this.input.style.color;
    this.scrollDiv = scrollDiv;

    mybox.disableSubmitOnEnter(this.input);

    var ctx = this;
    var keypressFt = function(e) {
        ctx.keyEvent = e;
        ctx.keypress.call(ctx);
    }
    mybox.addEvent(this.input, 'keydown', keypressFt, false);
}

mybox.AjaxTypeAhead.prototype = {

    startTimeout : function() {
        var el = this;
        var ft = function() {
            el.hide.call(el);
        };
        this.timerId = setTimeout(ft, this.timeVisible);
    },
    
    cancelTimeout : function() {
        if (this.timerId != null) {
            mybox.cancelTimer(this.timerId);
            this.timerId = null;
        }
    },

    mouseOver : function() {        
        var p = mybox.getMouseLocation(this.mouseEvent);  
        p.y = p.y + this.div.scrollTop; // rech
        
        var table = this.div.firstChild;
        var tbody = table.firstChild;        
        if (tbody) {            
            var trs = tbody.getElementsByTagName('tr');
            if (trs) {
                for (var i = 0; i < trs.length; i++) {
                    if (mybox.isOver(p, trs[i])) {
                        this.select(i);
                        return true;
                    }
                }
            }
        }    
        return true;
    },
    
    keypress : function() {
        if (this.timerId != null)
            this.cancelTimeout();

        var key = mybox.geKeyCode(this.keyEvent);

        if (key != 13 && key != 9) {           
            this.startTimeout();
        }

        if (key == 13 || key == 9) {  // enter, tab
            if (key == 13) {
                this.saveSelected();
            } else {
                this.hide();
            }
            return true;
        } else if (key == 27) { // escape
            this.hide();
        } else if (key == 38) {   // up
            this.move(-1);
            return false;
        } else if (key == 40) {   // down
            this.move(1);
            return false;
        } else {
            if (this.keyTimerId != null) {
                mybox.cancelTimer(this.keyTimerId);
            }
            this.input.style.color = '#a0a0a0';
            this.inputHidden.value = '';                
            var ctx = this;
            var ft = function() {
                ctx.update.call(ctx);
            };
            this.keyTimerId = setTimeout(ft, 500);
        }        
    },

    saveSelected : function() {
        if (this.selected == null || this.selected == -1) {
            this.inputHidden.value = '';
        } else {
            if (this.values != null && this.values[this.selected]) {
                this.input.value = this.values[this.selected][0];
                this.input.style.color = this.inputColor;
                this.inputHidden.value = this.values[this.selected][1]; 
            }
        }
        this.hide();
    },

    update : function() {        
        if (this.text != null && this.text == this.input.value) {
            this.show();
            return false;
        }
            
        this.text = this.input.value;
        if (this.text == '')
            return;

        var ctx = this;
        var fillFt = function() {            
            ctx.fill.call(ctx);
        }
        this.request = new mybox.AjaxRequest('GET', this.url, 
                this.paramName + '=' + escape(this.text), fillFt);
        this.request.run();        
    },    

    move : function(delta) {
        if (this.selected != -1) {
            this.select(this.selected + delta);
            this.moveCaretToEnd();
        }
    },

    moveCaretToEnd : function() {
        var pos = this.input.value.length;        
        if (this.input.setSelectionRange) {
            var ctx = this;
            var ft = function() {
                ctx.input.setSelectionRange(pos, pos);
            }
            setTimeout(ft, 1);
            //this.input.setSelectionRange(0, pos);
        } else if (this.input.createTextRange) {
            var m = this.input.createTextRange();
            m.moveStart('character', pos),
            m.collapse();
            m.select();
        }         
    },

    select : function(index) {
        var table = this.div.firstChild;
        var tbody = table.firstChild;        
        if (tbody) {            
            var trs = tbody.getElementsByTagName('tr');
            if (trs) {
                if (this.selected != -1 && this.selected < trs.length)
                    trs[this.selected].className = '';

                index = Math.max(0, Math.min(index, trs.length - 1));
                var tr = trs[index];
                tr.className = 'selected';
                this.selected = index;
            }
        }
    },

    validate : function() {
        var width = this.input.offsetWidth;

        var p = mybox.getLocation(this.input);
        if (this.scrollDiv != undefined) {
            p.y = p.y - this.scrollDiv.scrollTop;
        }
        if (this.iframe != null && this.ieUseFrame) {
            if (this.fixX != null) {
                this.iframe.style.top = this.fixY + 'px';
                this.iframe.style.left = this.fixX + 'px';
            } else {
                this.iframe.style.top = (p.y + this.input.offsetHeight) + 'px';
                this.iframe.style.left = p.x + 'px';                
            }
            this.iframe.style.display = 'none';
            if (this.forceSameWidth == true || width > this.div.offsetWidth)
                this.iframe.style.width = width;        
        } 
        if (this.fixX != null) {
            this.div.style.left = this.fixX + 'px';            
        } else {
            this.div.style.left = p.x + 'px';
        }
        if (this.fixY != null) {
            this.div.style.top = this.fixY + 'px';            
        } else {
            this.div.style.top = (p.y + this.input.offsetHeight) + 'px';
        }
        if (this.forceSameWidth == true || width > this.div.offsetWidth)
            this.div.style.width = width;
    },

    fixIE: function() {
        if (!this.ieUseFrame)
            return;
            
        if (document.all) {
            if (this.iframe == null) {
                this.iframe = document.createElement("<iframe id='" 
                        + this.div.id + "_IFRAME' name='" + this.div.id 
                        + "_IFRAME' style='visibility:hidden; display: none; position: absolute; top:0px;left:0px;'/>");
                                       
                document.body.insertBefore(this.iframe);
            }
            
            var popup = this.div;
            if (popup.style.display == 'block') {
                popup.style.zIndex = this.zIndex;
                this.iframe.style.zIndex = popup.style.zIndex - 1;                
                this.iframe.style.width = popup.offsetWidth;
                this.iframe.style.height = popup.offsetHeight;
                this.iframe.style.top = popup.style.top;
                this.iframe.style.left = popup.style.left;

                this.iframe.style.marginTop = popup.style.marginTop;
                this.iframe.style.marginLeft = popup.style.marginLeft;
                this.iframe.style.marginRight = popup.style.marginRight;
                this.iframe.style.marginBottom = popup.style.marginBottom;
                this.iframe.style.background = 'yellow';
                this.iframe.style.display = "block";
                this.iframe.style.visibility = "visible";                 
            } else {
                this.iframe.style.display = 'none';
            }
        }
        return false;
    },

    show : function() {
        if (this.timerId == null)
            return;

        this.validate();
        this.div.style.display = 'block';   
        this.fixIE();
        var ctx = this;

        var startFt = function() {
            ctx.startTimeout.call(ctx);
        };

        var mouseOverFt = function(e) {
            ctx.mouseEvent = e;
            ctx.cancelTimeout.call(ctx);
            ctx.mouseOver.call(ctx);
        }

        var clickFt = function(e) {
            ctx.mouseEvent = e;
            ctx.saveSelected.call(ctx);
        }

        mybox.addEvent(this.div, 'mouseover', mouseOverFt, false);
        mybox.addEvent(this.div, 'mouseout', startFt, false);
        mybox.addEvent(this.div, 'click', clickFt, false);
    },

    hide : function() {
        this.div.style.display = 'none';
        this.fixIE();
    },

    fill : function() {
        try {
            if (this.request == null)
                return false;

            var responseXML = this.request.req.responseXML;
            
            if (!responseXML)
                return false;

            var root = responseXML.getElementsByTagName('options')[0];            
            var options = root.getElementsByTagName('option');
            if (!options || options.length == 0) {
                this.div.innerHTML = '';
                return true;
            }

            this.values = new Array(options.length);
            var s = "<table class='" + this.tableClass + "'><tbody>";

            for (var i = 0; i < options.length; i++) {
                var textNode = options[i].childNodes[0];
                var valueNode = options[i].childNodes[1];
                var labelNode = options[i].childNodes[2];

                var opt = new Array(3);
                opt[0] = textNode.firstChild.nodeValue;
                opt[1] = valueNode.firstChild.nodeValue; 
                opt[2] = labelNode.firstChild.nodeValue;
                this.values[i] = opt;

                s += "<tr><td>";
                //s += this.formatText(textNode.firstChild.nodeValue);
                s += this.formatText(opt[2]);
                s += "</td></tr>";
            }
            s += "</tbody></table>";
            this.div.innerHTML = s;
            this.show();
            this.select(0);  
        } catch (e) {
            alert(e);
        }
    },

    formatText : function(s) {
        var regex = new RegExp('(' + this.text + ')', 'gi');
        s = s.replace(regex, "<span class='match'>$1</span>");        
        //if (this.text
        return s;
    }

}

mybox.fadeEffect = function(element, className, time, nivell) {
    this.element = element;
    this.className = className;
    this.time = time;
    this.nivell = nivell;
    this.limit = 0;
    this.inc = 1;  
    this.index = 0;
}

mybox.fadeEffect.prototype = {

    fadeIn: function() {
        this.index = this.nivell;
        this.limit = 0;
        this.inc = -1;
        this.fade0();
    },

    fadeOut: function() {
        this.index = 0;
        this.limit = this.nivell;
        this.inc = 1;
        this.fade0();
    },

    fade0 : function() {
        var ctx = this;
        this.element.className = this.className + this.index;        
        if (this.index != this.limit) {
            this.index = this.index + this.inc;
            var ft = function() {
                ctx.fade0.call(ctx);
            };            
            setTimeout(ft, this.time); 
        }
    }
}

/*******************************************************************************
 * 
 *******************************************************************************/
mybox.doClick = function(e, buttonName) {
    try {
        var keycode;
        var target; 
        if (window.event) {
            keycode = window.event.keyCode;
            target = window.event.srcElement;
        } else if (e) {
            keycode = e.which;
            target = e.target;
        } else 
            return true; 
        if (keycode == 13) {
            mybox.cancelEvent(e);
            var el = mybox.getElement(buttonName);
            if (el == undefined) {
                el = mybox.findJSFComponent(buttonName, target);
            }
            if (el != undefined) {
                if (el.click != undefined)
                    el.click();
                else
                    el.onclick();
            } else {
                alert('element not found ' + buttonName)
            }
            return false;
        } else
            return true;
   } catch (err) {
        alert(err);
   }
}

mybox.getWindowInnerWidth = function() {
    if (window.innerWidth) {
        return window.innerWidth;
    } else {
        return document.documentElement.offsetWidth;
    }
}

mybox.getWindowInnerHeight = function() {
    if (window.innerHeight) {
        return window.innerHeight;
    } else {
        return document.documentElement.offsetHeight;
    }
}

mybox.centerInWindow = function(el, elementWidth, elementHeight) {
    var width = mybox.getWindowInnerWidth();
    //var height = mybox.getWindowInnerHeight(); 
    var height = mybox.getWindowHeight(); 
    var s;
    if (elementWidth == undefined) {
        elementWidth = el.clientWidth;
        if (elementWidth == undefined) {
            s = el.style.width;
            s = s.substring(0, s.length - 2);
            elementWidth = parseInt(s);
        }
    }
    var left = width / 2 - elementWidth / 2;
    
    if (elementHeight == undefined) {
        elementHeight = el.clientHeight;
        if (elementHeight == undefined) {
            s = el.style.height;
            s = s.substring(0, s.length - 2);
            elementHeight = parseInt(s);
        }
    }
    var top = height / 2 - elementHeight / 2;
    
    top += mybox.getScrollXY()[1];
    el.style.top = top + 'px';
    el.style.left = left + 'px';
}
mybox.getScrollXY = function() {  
    var scrOfX = 0, scrOfY = 0;
    if( typeof( window.pageYOffset ) == 'number' ) {
        //Netscape compliant
        scrOfY = window.pageYOffset;
        scrOfX = window.pageXOffset;
    } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        //DOM compliant
        scrOfY = document.body.scrollTop;
        scrOfX = document.body.scrollLeft;
    } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
        //IE6 standards compliant mode
        scrOfY = document.documentElement.scrollTop;
        scrOfX = document.documentElement.scrollLeft;
    }
    return [ scrOfX, scrOfY ];
}

mybox.getWindowHeight = function() {
  var windowHeight=0;
  if (typeof(window.innerHeight)=='number') {
    windowHeight=window.innerHeight;
  }
  else {
    if (document.documentElement&&
      document.documentElement.clientHeight) {
        windowHeight=
          document.documentElement.clientHeight;
    }
    else {
      if (document.body&&document.body.clientHeight) {
        windowHeight=document.body.clientHeight;
      }
    }
  }
  return windowHeight;
}

mybox.stopPropagation = function(e) {
    if (window.event && window.event.cancelBubble == false) {
        window.event.cancelBubble = true;
    }
    if (e && e.stopPropagation) {
        e.stopPropagation();
    }
}

