/*global UNIFACE document */

/*******************************************************************************
date   refnum   version who description
090205 c27248   9.ajax  jdk acceskeys do not work & labels etc show the %sign
090305 c27328   9.ajax  fd  Move common code up in widget class inheritance tree
date   refnum   version who description
*******************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// UNIFACE.widget
// Namespace as well as interface definition.
///////////////////////////////////////////////////////////////////////////////
(function() {

UNIFACE.widget = function(fieldID) {
};
UNIFACE.widget.prototype = 
{ 
    render : function(a_placeHolder) {},
    setValue : function(aVal) {},
    getValue : function() {    return ""; },
    setValrep : function(aValrep, aProps) {},
    setResource : function(aRes) {},
    unrender : function() {},
    setSyntax : function(aSyntax) {},
    setProperties: function() {},
    mapEvents : function() {},
    getDomNode : function() {    return null;}
};


///////////////////////////////////////////////////////////////////////////////
// UNIFACE.widget.AbstractWidget
// Base class widget implementation.
///////////////////////////////////////////////////////////////////////////////


UNIFACE.widget.AbstractWidget = function(fieldID) {
    // Call base class
    UNIFACE.widget.apply(this, arguments);

    this.initialAttributes = {};
    this.backgroundImage = null;
    this.style =null;
    this.wrapperNode = null;
    this.styleNodes = [];
    this.backupCssTexts = [];
    this.backupHtmlProps = {};
};

UNIFACE.widget.AbstractWidget.prototype = new UNIFACE.widget();

UNIFACE.widget.AbstractWidget.prototype.setCssProperty = function(aStyle, aProp, aValue, aPriority) {
    if ( aStyle[aProp] !== aValue ) {
        if ( aPriority != null ) { // pragma(allow-loose-compare)
            if ( typeof aStyle.setProperty === "function" ) {
                aStyle.setProperty(aProp, aValue, aPriority);
            } else {
                aStyle.cssText += ";" + aProp + ":" + aValue + "! " + aPriority + ";";
            }
        } else {
            aStyle[aProp] = aValue;
        }
    }
};

UNIFACE.widget.AbstractWidget.prototype.setHtml_className = function(aValue) {
    var oldValue;
    var element = this.wrapperNode;
    
    if (element ) {
        oldValue = element.className;
        
        element.className = aValue;
    }
    
    return oldValue;
};

UNIFACE.widget.AbstractWidget.prototype.setHtmlProp = function(aProp, aValue) {
    var oldValue;
    try {
        var element = this.getElement();
        
        if (element ) {
            oldValue = element[aProp];
            element[aProp] = aValue;
        }
    } catch ( e ) {  // happen for ie6
        //oldValue = null;
    }
    return oldValue;
};
UNIFACE.widget.AbstractWidget.prototype.getStyleNode = function(aProp) {
    return this.getElement();
};

UNIFACE.widget.AbstractWidget.prototype.setStyleProp = function(aProp, aValue) {
    try {
        var styleNode = this.getStyleNode(aProp);
        this.setCssProperty(styleNode.style, aProp, aValue);
    } catch ( e ) {  // happen for ie6
        // ignore;
    }
};

UNIFACE.widget.AbstractWidget.prototype.setProperties = function () {
    var p, lSetter, oldValue;

    // restore the html properties
    for ( p in this.backupHtmlProps ) if ( this.backupHtmlProps.hasOwnProperty(p) ) {
        lSetter = this["setHtml_" + p];
        if ( typeof lSetter === "function" ) {
            lSetter.call(this, this.backupHtmlProps[p]);
        } else {
            this.setHtmlProp(p, this.backupHtmlProps[p]);
        }
    }
    this.backupHtmlProps = {};

    // First restore the style properties.
    for ( var i=0, l=this.styleNodes.length; i<l; i++ ) {
        this.styleNodes[i].style.cssText = this.backupCssTexts[i];
    }

    var l_props = this.callBack.getProperties();
    // Set the html properties
    for ( p in l_props.html ) if ( l_props.html.hasOwnProperty(p) ) {
        lSetter = this["setHtml_" + p];
        if ( typeof lSetter === "function" ) {
            oldValue = lSetter.call(this, l_props.html[p]);
        } else {
            oldValue = this.setHtmlProp(p, l_props.html[p]);
        }
        this.backupHtmlProps[p] = oldValue;
    }

    // Set the style properties
    var element = this.getElement();
    if (element && element.style != undefined) { // pragma(allow-loose-compare)
        var l_style = element.style;
        
        for ( p in l_props.preStyle ) if ( l_props.preStyle.hasOwnProperty(p) ) {
            lSetter = this["setStyle_" + p];
            if ( typeof lSetter === "function" ) {
                lSetter.call(this, l_props.preStyle[p]);
            } else {
                this.setStyleProp(p, l_props.preStyle[p]);
                //l_style[p] = l_props.preStyle[p];
            }
        }
        
        if ( l_props.preStyle.display != undefined ) { // pragma(allow-loose-compare)
            element.U_display = l_props.preStyle.display;
        }
        
        this.style = l_style.cssText;
    }
    
    // Set the uniface properties
    if (typeof this.setUnifaceProp === "function") {
        for (p in l_props.uniface) if (l_props.uniface.hasOwnProperty(p)) {
            this.setUnifaceProp(p, l_props.uniface[p]);
        }
    }
    
    // Set the trigger properties.
    if (typeof this.setTriggerProp === "function") {
        for (p in l_props.trigger) if (l_props.trigger.hasOwnProperty(p)) {
            this.setTriggerProp(p, l_props.trigger[p]);
        }
    }
};
        
UNIFACE.widget.AbstractWidget.prototype.postRender = function(a_placeHolder) {
    this.setValue(this.callBack.getValue());
};

UNIFACE.widget.AbstractWidget.prototype.render = function(a_placeHolder) {
    this.preRender(a_placeHolder);
    this.doRender(a_placeHolder);
    this.postRender(a_placeHolder);
    
    // backup the style properties
    this.initStyleNodes();
    for ( var i=0, l=this.styleNodes.length; i<l; i++ ) {
        this.backupCssTexts.push(this.styleNodes[i].style.cssText);
    }
};

UNIFACE.widget.AbstractWidget.prototype.initStyleNodes = function() {
    this.styleNodes.push(this.getElement());
};

var g_helperNode;
///////////////////////////////////////////////////////////////////////////////
// UNIFACE.widget.AbstractWidget.prototype.accesskey
// Removes the UNIFACE % signs from the string and fills in the accessKey 
// member which can be used by the widget to set the access key.
// Parameters:
// labelString - string containing % signs
// bSupportsAccess - Some widgets do not support accesskeys (dropdown/listbox)
//                   but % should be removed.
// bAsHTML         - Return string as HTML to under accelerator char.
///////////////////////////////////////////////////////////////////////////////
UNIFACE.widget.AbstractWidget.prototype.accesskey = function(labelString,bSupportsAccess,bAsHTML) {
  var str = null;

  if (bAsHTML) {
      if (g_helperNode === undefined) {
          g_helperNode = document.createElement("div");
          g_helperNode.style.display = "none";
          document.body.appendChild(g_helperNode);
      }
      var l_text = document.createTextNode(labelString);
     
      g_helperNode.innerHTML = "";
      g_helperNode.appendChild(l_text);
      str =  g_helperNode.innerHTML;
  } else {
      str =labelString;
  }
  this.ackey = 0; //remember for rendering
  var me = this;
  
  return str.replace(/%(.)/g, function(aMatch, aChar) {
        if (me.ackey===0 && /[a-zA-Z]/.test(aChar)) {
            me.ackey = aChar;
            if (bAsHTML){
                return "<u>" + aChar + "</u>";
            }
        }
        return aChar;
    }
  );
};

UNIFACE.widget.AbstractWidget.prototype.resetProperties = function() {
};
UNIFACE.widget.AbstractWidget.prototype.getElement = function() {
};
UNIFACE.widget.AbstractWidget.prototype.preRender = function() {
};
UNIFACE.widget.AbstractWidget.prototype.doRender = function() {
};
UNIFACE.widget.AbstractWidget.prototype.getEventCatcher = function() {
};


///////////////////////////////////////////////////////////////////////////////
// UNIFACE.eventMapper
// Object that maps widget events to field triggers and keeps track of those
// mappings so that they can be undone on page unload.
///////////////////////////////////////////////////////////////////////////////

UNIFACE.eventMapper = (function() {
    var allMappings = [];
    function _map(source, eventName, widget, trg) {
        // Get the mapped javascript function
        var f = widget.callBack.bindEvent(trg);
        if (typeof f === "function") {
            // Map the event to the trigger
            if (source.addEventListener) {
                source.addEventListener(eventName.substring(2), f, false);
            } else if (source.attachEvent) {
                source.attachEvent(eventName, f);
            } else {
            	source[eventName] = f;
            }
            // Register the mapping
            allMappings.push({src:source, evt:eventName, listener:f });
        }
    }
    function _clear() {
        // Clear all event mappings
        for (var i = allMappings.length - 1; i >= 0; i--) {
            var mapping = allMappings[i];
            if (mapping.src.removeEventListener) {
            	mapping.src.removeEventListener(mapping.evt.substring(2), mapping.listener, false);
            } else if (mapping.src.detachEvent) {
            	mapping.src.detachEvent(mapping.evt, mapping.listener);
            } else {
            	mapping.src[mapping.evt] = null;
            }
            allMappings[i] = null;
        }
        allMappings = [];
    }
    UNIFACE.addOnUnloadListener(_clear);

    return {
        map: _map
    };
})();

}());
