// DataSource.js
// Javascript Behaviour for the DataSource 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
// ----- 
// 30.03.2007 created by Matthias Hertel
// 09.07.2007 registerDataChange was removed. Using OpenAjax.hub.publish now.
// 11.07.2007 insert, update and remove commands added.
// 15.08.2007 registering in OpenAjax added.
// 12.12.2007 usking jcl.DataInputBehavior
// 28.12.2007 documentation
// 06.01.2008 adding a "changed" event afer the page was loaded

jcl.DataSourceBehavior = {
/// <summary>Implementation of a DataSource controller.<br />
/// This control implements commands for a Ajax form that is bound to a web service for
/// retrieving and updateing data on a server. This control is invisible by default.</summary>

idList : "",  /// <summary>List containing the ids of all selected records.</summary>
index: 0,     /// <summary>Current cursor position.</summary>
form: null,   /// <summary>The form element.</summary>
sort: null,   /// <summary>Sort by column criteria.</summary>

_namespace: "de.mathertel.datasource.", /// <summary>The root namespace for dataSource events.</summary>

init: function () {
  /// <summary>Initialze the JavaScript control.
  /// Setup the service, form and cursor.</summary>
  var ws = "xTableData"; // ""
  if (this.service != null) 
    ws = this.service;
  if ((this.attributes != null) && (this.attributes["service"] != null))
    ws = this.attributes["service"].value;

  this._searchAction.call = "proxies." + ws + ".Search";
  this._displayAction.call = "proxies." + ws + ".Fetch";

  this.idList = "";
  this.index = -1;
  this._fireDataChange();
  
  if ((this.form) && (typeof(this.form) == "string"))
    this.form = document.getElementById(this.form);
  OpenAjax.hub.subscribe(this._namespace + "**", this._listener, this);
},

afterinit: function () {
  this._fireDataChange();
},



clear: function() {
  /// <summary>Handle the clear command:
  /// clear out all values from the form.</summary>
  this.form.clearData();
  this.index = -1;
  this._fireDataChange();
}, // clear


search: function() {
  /// <summary>Handle the search command:
  /// find all records that match the current entered criteria.</summary>
  ajax.Start(this._searchAction, this);
}, // search


first: function () {
  /// <summary>Handle the first command:
  /// navigate to the first record.</summary>
  this.index = 0;
  this._display();
}, // first


previous: function () {
  /// <summary>Handle the previous command:
  /// navigate to the previous record.</summary>
  this.index--;
  this._display();
}, // prev


next: function () {
  /// <summary>Handle the next command:
  /// navigate to the next record.</summary>
  this.index++;
  this._display();
}, // next


last: function () {
  /// <summary>Handle the last command:
  /// navigate to the last record.</summary>
  this.index = this.idList.length-1;
  this._display();
}, // last


insert: function () {
  /// <summary>Handle the insert command:
  /// insert the current values as a new record.</summary>
  ajax.Start(this._insertAction, this);
}, // insert


update: function () {
  /// <summary>Handle the update command:
  /// update the current record with then current values.</summary>
  if ((this.idList != null) && (this.idList.length >= 0) && (this.index >= 0)) {
    ajax.Start(this._updateAction, this);
  } // if
}, // update


remove: function () {
  /// <summary>Handle the remove command:
  /// delete the current record.</summary>
  if ((this.idList != null) && (this.idList.length >= 0) && (this.index >= 0)) {
    ajax.Start(this._removeAction, this);
  } // if
}, // remove


processException: function(ex) { 
  /// <summary>Handle an exception: t.b.d</summary>
  alert(ex.description);
},
  

_listener: function(name, data) {
  /// <summary>Listen to de.mathertel.datasource.** OpenAjax events
  /// and call all defined functions.</summary>
  var evName = name.substr(this._namespace.length);
  if ((this[evName]) && (typeof(this[evName]) == "function"))
    this[evName]();
}, // _listener
  

_display: function() {
  /// <summary>Start the display ajax action.</summary>
  if ((this.idList == null) || (this.idList.length == 0)) {
    this.form.clearData();
    this.index = -1;
    this._fireDataChange();
  } else {
    this.index = Math.max(0, this.index); 
    this.index = Math.min(this.idList.length-1, this.index); 
    ajax.Start(this._displayAction, this);
  }
}, // _display


_fireDataChange: function () {
  /// <summary>Publish an OpenAjax event
  /// that a complete new data set is available in the form.</summary>
  OpenAjax.hub.publish(this._namespace + "changed", this);
},


// --- some AJAX action definitions ---

_searchAction: {
  /// <summary>AJAX action to search for records that match the criterias
  /// by retreiving a set of unique ids from the server.</summary>
  delay: 100,
  prepare: function (ds) { 
    var p = new Array();
    p[0] = ds.form.read();
    p[1] = ds.sort;
    p.multi = true;
    return(p);
  },
  call: proxies.TableData.Search,
  finish: function (data, ds) {
    ds.idList = data.split(';');
    ds._display();
  },
  onException: function (ex, ds) { ds.processException(ex) }
}, // _searchAction 


_insertAction: {
  /// <summary>AJAX action to insert a new record on the server.</summary>
  delay: 100,
  prepare: function (ds) { return(ds.form.read()); },
  call: proxies.TableData.Insert,
  finish: function (data, ds) {
    ds.idList = data.split(';');
    ds._display();
  },
  onException: function (ex, ds) { ds.processException(ex) }
}, // _insertAction


_updateAction: {
/// <summary>AJAX action to update the current record on the server.</summary>
  delay: 100,
  prepare: function (ds) { 
    var p = new Array();
    p[0] = ds.idList[ds.index];
    p[1] = ds.form.read();
    p.multi = true;
    return(p);
  },
  call: proxies.TableData.Update,
  finish: function (data, ds) {
    ds.idList = data.split(';');
    ds._display();
  },
  onException: function (ex, ds) { ds.processException(ex) }
}, // _updateAction


_removeAction: {
/// <summary>AJAX action to delete the current record on the server.</summary>
  delay: 100,
  prepare: function (ds) { return(ds.idList[ds.index]) },
  call: proxies.TableData.Delete,
  finish: function (data, ds) {
    ds.idList.splice(ds.index, 1);
    ds._display();
    },
  onException: function (ex, ds) { ds.processException(ex) }
}, // _removeAction


_displayAction : {
/// <summary>AJAX action to fetch a record from the server
/// and display it inside the form elements.</summary>
  delay: 100,
  prepare: function (ds) { return(ds.idList[ds.index]); },
  call: proxies.TableData.Fetch,
  finish: function (data, ds) {
    ds.form.write(data); 
    ds._fireDataChange();
  },
  onException: function (ex, ds) { ds.processException(ex) }
} // _displayAction
  
} // jcl.DataSourceBehavior

