
// ################################################################################
// #########################################################|  CSVReader-Editor  |##
// ################################################################################

// Autor: df
// 11.11.2005

// ============================================================
// Klasse CSVReader
// ============================================================
//
// Objekthierarchie:
// -----------------
//   CSVReader
//     |
//
// Konstruktor:
// ------------
//   + CSVReader()
//   + CSVReader.createInstance()
//
// Eigenschaften:
// --------------
//   + hasHead: bool (readonly) (false, true)
//   + csvString: str (readonly) (csv)
//   + csvQuote: str (readonly) (" oder ')
//   + csvSeparator: str (readonly) (, oder ;)
//   + row: arr 
//
// Methoden:
// ---------
//   + setHasHead(bool) : void
//   + setCSVString(str) : void
//   + setCSVQuote(str) : void
//   + setCSVSeparator(str) : void
//
// Beschreibung:
// -------------
//   ...
//

var undefined;

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

function CSVReader(idx) {
  if (arguments.length>1) {
    focus();
    throw new Error("new CSVReader: Falsche Anzahl von Argumenten!");
  }
  // Attribute
  this._id = undefined;
  this.hasHead = false;
  this.csvString = '';
  this.csvQuote = CSVReader._defaultQuote;
  this.csvSeparator = CSVReader._defaultSeparator;
  this.row = [];
  
  this.id(idx);
}

// toString()
CSVReader.prototype.toString = function() {
  var str = '';
  return str;
}

// ------------------------------------------------------------
// Zugriffsmethoden
// ------------------------------------------------------------

// -------------
// id()
// -------------
CSVReader.prototype.id = function(str) {
  if (arguments.length > 1) {
    focus();
    throw new Error("CSVReader->id: Falsche Anzahl von Argumenten!");
  }
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("CSVReader->id: Argument ist nicht vom Typ String!");
    }
    this._id = str;
  }
  return this._id;
}

// -------------
// setHasHead
// -------------
CSVReader.prototype.setHasHead = function(b) {
  if (arguments.length>1) {
    focus();
    throw new Error("CSVReader->setHasHead: Falsche Anzahl von Argumenten!");
  }
  if (typeof b != "boolean") {
    focus();
    throw new Error("CSVReader->setHasHead: Argument ist nicht vom Typ boolean!");
  }
  this.hasHead = b;
}

// -------------
// setCSVString()
// -------------
CSVReader.prototype.setCSVString = function(str) {
  if (arguments.length > 1) {
    focus();
    throw new Error("CSVReader->setCSVString: Falsche Anzahl von Argumenten!");
  }
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("CSVReader->setCSVString: Argument ist nicht vom Typ String!");
    }
    this.csvString = CSVReaderUtil.stripSpace(str);
  }
  return this.csvString;
}

// -------------
// setCSVQuote()
// -------------
CSVReader.prototype.setCSVQuote = function(str) {
  if (arguments.length > 1) {
    focus();
    throw new Error("CSVReader->setCSVQuote: Falsche Anzahl von Argumenten!");
  }
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("CSVReader->setCSVQuote: Argument ist nicht vom Typ String!");
    }
    this.csvQuote = str;
  }
  return this.csvQuote;
}

// -------------
// setCSVSeparator()
// -------------
CSVReader.prototype.setCSVSeparator = function(str) {
  if (arguments.length > 1) {
    focus();
    throw new Error("CSVReader->setCSVSeparator: Falsche Anzahl von Argumenten!");
  }
  if (arguments.length) {
    if (typeof str != "string") {
      focus();
      throw new Error("CSVReader->setCSVSeparator: Argument ist nicht vom Typ String!");
    }
    this.csvSeparator = str;
  }
  return this.csvSeparator;
}

// ------------------------------------------------------------
// Private Instanzmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Instanzmethoden
// ------------------------------------------------------------

// -------------
// callCSVProperties()
// -------------
CSVReader.prototype.callCSVProperties = function() {
  var callback = new Function('quote', 'separator', 'CSVReader.getInstance("'+ this.id() +'").setCSVProperties(quote, separator)');
  dialogContext = {callback : callback, multiple : false};
  var dialogWindow = window.open('');
  dialogWindow.document.open();
  var html = '<html><head><script>';
  html += 'function giveProperties(){\n';
  html += 'var quote = document.myform.quote.options[document.myform.quote.selectedIndex].value\n';
  html += 'var separator = document.myform.separator.options[document.myform.separator.selectedIndex].value\n';
  html += 'opener.dialogContext.callback(quote, separator);\n';
  html += 'return false;\n';
  html += 'close();\n';
  html += '}\n';
  html += '</script>\n</head>\n<body>\n';
  html += '<form name="myform" onsubmit="return giveProperties();">\n';
  html += '<select name="separator">\n';
  html += '<option value="," selected="selected">Komma</option>\n';
  html += '<option value=";">Semikolon</option>\n';
  html += '</select><br/>\n';
  html += '<select name="quote">\n';
  html += '<option value=\'"\' selected=\'selected\'>Gänsefuß</option>\n';
  html += '<option value="\'">Hochkomma</option>\n';
  html += '</select><br/>\n';
  html += '<input type="submit" value="OK"/><br/>\n';
  html += '</form>\n';
  html += '</body></html>\n';
  dialogWindow.dialogContext = dialogContext;
  dialogWindow.document.write(html);
  dialogWindow.document.close();
  dialogWindow.focus();
  return dialogContext;
}

// -------------
// setCSVProperties()
// -------------
CSVReader.prototype.setCSVProperties = function(quote, separator) {
  if (arguments.length != 2) {
    focus();
    throw new Error("CSVReader->setCSVProperties: Falsche Anzahl von Argumenten!");
  }
  if (typeof quote != "string") {
    focus();
    throw new Error("CSVReader->setCSVProperties: Argument ist nicht vom Typ String!");
  }
  if (typeof separator != "string") {
    focus();
    throw new Error("CSVReader->setCSVProperties: Argument ist nicht vom Typ String!");
  }
  this.setCSVQuote(quote);
  this.setCSVSeparator(separator);
}

// -------------
// getStructureByCSVString()
// -------------
CSVReader.prototype.getStructureByCSVString = function() {
  if (!this.csvString.length) {
    throw new Error("CSVReader->getStructureByCSVString: Es existiert kein CSV-String!");
  }
  var _csvString = this.csvString;
  var _rows = [];
  var _cell = [];
  var _str = '';
  var columnFirstRow = 0;
  var _escapingContext = false;
  while (_csvString.length){
    if (_csvString.charAt(0) == this.csvQuote){
      if (!_escapingContext){
        _escapingContext = true;
      } else {
        _escapingContext = false;
        if (_csvString.charAt(1) == this.csvQuote){
          _escapingContext = true;
        }
      }
    }
    if (! (_csvString.charAt(0) == this.csvSeparator && !_escapingContext)){
      _str += _csvString.charAt(0);
    }
    if ((_csvString.charAt(1) == this.csvSeparator && !_escapingContext) || ((_csvString.charAt(1) == '\n' && !_escapingContext) || _csvString.length == 1)){
      _str = this.formatValue(_str);
      _cell.push(_str);
      if (this.row.length == 0){
        columnFirstRow++;
      }
      _str = '';
      if ((_csvString.charAt(1) == '\n' && !_escapingContext) || _csvString.length == 1){
        if (columnFirstRow != _cell.length){
          alert('Die Spaltenanzahl ist nicht für alle Zeilen gleich.\nBitte überprüfen Sie Ihre CSV-Datei.\nFehler in Zeile ' + this.row.length + ', Spalte 1 = ' + _cell[0]);
          return false;
        }
        this.row.push(_cell);
        var _cell = [];
      }
    }
    _csvString = _csvString.substring(1, _csvString.length);
  }
  return this.row;
}

// ----------------
// formatValue
// ----------------
CSVReader.prototype.formatValue = function(str) {
  if (arguments.length != 1) {
    focus();
    throw new Error("CSVReader->formatValue: Falsche Anzahl von Argumenten!");
  }
  if (typeof str != "string") {
    focus();
    throw new Error("CSVReader->formatValue: Argument ist nicht vom Typ String!");
  }
  str = CSVReaderUtil.stripSpace(str);
  var exec = new RegExp('^' + this.csvQuote);
  str = str.replace(exec, '');
  exec = new RegExp(this.csvQuote + '$');
  str = str.replace(exec, '');
  exec = new RegExp(this.csvQuote + '' + this.csvQuote, 'gi');
  str = str.replace(exec, this.csvQuote);
  return str;
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

CSVReader._defaultQuote = '"';

CSVReader._defaultSeparator = ',';

CSVReader._defaultID = [];

CSVReader._registerInstance = {};

// ------------------------------------------------------------
// Öffentliche Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Private Klassenmethoden
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// ----------------
// getInstance
// ----------------
CSVReader.getInstance = function(idx) {
  if (arguments.length!=1) {
    throw new Error("CSVReader.getInstance: Falsche Anzahl von Argumenten!");
  }
  if (! (CSVReader._registerInstance[idx])){
    focus();
    throw new Error("CSVReader.getInstance: Es ist keine CSVReader.Instance mit id=" + idx + " registriert!");
  } 
  return CSVReader._registerInstance[idx];
}

// ----------------
// createInstance
// ----------------
CSVReader.createInstance = function(idx) {
  if (!arguments.length) {
    idx = CSVReader._defaultID.length;
    CSVReader._defaultID.push('1');
  }
  idx = idx.toString();
  if (! (CSVReader._registerInstance[idx])){
    CSVReader._registerInstance[idx] = new CSVReader(idx);
  } 
  return CSVReader.getInstance(idx);
}


// ============================================================
// Klasse TableUtil
// ============================================================

// ------------------------------------------------------------
// Konstruktor
// ------------------------------------------------------------

function CSVReaderUtil() {
}

// ------------------------------------------------------------
// Private Klasseneigenschaften
// ------------------------------------------------------------

// ------------------------------------------------------------
// Öffentliche Klassenmethoden
// ------------------------------------------------------------

// --------------
// stripSpace
// --------------
CSVReaderUtil.stripSpace = function(attr){
  var result = '';
  if (attr){
    attr = new String(attr);
    result = attr.replace(/^\s+/,'');
    result = result.replace(/\s+$/,'');
  }
  if (result.match(/^\s+/) || result.match(/\s+$/)){
    return TableUtil.stripSpace(result);
  }
  return result;
}




