connection = NULL;
    
    $this->old_values = NULL;
    $this->error = NULL;
    
    ini_set("memory_limit",PHPWriter::mem_max_meg . "M");
    
    // print lots of error messages
    
    if(PHPWriter::debug) {
      error_reporting(E_ALL|E_STRICT);
      ini_set('display_errors', true);
      ini_set('html_errors', true);
    }
    
    $_POST['server'] = PHPWriter::fetch_value_if_exists($_GET,'server',PHPWriter::default_server);
    $_POST['user'] = PHPWriter::fetch_value_if_exists($_GET,'user',PHPWriter::default_user);
    $_POST['database'] = PHPWriter::fetch_value_if_exists($_GET,'database',PHPWriter::default_db);
    $_POST['table'] = PHPWriter::fetch_value_if_exists($_GET,'table',PHPWriter::default_table);
    $_POST['query'] = PHPWriter::fetch_value_if_exists($_GET,'query',PHPWriter::default_query);
    
  }
  
  function preserve_error()
  {
    if(mysql_errno() != 0) {
      $this->error .= mysql_error() . "
\n";
    }
  }
  
  function dump_array($array)
  {
    $output =  "" . time() . "
\n";
    if($array) {
      $keys = array_keys($array);
      for($i = 0;$i < count($keys);$i++) {
        $output .= $keys[$i] . " = [" . $array[$keys[$i]] . "]
\n";
      }
    }
    return $output;
  }
  
  function wrap_tag($data,$tag,$extra = "") {
    return "<$tag $extra>$data$tag>\n";
  }
  
  function fetch_value_strict($base,$name,$default = '') {
    $result = NULL;
    if($base && array_key_exists($name,$base) && strlen($base[$name]) > 0) {
      $result = $base[$name];
    }
    else if ($default && strlen($default) > 0) {
      $result = $default;
    }
    return $result;
  }
  
  function fetch_value_if_exists($base,$name,$default = '') {
    $result = NULL;
    if($base && array_key_exists($name,$base) && sizeof($base[$name]) > 0) {
      $result = $base[$name];
    }
    else if ($default && strlen($default) > 0) {
      $result = $default;
    }
    else if($this->old_values && array_key_exists($name,$this->old_values) && strlen($this->old_values[$name]) > 0) {
      $result = $this->old_values[$name];
    }
    return $result;
  }
  
  function get_assoc_values($base) {
    return array(
      $this->fetch_value_if_exists($base,'server'),
      $this->fetch_value_if_exists($base,'user'),
      $this->fetch_value_if_exists($base,'password'),
      $this->fetch_value_if_exists($base,'database'),
      $this->fetch_value_if_exists($base,'table'),
      $this->fetch_value_if_exists($base,'query'),
      $this->fetch_value_if_exists($base,'record')
    );
  }
  
  function set_values($names,$values) {
    $n = 0;
    $base = array();
    foreach($names as $name) {
      $base[$name] = $values[$n];
      $n++;
    }
    return $base;
  }
  
  function make_text_field($type,$title,$name,$value,$tip, $width = PHPWriter::textfield_width)
  {
    $btitle = $this->wrap_tag($title . ":","b");
    $result = $this->wrap_tag(" " . $btitle,"td");
    $input = "\n";
    $result .= $this->wrap_tag($input,"td");
    return $result;
  }
  
  function make_dropdown_list($title,$name,$value,$val_array,$tip) {
    $btitle = $this->wrap_tag($title . ":","b");
    $result = $this->wrap_tag(" " . $btitle,"td");
    $list = "";
    if($val_array)  {
      foreach ($val_array as $item) {
        $sel = ($item == $value)?"selected":"";
        $list .= $this->wrap_tag($item,"option",$sel);
      }
    }
    $substr = "name = \"$name\" title=\"$tip\" onChange=\"submit();\"";
    $list = $this->wrap_tag($list,"select",$substr);
    $result .= $this->wrap_tag($list,"td");
    return $result;
  }
  
  function create_table_header() {
    $row = "";
    mysql_data_seek($this->header_result,0);
    while($field = mysql_fetch_row($this->header_result)) {
      $row .= $this->wrap_tag($field[0],"td","class=\"cellTitle\"");
    }
    return $this->wrap_tag($row,"tr");
  }
  
  function create_table_rows() {
    $result = NULL;
    if($this->query_result) {
      $result = array();
      $record = $this->fetch_value_if_exists($_POST,'record');
      $n = 0;
      mysql_data_seek($this->query_result,0);
      while($rec = mysql_fetch_assoc($this->query_result)) {
        $selected = ($record == $n);
        $to_mark = ($record == $n+PHPWriter::record_list_offset);
        $row = "";
        mysql_data_seek($this->header_result,0);
        while($field = mysql_fetch_row($this->header_result)) {
          $fdata = $rec[$field[0]];
          $fdata = htmlspecialchars($fdata);
          $fdata = preg_replace("/\n/m","
\n",$fdata);
          if($to_mark) {
            $fdata .= "";
          }
          $row .= $this->wrap_tag($fdata,"td");
        }
        $class = ($selected)?"selectcell":"cell" . ($n % 2);
        $result[] = $this->wrap_tag($row,"tr","class=\"$class\" onClick=\"choose_row(" . $n . ");\"");
        $n++;
      }
    }
    return $result;
  }
  
  function print_data_table() {
    list($server,$user,$password,$database,$table) = $this->get_assoc_values($_POST);
    if($server && $user && $database && $table) {
      if($this->header_result) {
        $table = "";
        if($header = $this->create_table_header()) {
          $table .= $header;
          if($table_rows = $this->create_table_rows()) {
            $table .= join($table_rows,"\n");
            $table = $this->wrap_tag($table,"table","width=100% title=\"Click a record to edit it below\"");
            $wraptable = $this->fetch_value_if_exists($_POST,'Wraptable');
            if(!$wraptable[0]) {
              print "\n";
            }
            print $table;
          }
          else { // no matching records note
            print "
No matching records.  | 
\n"; $also .= "
New $spec record: enter record data, then press \"Accept\" to save your new entry.
\n";
      $also .= "Use \"Tab\", not \"Enter\", to move between fields.
\n";
    }
    else if($this->deleteRecordFlag) { // also carry forward
      $also .= "
Delete: press "; $also .= " "; $also .= " to delete record " . ($record+1) . ", or "; $also .= ""; $also .= "\n"; // this prevents multiple deletes if the user // reloads the page after a delete $_SESSION['arm_delete'] = true; } else { $lines = $this->get_field_lines(); $note = ($lines == 1)?"or \"Enter\" ":""; $item = "Press \"Accept\" $note to commit changes to the database."; $also .= "
$item
";
    }
    if($this->error) {
      $also .= "SQL Error: $this->error
\n";
    }
    if($this->acceptRecordFlag && !$this->changedFlag) {
      $also .= "NOTE: No changes to commit.
\n";
    }
    return $dtable . $also;
  }
  
  function get_database_list() {
    $result = NULL;
    list($server,$user,$password,$database) = $this->get_assoc_values($_POST);
    if($server && $user) {
      $this->connection = mysql_connect($server,$user,$password);
      $this->preserve_error();
      if($this->connection) {
        $result = array();
        $db_list = mysql_list_dbs($this->connection);
        while ($row = mysql_fetch_row($db_list)) {
          $result[] = $row[0];
        }
      }
    }
    return $result;
  }
  
  function get_table_list() {
    $result = NULL;
    list($server,$user,$password,$database,$table) = $this->get_assoc_values($_POST);
    if($server && $user && $database) {
      $this->connection = mysql_connect($server,$user,$password);
      $this->preserve_error();
      if($this->connection) {
        $result = array();
        $table_list = mysql_query("show tables from " . $database,$this->connection);
        while ($row = mysql_fetch_row($table_list)) {
          $result[] = $row[0];
        }
        mysql_free_result($table_list);
      }
    }
    return $result;
  }
  
  function get_data_table($force = false) {
    list($server,$user,$password,$database,$table,$query,$record) = $this->get_assoc_values($_POST);
    list($oserver,$ouser,$opassword,$odatabase,$otable,$oquery,$orecord) = $this->get_assoc_values($this->old_values);
    // preconditions for creating a new data table
    if($server && $user && $database && $table) {
      $no_table = $this->query_result == NULL;
      if($force || $no_table || ($database != $odatabase || $table != $otable || $query != $oquery)) {
        $this->perform_standard_query($server,$user,$password,$database,$table,$query);
        if($this->query_result) {
          // new table, test record value
          $record = $this->set_record_range($this->record_count,$record);
          $_POST['record'] = $record;
        }
      }
    }
  }
  
  function get_field_lines() {
    return $this->fetch_value_if_exists($_POST,'fieldlines',1);
  }
  
  function build_field_lines_control() {
    $lines = $this->get_field_lines();
    $output="";
    $n = 1;
    while($n < 32) {
      $ch = ($n == $lines)?"selected":"";
      $output .= "\n";
      $n <<= 1;
    }
    $title = $this->wrap_tag("Field rows:","td");
    $output = $this->wrap_tag($output,"select","name=\"fieldlines\" title=\"Select number of entry rows\" onChange=\"submit();\"");
    return $title . $this->wrap_tag($output,"td");
  }
  
  function  make_control_tables($add_this) {
    $tables = "";
    $output = $add_this;
    $query = $this->fetch_value_if_exists($_POST,'query','.*');
    if(strlen($query) < 1) {
      $query = '.*';
    }
    $output .= $this->make_text_field("text","Query","query",$query,"Enter a search query (applied to all fields)",18);
    $record = $this->fetch_value_if_exists($_POST,'record');
    $output .= "