/*
 * SocialEngineMods Javascript Library Lite v0.1
 * http://www.SocialEngineMods.Net
 *
 * Copyright SocialEngineMods.Net
 * This code is licensed GPL for use exclusively on SocialEngine sites
 *
 */


/* Extensions */


Function.prototype.bind = function(obj) {
  var method = this, temp = function() {
    return method.apply(obj, arguments)
  };
  return(temp);
}; 


/* SEMods */


SEMods = function () {};
SEMods.debug = true;


/* SEMods Utils */


SEMods.Utils = function () {};
SEMods.Utils = {
    htmlspecialchars : function (text) {
        return text ? text.toString().replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#039;').replace(/</g, '&lt;').replace(/>/g, '&gt;') : '';
    },

    toHtml : function (text) {
        return SEMods.Utils.htmlspecialchars(text).replace(/\n/g, '<br />');
    },
    
    debug : function (message) {
      if(SEMods.debug)
    	alert(message);
    }
};


/* SEMods Browser */


SEMods.Browser = function () {};
SEMods.Browser = {
    isIE : (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent) ),
    isFireFox : (/FireFox/i.test(navigator.userAgent)),
    isOpera : (/Opera/i.test(navigator.userAgent)),

    addEvent : function (obj, type, func) {
        if (obj.addEventListener) {
            obj.addEventListener(type, func, 0);
        } else if (obj.attachEvent) {
            obj.attachEvent("on" + type, func);
        }
    },
    
	register_onload : function (handler) {
	  if (window.onload) {
	    var original_handler=window.onload;
	    window.onload=function() { original_handler(); handler(); };
	  }
	  else {
	    window.onload=handler;
	  }
	},
	
	ge : function(element) {
      var elem = document.getElementById(element);
      if(elem)
        return elem;
	  return this.geByName(element);
	},
    
	geByName : function(element) {
		var elems = document.getElementsByName(element);
        if(elems.length == 1)
          return elems[0];
        return null;
	},
    
    getStyle : function(obj, property) {
        if (window.getComputedStyle) {
            return window.getComputedStyle(obj, null).getPropertyValue(property);
        }
        if (document.defaultView && document.defaultView.getComputedStyle) {
            var computedStyle = document.defaultView.getComputedStyle(obj, null);
            if (computedStyle) return computedStyle.getPropertyValue(property);
        }
        if (obj.currentStyle) {
            return obj.currentStyle[property];
        }
        return obj.style[property];
    },
    
    getStyleName : function(stylename) {
      return SEMods.Browser.isIE ? stylename : stylename.replace(/[A-Z]/g, function(a){return'-'+a.toLowerCase();} );
    },
    
    // em's not supported for now
    getPXMetrics : function(metric, defvalue) {
      var metricBase = parseFloat(metric);
      if(isNaN(metricBase)) return defvalue!=null ? defvalue : metricBase;
      return /px/i.test(metric) ? metricBase : /pt/i.test(metric) ? 1.3333*metricBase  : metricBase;
    }
    
};


/* SEMods TextAreaControl */


SEMods.TextAreaControl = function(object) {
    this.obj = object;
    this.obj.style['overflow'] = 'hidden';
    this.originalHeight = this.obj.offsetHeight;
    var updater = this.update.bind(this);
    SEMods.Browser.addEvent(object, "focus", this.onFocus.bind(this));
    SEMods.Browser.addEvent(object, "blur", this.onBlur.bind(this));
    this.update();
};

SEMods.TextAreaControl.prototype = {
    obj : null,
    updating : false,
    autoGrow : false,
    originalHeight : null,
    shadowElement : null,
    increment : 0,
    timer : null,
    lastLength : 0,
    fontFamily : SEMods.Browser.getStyleName('fontFamily'),
    fontSize : SEMods.Browser.getStyleName('fontSize'),
    paddingLeft : SEMods.Browser.getStyleName('paddingLeft'),
    paddingRight : SEMods.Browser.getStyleName('paddingRight'),
    lineHeight : SEMods.Browser.getStyleName('lineHeight'),
    
    setAutoGrow : function(autoGrow) {
        this.autoGrow = autoGrow;
        this.createShadowElement();
        this.update();
    },
    
    onUpdate : function() {
        if(this.autoGrow && this.lastLength != this.obj.value.length) {
            this.lastLength = this.obj.value.length;
            this.updateShadowElement();
            this.obj.style.height = Math.max(this.originalHeight, this.shadowElement.offsetHeight + this.increment) + 'px';
        }
    },
    
    beginUpdate : function() {
        if(this.updating)
            return false;
        this.updating = true;
        return true;
    },
    
    endUpdate : function() {
        this.updating = false;
    },
    
    update : function() {
        if(!this.beginUpdate())
            return;
        
        this.onUpdate();
        this.endUpdate();
    },
    
    createShadowElement : function() {
        if(this.shadowElement)
            return;
        
        this.shadowElement = document.createElement("DIV");
        this.shadowElement.style.position = "absolute";
        this.shadowElement.style.top = "-99999px";
        this.shadowElement.style.left = "-99999px";
        
        document.body.appendChild(this.shadowElement);
    },
    
    updateShadowElement : function () {
        if(this.shadowElement) {
            this.shadowElement.innerHTML = SEMods.Utils.toHtml(this.obj.value + '<br>');
            var fontSize = SEMods.Browser.getPXMetrics( SEMods.Browser.getStyle(this.obj, this.fontSize), 10);
            var lineHeight = SEMods.Browser.getStyle(this.obj, this.lineHeight);
            // Opera misses on line-height
            if(SEMods.Browser.isOpera) 
              lineHeight = SEMods.Browser.getPXMetrics( lineHeight, 0) + 3 + 'px';
              
            this.increment = fontSize + 10;
        
            this.shadowElement.style['width'] = this.obj.offsetWidth + 'px';
            this.shadowElement.style['lineHeight'] = lineHeight;
            this.shadowElement.style['fontSize'] = SEMods.Browser.getStyle(this.obj, this.fontSize);

            this.shadowElement.style['fontFamily'] = SEMods.Browser.getStyle(this.obj, this.fontFamily);
            this.shadowElement.style['paddingLeft'] = SEMods.Browser.getStyle(this.obj, this.paddingLeft);
            this.shadowElement.style['paddingRight'] = SEMods.Browser.getStyle(this.obj, this.paddingRight);
            
        } 
    },
    
    onFocus : function() {
      this.timer = setInterval(this.update.bind(this), 500);
    },
    
    onBlur : function() {
      if(this.timer) {
        clearInterval(this.timer);
        this.timer = null;
      }
    }
    
};


/* Global namespace helper functions */


function textarea_autogrow(elementid) {
    var el = SEMods.Browser.ge(elementid);
    if(!el) SEMods.Utils.debug("textarea_autogrow(): element not found");
    if(el && !el._controlled) {
        el._controlled = true;
        new SEMods.TextAreaControl(el).setAutoGrow(true);
    }
};
