/****************************************
* FILE: data_display.js                 *
* NAME: Mick Thomure                    *
* DESC: Functions for handling form     *
*       fields created by data:display  *
* NOTE: funcs prepended with 'dd_' are	*
*	considered private to the file.	*
****************************************/


/******** VARS ***********************/

  var DD_PREPEND, DD_QINFO, DD_ERROR, DD_ID_CACHE;

  // Field prepend string
  DD_PREPEND   = '';
  // Name of query info object
  DD_QINFO = Object();
  // Error message
  DD_ERROR = '';
  // ID cache (see dd_get_ids)
  DD_ID_CACHE = Object();


/******** FUNCS **********************/

  /******************************************************
  * PARAM:						*
  *   pre - (str) prepended string (opt)		*
  * DESC: Set prepend string for data_display's fields.	*
  * RETURN: none					*
  ******************************************************/
  function dd_set_prepend(pre) {
    DD_PREPEND = pre;
  }
  
  /******************************************************
  * PARAM:						*
  * DESC: Get prepend string for data_display's fields.	*
  * RETURN: (str) current prepend string		*
  ******************************************************/
  function dd_get_prepend() {
    return DD_PREPEND;
  }

  /******************************************************
  * PARAM:						*
  *   qname - (str) query name				*
  *   id    - (int) query index				*
  * DESC: Set index [id] for query [qname].		*
  * RETURN: none					*
  ******************************************************/
  function dd_set_query(qname, id) {
    DD_QINFO[ qname ] = id;
  }

  /******************************************************
  * PARAM:						*
  *   qname - (str) query name				*
  * DESC: Get index for query [qname].			*
  * RETURN: (int) current index value			*
  ******************************************************/
  function dd_get_query(qname) {
    return DD_QINFO[ qname ];
  }


  /******************************************************
  * PARAM:						*
  *   form - (HTMLForm|str) html form			*
  *   query - (str) query name
  *   field - (str) html field name
  *   row   - (int) row index
  *   value - (str|int) field value
  * DESC: 
  * RETURN: (int) 1 on success, else null		*
  ******************************************************/
  function dd_set_sql_field(form, query, field, row, value) {
    if (!(form = u_get_form(form)))
      return dd_error(u_error());

    var t = form[ dd_sql2html(form, query, field, row) ];

    if (t) {
      t.value = value;
      return 1;
    }

    return dd_error("Field not found: " + field);
  }

  /******************************************************
  * PARAM:						*
  *   form - (HTMLForm|str) html form			*
  *   query - (str) query name
  *   field - (str) html field name
  *   row   - (int) row index
  * DESC: 
  * RETURN: 
  ******************************************************/
  function dd_get_sql_field(form, query, field, row) {
    var t = dd_get_sql_field_obj(form, query, field, row);

    if (t)
      return t.value;

    // Return error value from dd_get_sql_field_obj()
    return t;
  }


  /******************************************************
  * PARAM:						*
  * DESC: 
  * RETURN: 
  ******************************************************/
  function dd_get_sql_field_obj(form, query, field, row) {
    if (!(form = u_get_form(form)))
      return dd_error(u_error());

    var t = form[ dd_sql2html(form, query, field, row) ];

    if (t)
      return t;

    return dd_error("Field not found: " + field);
  }


  /******************************************************
  * PARAM:						*
  *   form - (obj) html form				*
  *   pid  - (int) parent id				*
  * DESC: Get list of sub ids in [form] for [pid].	*
  * RETURN: (array) sub ids if found, else null		*
  ******************************************************/
  function dd_get_ids(form, pid) {
    var i, c, m, r;

    // Look for id list in cache
    if (!(r = DD_ID_CACHE[ pid ])) {
      c = form.elements;
      r = Array();

      for (i=0; i < c.length; i++) {
	if (m = c[ i ].name.match("^" + DD_PREPEND + "[ahs]\\(" + pid + ", (\\d+)\\)$"))
	  r[ r.length ] = m[1];
      }

      DD_ID_CACHE[ pid ] = r;
    }

    if (r.length)
      return r;

    return null;
  }


  /******************************************************
  * PARAM:						*
  * DESC: 
  * RETURN: 
  ******************************************************/
  // Lookup sql name from HTML field name
  function dd_html2sql(form, query, fname) {
    var t, qid, findex, farray, re, matches, rindex, rids;

    if (typeof fname != 'string')
      return dd_error("Invalid field name: " + fname);

    if (!(form = u_get_form(form)))
      return dd_error(u_error());

    if (!(qid = dd_get_query_id(query)))
      return null;

    farray = dd_get_array(form, qid, 'names');

    if (matches = fname.match(DD_PREPEND + "s\\(([0-9]+)\\s*,\\s*([0-9]+)\\)$")) {
      rindex = Number(matches[1]);
      findex = Number(matches[2]);

      // Get list of sub ids for record array
      rids = dd_get_ids(form, dd_get_array(form, qid, 'records'));
      // Check that [rindex] is in [rids]
      if (!rids || !u_grep(rindex, rids))
	return dd_error("Record array not found: " + rindex);

      return dd_get_scalar(form, farray, findex);
    }

    return dd_error('Field not found (' + fname + ')');
  }

  var lookup_sql_field = dd_html2sql;

  /******************************************************
  * PARAM:						*
  * DESC: 
  * RETURN: 
  ******************************************************/
  // Create HTML field name from SQL field info
  function dd_sql2html(form, query, field, row) {
    var t, qid, rarray, rindex, farray, findex;

    if (!(form = u_get_form(form)))
      return dd_error(u_error());

    if (!(qid = dd_get_query_id(query)))
      return null;

    if (row == null)
      row = 0;

    rarray = dd_get_array(form, qid,    'records');
    farray = dd_get_array(form, qid,    'names');
    rindex = dd_get_array(form, rarray, row);

    if ((findex = dd_get_index_by_value(form, farray, field)) < 0)
      return dd_error('Field not found (' + field + ')');

    return dd_get_scalar_name(rindex, findex);
  }

  var lookup_html_field = dd_sql2html;


/********* Utility Functions *******************************************/

  /******************************************************
  * PARAM:						*
  * DESC: 
  * RETURN: 
  ******************************************************/
  function dd_error(msg) {
    if (msg != null) {
      DD_ERROR = msg;
      return null;
    }
    return DD_ERROR;
  }


  /**************************************************************************************************************
  * PARAM:                                                                                                      *
  *   form - (Form Object)                                                                                      *
  *   id   - (int) id of array                                                                                  *
  *   v    - (str) entry value to search for                                                                    *
  * DESC: Lookup an array index by its value (grep the array associated with [id]).                             *
  * WARNING: if more than one entry has the same value, this function will return the index of the first entry. *
  * RETURN: (int) array index if [v] is found, else -1                                                          *
  ***************************************************************************************************************/
  function dd_get_index_by_value(form, id, v) {
    var i, f;

    // Loop through all the values for array associated with [id]
    for (i = 0; f = form[ dd_get_scalar_name(id, i) ]; i++) {
      if (f.value == v)
        return i;
    }

    return -1;
  }


  /******************************************************
  * PARAM:						*
  * DESC: 
  * RETURN: 
  ******************************************************/
  // Lookup query id from query name
  function dd_get_query_id(query) {
    var qid;

    if (!DD_QINFO)
      return dd_error('Query info variable not found');

    if ((qid = DD_QINFO[query]) == null)
      return dd_error('Query not found (' + query + ')');

    return qid;
  }

  function dd_get_name(type, pid, id) {
    return DD_PREPEND + type + '(' + pid + ', ' + id + ')';
  }
  function dd_get_entry(form, type, pid, id) {
    return form[ dd_get_name(type, pid, id) ].value;
  }

  // Shortcut functions
  function dd_get_array(form, pid, id) {
    return dd_get_entry(form, 'a', pid, id);
  }
  function dd_get_scalar(form, pid, id) {
    return dd_get_entry(form, 's', pid, id);
  }
  function dd_get_hash(form, pid, id) {
    return dd_get_entry(form, 'h', pid, id);
  }
  function dd_get_array_name(pid, id) {
    return dd_get_name('a', pid, id);
  }
  function dd_get_scalar_name(pid, id) {
    return dd_get_name('s', pid, id);
  }
  function dd_get_hash_name(pid, id) {
    return dd_get_name('h', pid, id);
  }





/****** Old Functions **********************************************************/
  // Lookup sql name from HTML field name
  function dd_html2sql_old(form, query, fname) {
    var re, matches, t;

    if (!(form = u_get_form(form)))
      return dd_error(u_error());

    if ((matches = fname.match(DD_PREPEND + "field\\([A-z|_|0-9]+\\s*,\\s*(.*)\\)$")) && matches.length > 1)
      return matches[1];

    return dd_error("Field not found (" + fname + ")");
  }

  // Create HTML field name from SQL field info
  function dd_sql2html_old(form, query, field, row) {
    var t, qid;

    if (!(form = u_get_form(form)))
      return dd_error(u_error());

    if (!(qid = dd_get_query_id(query)))
      return null;

    if (row == null)
      row = 0;

    // Increment outside string concat to avoid '01' instead of '1' being printed
    row++;

    return DD_PREPEND + 'field(r_' + qid + '_' + row + ', ' + field + ')';
  }

