
function common_ini(req, file_name) {
  this.req = req;
  this.file_name = file_name;

  this.ifile = '';
  this.ifile_lines = 0;
  this.isDebug = false;

  this.sections = new Array();

  this.set_cached_sections = common_ini_set_cached_sections;
  this.set_cached_keys = common_ini_set_cached_keys;

  this.enum_sections = common_ini_enum_sections;
  this.enum_keys = common_ini_enum_keys;
  this.get_key = common_ini_get_key;

  this.write_sections = common_ini_write_sections;
  this.write_select_single = common_ini_write_select_single;

  this.set_cached_sections();

  return this;
}

function common_ini_set_cached_sections()
{
  this.sections.length = 0;

  var tmp = this.req.read(this.file_name);

  if(!is_string(tmp)) return false;

  tmp = tmp.replace(/\r/g, '');

  this.ifile = tmp.split('\n');

  this.ifile_lines = this.ifile.length;

  if(this.ifile_lines === 0) return true;

  var pos = 0;
  var vValue = null;

  for(var i = 0; i < this.ifile_lines; i++)
  {
    vValue = lr_trim(this.ifile[i]);

    if(strlen(vValue) === 0 || vValue.substr(0, 1) !== '[' || (pos = vValue.lastIndexOf(']')) === false) continue;

    buf = lr_trim(vValue.substr(1, pos - 1));

    if(array_key_exists(buf, this.sections)) continue;

    this.sections[buf] = {0: i, 1: new Array()};
    this.set_cached_keys(buf);
  }


  return true;
}

function common_ini_set_cached_keys(section)
{
  if(!array_key_exists(section, this.sections)) return false;

  var vValue = null;
  var buf = null;
  
  for(var i = this.sections[section][0] + 1; i < this.ifile_lines; i++)
  {
    vValue = lr_trim(this.ifile[i]);

    if(strlen(vValue) === 0) continue;

    if(vValue.substr(0, 1) === '[' && vValue.lastIndexOf(']') !== -1) return true;

    if(vValue.substr(0, 1) === ';' || vValue.indexOf('=') === -1) continue;

    buf = vValue.split('=', 2);

    if(!is_array(buf)) return false;
    
    buf[0] = lr_trim(buf[0]);
    
    if(!array_key_exists(buf[0], this.sections[section][1])) this.sections[section][1][buf[0]] = lr_trim(buf[1]);
  }

  return true;
}

function common_ini_enum_sections()
{
  return array_keys(this.sections);
}

function common_ini_enum_keys(section)
{
  if(!array_key_exists(section, this.sections)) return new Array();

  return array_keys(this.sections[section][1]);
}

function common_ini_get_key(section, keyname, ret_default)
{
  if(!isset(ret_default)) ret_default = false;

  if(!array_key_exists(section, this.sections) ||
     !array_key_exists(keyname, this.sections[section][1])
     ) return ret_default;

  return this.sections[section][1][keyname];
}

function common_ini_write_sections(sections, to_write, auto_type, use_numeric, doc, html_sections, std_add)
{
  if(!isset(sections) || !(is_string(sections) || is_array(sections))) return false;

  if(is_string(sections) && strlen(sections)===0) return false;

  if(is_string(sections)) sections = [sections];

  if(is_string(to_write) && strlen(to_write)===0) return false;

  if(!is_string(to_write)) to_write = 'innerHTML';

  if(!is_bool(auto_type)) auto_type = false;
  if(!is_bool(use_numeric)) use_numeric = false;

  if(!is_string(std_add)) std_add = '';

  if(!isset(html_sections)) html_sections = [];
  if(is_string(html_sections)) html_sections = [html_sections];

  if(!isset(doc) || is_null(doc)) doc = document;

  var i = null, j = null;
  var list_keys = null;
  var cur_section = null, cur_section_doc = null, cur_key = null;

  var is_std_add = strlen(std_add)>0;

  var cur_elem = null;

  var cur_target = null;
  var to_eval = '';

  var to_numeric = false;

  if(is_std_add) std_add = '"' + std_add + '" + ';

  for(i in sections)
  {
    cur_section = sections[i];

    if(!is_string(cur_section) || strlen(cur_section)===0) continue;

    //if(this.isDebug) alert(cur_section);

    list_keys = this.enum_keys(cur_section);

    cur_section_doc = (array_key_exists(i, html_sections) ? html_sections[i] : cur_section);

    //if(this.isDebug) alert(cur_section_doc);

    for(j in list_keys)
    {
      cur_key = list_keys[j];

      if(!is_string(cur_key) || strlen(cur_key)===0) continue;

      //if(this.isDebug) alert(cur_section + '_' + cur_key);

      cur_elem = doc.getElementById(cur_section_doc + '_' + cur_key);

      if(!cur_elem) continue;

      //alert(cur_section + '_' + cur_key);

      if(auto_type)
      {
        to_eval = 'to_numeric = is_number(cur_elem.' + to_write + ');';

        try {
          eval(to_eval);
        } catch(not_eval)
        {
          alert('canīt detect the typ');
        }
      }
      else to_numeric = use_numeric;

      to_eval = 'cur_elem.' + to_write + ' = ' + (to_numeric ? '1*' :
                                                  (is_std_add ? std_add : '')) + 'this.get_key(cur_section, cur_key);';

      try {
        eval(to_eval);
      } catch(not_eval)
      {
        alert('canīt write to '+to_eval);
      }
    }
  }

  return true;
}

function common_ini_write_select_single(section, obj_name, append_mode, auto_key, chk_key, doc)
{
  if(!is_string(section) || strlen(section)===0 ||
     !is_string(obj_name) || strlen(obj_name)===0
    ) return false;

  if(!is_bool(append_mode)) append_mode = false;
  if(!is_bool(auto_key)) auto_key = false;

  if(!isset(chk_key)) chk_key = null;

  if(!isset(doc)) doc = document;

  var obj = doc.getElementById(obj_name);

  if(!obj) return false;

  var tmp, i;

  if(auto_key && is_null(chk_key) && obj.selectedIndex !== -1)
  {
    chk_key = '' + obj.options[obj.selectedIndex].value;
    /*for(i = 0; i < obj.length; i++)
    {
      if(obj.options[i].selected === false) continue;

      chk_key = '' + obj.options[i].value;
      break;
    }*/
  }

  if(!append_mode) obj.length = 0;

  var list_keys = null;
  var cur_section = null, cur_key = null;

  var cur_elem = null;
  var do_sel = false;

  list_keys = this.enum_keys(section);

  for(i in list_keys)
  {
    cur_key = list_keys[i];

    if(!is_string(cur_key) || strlen(cur_key)===0) continue;

    do_sel = (!is_null(chk_key) && cur_key === chk_key);

    obj.options[obj.length] = new Option(this.get_key(section, cur_key), cur_key, do_sel, do_sel);
  }

  return true;
}
