// DataInput.js
// Javascript Behaviour for the DataInput Control
// Copyright (c) by Matthias Hertel, http://www.mathertel.de
// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
// ----- 
// 16.09.2005 created by Matthias Hertel
// 30.09.2005 precission (prec) attribute added
// 21.10.2006 persisting properties removed. use the the PropPersist AJAX Control instead.
// 19.07.2007 helptext added
// 09.08.2007 eventname added: the local or complete event name that is used for publishing OpenAjax events.
// 09.08.2007 afterinit method added to publish current value
// 15.08.2007 registering in OpenAjax added.
// 22.08.2007 only publish real, non-empty values in the afterinit function.
// 14.09.2007 propname removed.
// 12.12.2007 adding OpenAjax events for forms.
// 18.12.2007 Simplifications and documentation.

jcl.DataInputBehavior = {
/// <summary>Implementation of a DataInput control.<br />
/// This control allows displaying data from OpenAjax events in &lt;input&gt; elements
/// and publishing OpenAjax events when the user changes the value.</summary>

// --- Attributes
nosubmit: false, /// <summary>Enable the ENTER Key on input elements without submitting a html-form.</summary>

datatype: "", /// <summary>The datatype of the input element.</summary>
prec: "", /// <summary>Precision for numeric types.</summary>

eventname: "", /// <summary>The local or complete event name that is used for publishing OpenAjax events.</summary>
helptext: "", /// <summary>the helptext is displayed when the field is empty and has no focus.</summary>


init: function () {
  /// <summary>Initialze the JavaScript control.</summary>
  var en;
  if ((this.eventname != null) && (this.eventname != "")) {
    en = jcl.BuildFullEventname(this);
    OpenAjax.hub.subscribe(en, this.handleEvent, this);
    OpenAjax.hub.subscribe(jcl.EventNameSpace(en) + ".clear", this.clearData, this);
    OpenAjax.hub.subscribe(jcl.EventNameSpace(en) + ".reset", this.resetData, this);
  } // if
      
  // if a datatype is given and if the nls functionality is present
  // use the nls functionality to support the special datatype
  // conversion functions and input-key filters.
  if ((typeof(nls) != "undefined") && (this.datatype != "")) {
    this._toString = nls[this.datatype].toString;
    this._toValue = nls[this.datatype].toValue;
    this._keys = nls[this.datatype].keys;
    this._mapkeys = nls[this.datatype].mapkeys;
    this.title = nls[this.datatype].title;
  } // if
  
  // a precision might be set for numeric values.
  if (this.prec == "")
    this.prec = 0;
  else
    this.prec = parseInt(this.prec, 10);
    
  if ((this.value == "") && (this.helptext != null)) {
    this.value = this.helptext;
    jcl.addClassName(this, "EMPTY");
  } // if
}, // init


afterinit: function () {
  /// <summary>After loading the page the other components should know about the current value.</summary>
  if (! this._isEmpty())
    this.validate();
}, // afterinit


// --- events

onfocus: function(evt) {
  /// <summary>Handle the onfucus event.
  /// Remove the helptext when the focus enters the field and no real value is present.</summary>
  if (this._isEmpty()) {
    jcl.removeClassName(this, "EMPTY");
    this.value = "";
  } // if
}, // onfocus


onblur: function(evt) {
  /// <summary>Handle the onblur event.
  /// Add the helptext when the focus leaves the field and no real value is present.</summary>
  if ((this.value == "") && (this.helptext != null) && (this.helptext != "")) {
    this.value = this.helptext;
    jcl.addClassName(this, "EMPTY");
  } // if
}, // onblur


onkeypress: function(evt) {
  /// <summary>Handle the onkeypress event.
  /// Analyse the pressed key and allow only valid key entries.
  /// This feature is useable for numeric values and helps avoiding bad formats.
  /// map some key to others: This feature can be used to map decimal separators.</summary>
  evt = evt || window.event;
  var fieldValue = this.value;
  var k;
  var r = true;

  // validate the value when pressing <enter>
  if (evt.keyCode == 13)
    this.validate();

  // get the pressed character 
  if (jcl.isIE) {
    k = String.fromCharCode(evt.keyCode);
  } else {
    if (evt.charCode == 0)
      return(true);
    k = String.fromCharCode(evt.charCode);
  }
  
  // if a key list is present, allow only the specified keys.
  if ((this._keys == null) || (this._keys.indexOf(k) >= 0)) {
    r = true;
  } else if ((this._mapkeys != null) && (this._mapkeys.indexOf(k) >= 0)) {
    // if the key is in the mapkeys list then use the first specified key instead
    if (jcl.isIE)
      evt.keyCode = this._keys.charCodeAt(0);
  } else {
    r = false;
  } // if
  evt.returnValue = r;
  return (r);
}, // handleKeyPress


onchange: function (evt) {
  /// <summary>Handle the onchange event and revalidate the current value.</summary>
  this.validate();
}, // onchange


// --- OpenAjax event handler ---
handleEvent: function (eventName, eventData) {
  /// <summary>OpenAjax event handler that captures any changed values.</summary>
  this.setData(eventData);
}, // handleEvent


// --- data binding ---

setData: function(v) {
  /// <summary>Display a new value.</summary>
  this.value = this._toString(v, this.prec);
  if (this.value.length == 0)
    jcl.addClassName(this, "EMPTY");
  else
    jcl.removeClassName(this, "EMPTY");
}, // setData


getData: function() {
  /// <summary>Return the actual value of the input field.</summary>
  if (this._isEmpty())
    return("");
  else
    return(this._toValue(this.value, this.prec));
}, // getData


clearData: function() {
  /// <summary>Clear the current value.</summary>
  this.value = "";
  jcl.addClassName(this, "EMPTY");
}, // clearData


resetData: function() {
  /// <summary>Reset the actual value to the initial defined value.</summary>
  this.setData(this.defaultValue);
}, // resetData


validate: function () {
  /// <summary>Validate and reformat the current value.</summary>
  var v = this._toValue(this.value, this.prec);
  this.value = this._toString(v, this.prec);
  OpenAjax.hub.publish(jcl.BuildFullEventname(this), v);
}, // validate


_isEmpty: function () {
  /// <summary>Return true if the current value is empty and a helptext might be displayed.</summary>
  return (this.className.indexOf("EMPTY") >= 0);
}, // _isEmpty

// --- nls support
// these wil be replaced by some objects and methods from the 
// nls object that holds datatype specific objects and methods.

_keys: null,
_mapkeys: null,
_toString: function (v) { return(v); },
_toValue: function (v) { return(v); }

} // jcl.DataInputBehavior