/**
  * FormHandler::_getForm()
  *
  * Private: get the form
  *
  * @return string: the generated form
  * @access public
  * @author Teye Heimans
  */
 function _getForm($iDisplayPage = null)
 {
     // is no specific page requested, then get the "current" page
     if (is_null($iDisplayPage)) {
         $iDisplayPage = $this->_curPage;
     }
     // make sure that the requested page cannot be negative
     if ($iDisplayPage <= 0) {
         $iDisplayPage = 1;
     }
     // set the tab indexes for the fields...
     reset($this->_tabindexes);
     ksort($this->_tabindexes);
     while (list($index, $field) = each($this->_tabindexes)) {
         // check if the field exists in the form ?
         if ($this->fieldExists($field)) {
             // set the tab index
             $this->_fields[$field][1]->setTabIndex($index);
         } else {
             trigger_error('Error, try to set the tabindex of an unknown field "' . $field . '"!', E_USER_NOTICE);
         }
     }
     // set the focus to the first (tab index) field if no focus is set yet
     if (is_null($this->_focus)) {
         // are there tab indexes set ?
         if (sizeof($this->_tabindexes) > 0) {
             // set the focus to the element with the lowest positive tab index
             reset($this->_tabindexes);
             while (list($key, $field) = each($this->_tabindexes)) {
                 if ($key >= 0 && $this->setFocus($field)) {
                     break;
                 }
             }
         }
         // no focus set yet. Set the focus to the first field
         if (is_null($this->_focus)) {
             // is it a object (only fields + buttons are objects)
             foreach ($this->_fields as $name => $data) {
                 if (is_object($this->_fields[$name][1]) && $this->setFocus($name)) {
                     break;
                 }
             }
         }
     }
     // initialize the used vars
     $hidden = '';
     $form = '';
     $buffer = array();
     $repeat = true;
     $page = 1;
     // start a new mask loader
     $mask = new MaskLoader();
     // set the seach values
     $mask->setSearch(array('/%field%/', '/%error%/', '/%title%/', '/%seperator%/', '/%name%/', '/%error_id%/', '/%value%/', '/%help%/'));
     // walk trought the fields array
     foreach ($this->_fields as $id => $field) {
         switch ($field[0]) {
             // multiple pages in this form
             case '__PAGE__':
                 # why did we stop at the current page ?
                 //if( $field[1] == $iDisplayPage)
                 //{
                 //    break;
                 //}
                 $page++;
                 break;
                 // hidden field
             // hidden field
             case '__HIDDEN__':
                 $hidden .= $field[1]->getField() . "\n";
                 $hidden .= $field[1]->getError() . "\n";
                 break;
                 // new mask to set
             // new mask to set
             case '__MASK__':
                 if (!isset($this->_mask) || is_null($this->_mask) || $page == $iDisplayPage) {
                     list($this->_mask, $repeat) = $field[1];
                 }
                 break;
                 // insert html or a line
             // insert html or a line
             case '__HTML__':
             case '__LINE__':
                 // but only if the html or line is on this page!
                 if ($page == $iDisplayPage) {
                     $form .= $field[1];
                 }
                 break;
                 // begin new fieldset
             // begin new fieldset
             case '__FIELDSET__':
                 if ($page == $iDisplayPage) {
                     array_unshift($field[1], $form);
                     array_push($buffer, $field[1]);
                     $form = '';
                 }
                 break;
                 // end new fieldset
             // end new fieldset
             case '__FIELDSET-END__':
                 if ($page == $iDisplayPage) {
                     if (sizeof($buffer) > 0) {
                         $d = array_pop($buffer);
                         $form = $d[0] . str_replace(array('%name%', '%caption%', '%content%', '%extra%'), array($d[1], $d[2], $form, $d[3]), FH_FIELDSET_MASK);
                     } else {
                         trigger_error('Fieldset is closed while there is not an open fieldset!');
                     }
                 }
                 break;
                 // default action: field or button
             // default action: field or button
             default:
                 // the fields are not displayed in this page..
                 // set them as hidden fields in the form
                 if ($page != $iDisplayPage) {
                     // put the data of the field in a hidden field
                     // buttons are just ignored
                     if ($field[0] != '__BUTTON__') {
                         // create a new hidden field to set the field's value in
                         $h = new HiddenField($this, $id);
                         $value = $field[1]->getValue();
                         $h->setValue(is_array($value) ? implode(', ', $value) : $value);
                         $hidden .= $h->getField() . "\n";
                         unset($h);
                     }
                 } else {
                     // set the mask which should be filled
                     $mask->setMask($this->_mask);
                     // easy names for the data
                     $title = $field[0];
                     $obj =& $field[1];
                     $name = $id;
                     // buttons don't have a title :-)
                     if ($title == '__BUTTON__') {
                         $title = '';
                     }
                     /**
                      * From this point, we are collecting the data
                      * to fill the mask.
                      */
                     // Get the field or button value
                     // can we get a field ?
                     if (is_object($obj) && method_exists($obj, 'getField')) {
                         $fld = $obj->getField();
                     } else {
                         if (is_object($obj) && method_exists($obj, 'getButton')) {
                             $fld = $obj->getButton();
                         } else {
                             // trigger error ?? (TODO)
                             $fld = '';
                         }
                     }
                     // escape dangerous characters
                     $fld = str_replace('%', '____FH-percent____', $fld);
                     /**
                      * Get the error message for this field
                      */
                     // get possible error message
                     $error = '';
                     if ($this->_displayErrors && is_object($obj) && method_exists($obj, 'getError')) {
                         // custom error message set and we got an error?
                         if (array_key_exists($name, $this->_customMsg) && $obj->getError() != '') {
                             // use the default error mask ?
                             if ($this->_customMsg[$name][1]) {
                                 $error = sprintf(FH_ERROR_MASK, $name, $this->_customMsg[$name][0]);
                             } else {
                                 $error = $this->_customMsg[$name][0];
                             }
                         } else {
                             $error = $obj->getError();
                         }
                     }
                     // save the error messages
                     // (when the user wants to use his own error displayer)
                     $this->errors[$name] = $error;
                     /**
                      * Get the value for of the field
                      */
                     $value = '';
                     if (is_object($obj) && method_exists($obj, 'getValue')) {
                         if (is_array($obj->getValue())) {
                             $value = implode(', ', $obj->getValue());
                         } else {
                             $value = $obj->getValue();
                         }
                     }
                     /**
                      * Get the help string
                      */
                     $help = '';
                     if (array_key_exists($name, $this->_help) && !$this->isViewMode() && !$this->isFieldViewMode($name)) {
                         if (strpos(FH_HELP_MASK, '%s')) {
                             $help = sprintf(FH_HELP_MASK, $this->_helpIcon, $this->_help[$name][0], str_replace('%title%', addslashes(htmlentities($title, null, FH_HTML_ENCODING)), $this->_help[$name][1]));
                         } else {
                             $help = str_replace(array('%helpicon%', '%helptext%', '%helptitle%'), array($this->_helpIcon, $this->_help[$name][0], str_replace('%title%', addslashes(htmlentities($title, null, FH_HTML_ENCODING)), $this->_help[$name][1])), FH_HELP_MASK);
                         }
                     }
                     // give the field a class error added 25-08-2009 in order to give the field the error mask
                     if ($this->isPosted() == true and $error != '') {
                         $fld = $this->parse_error_Fieldstyle($fld);
                     }
                     // now, put all the replace values into an array
                     $replace = array($fld, $error, !empty($title) ? $title : "", !strlen($title) ? '' : ':', !empty($name) ? $name : '', !empty($name) ? 'error_' . $name : '', $value, $help);
                     // fill the mask
                     $html = $mask->fill($replace);
                     // added 07-01-2009 in order to specify which element should get the error class
                     if ($this->isPosted() == true and $error != '') {
                         $html = $this->parse_error_style($html);
                     } else {
                         $html = str_replace('%error_style%', '', $html);
                     }
                     // is the mask filled ?
                     if ($html) {
                         // add it the the form HTML
                         $form .= str_replace('____FH-percent____', '%', $html);
                         // if we don't have to repeat the current mask, use the original
                         if (!$repeat) {
                             $this->_mask = FH_DEFAULT_ROW_MASK;
                         } else {
                             if (is_numeric($repeat)) {
                                 $repeat--;
                             }
                         }
                     }
                 }
                 break;
         }
     }
     // add the page number to the forms HTML
     if ($this->_pageCounter > 1) {
         $h = new HiddenField($this, $this->_name . '_page');
         $h->setValue($iDisplayPage);
         $hidden .= $h->getField() . "\n";
         unset($h);
     }
     // get a possible half filled mask and add it to the html
     $form .= str_replace('____FH-percent____', '%', $mask->fill(null));
     // delete the mask loader
     unset($mask);
     // get occured PHP errors
     $errors = catchErrors();
     $errmsg = '';
     // walk all error messages
     foreach ($errors as $error) {
         switch ($error['no']) {
             case E_USER_WARNING:
                 $type = 'Warning';
                 break;
             case E_USER_NOTICE:
                 $type = 'Notice';
                 break;
             case E_USER_ERROR:
                 $type = 'Error';
                 break;
             default:
                 $type = 'Warning (' . $error['no'] . ')';
                 break;
         }
         $errmsg .= "<b>" . $type . ":</b> " . basename($error['file']) . " at " . $error['line'] . " " . $error['text'] . "<br />\n";
     }
     // set the javascript needed for setting the focus
     if ($this->_focus) {
         $this->_setJS("// set the focus on a specific field \n" . "var elem = document.getElementById ? document.getElementById('" . $this->_focus . "'): document.all? document.all['" . $this->_focus . "']: false; \n" . "if( (elem) && (elem.type != 'hidden')) {\n" . "    try {\n" . "      elem.focus();\n" . "    } catch(e) {}\n" . "}\n", 0, 0);
     }
     // NOTE!!
     // DO NOT REMOVE THIS!
     // You can remove the line "This form is generated by FormHandler" in the config file!!
     // DONT REMOVE THE HTML CODE BELOW! Just set FH_EXPOSE to FALSE!
     $sHeader = $errmsg . "<!--\n" . "  This form is automaticly being generated by FormHandler v3.\n" . "  See for more info: http://www.formhandler.net\n" . "  This credit MUST stay intact for use\n" . "-->\n" . $this->getJavascriptCode(true) . '<form id="' . $this->_name . '" method="post" action="' . htmlentities($this->_action, null, FH_HTML_ENCODING) . '"' . (sizeof($this->_upload) > 0 ? ' enctype="multipart/form-data"' : '') . (!empty($this->_extra) ? " " . $this->_extra : "") . ">\n" . '<ins>' . $hidden . '</ins>' . ($this->_setTable ? sprintf("<table border='%d' cellspacing='%d' cellpadding='%d'%s>\n", $this->_tableSettings['border'], $this->_tableSettings['cellspacing'], $this->_tableSettings['cellpadding'], (!empty($this->_tableSettings['width']) ? " width='" . $this->_tableSettings['width'] . "'" : "") . ' ' . $this->_tableSettings['extra']) : '');
     $sFooter = ($this->_setTable ? "\n</table>\n" : '') . (FH_EXPOSE ? "<p><span style='font-family:tahoma;font-size:10px;color:#B5B5B5;font-weight:normal;'>" . 'This form is generated by </span><a href="http://www.formhandler.net" >' . '<span style="font-family:Tahoma;font-size:10px;color:#B5B5B5;"><strong>FormHandler</strong></span></a></p>' . "\n" : '') . "</form>\n" . "<!--\n" . "  This form is automaticly being generated by FormHandler v3.\n" . "  See for more info: http://www.formhandler.net\n" . "-->" . $this->getJavascriptCode(false);
     $search = array('%header%', '%footer%');
     $replace = array($sHeader, $sFooter);
     $new_form = str_replace($search, $replace, $form, $num_replaced);
     if ($num_replaced === 2) {
         return $new_form;
     } else {
         return $sHeader . $form . $sFooter;
     }
 }
 function FlushForm($returnTheForm = false)
 {
     $handle = null;
     // output handler
     // is there a oncorrect or onsaved function ?
     if (!$this->OnCorrect && !$this->OnSaved) {
         $this->error("You didn't specify a 'commit after form' function!", E_USER_ERROR, __FILE__, __LINE__);
     } elseif (!$this->OnCorrect && !$this->useDB) {
         $this->error("You are using the function OnSaved but you don't use the database option! Use OnCorrect instead!", E_USER_ERROR, __FILE__, __LINE__);
     }
     // errors welke zijn voorgekomen in een var zetten
     $errors =& catchErrors();
     $errmsg = '';
     foreach ($errors as $error) {
         $errmsg .= "<b>Error:</b> (" . basename($error['err_file']) . ":" . $error['err_line'] . ") " . $error['err_text'] . "<br />\n";
     }
     // look if there are class errors
     if ($this->classError) {
         $this->form = "<h3>Error!</h3>\n" . $this->classError;
         $handle = false;
         // is the form a editform ? (if so, is the user authorised??)
     } elseif ($this->editForm && !$this->permitEdit) {
         $this->form = "<h3>Error!</h3>\n" . $this->_edit . "<br /><br /><a href='javascript:history.back(1)'>" . $this->_back . "</a>\n";
         $handle = false;
     } else {
         // if the form is posted and there are no errors
         if (!$this->formErrors && $this->posted) {
             // is a confirmation needed and not posted yet ?
             if (is_array($this->confirm) && $this->Value("__confirmation__") == '') {
                 return $this->ConfirmForm($returnTheForm);
             }
             // close all borders
             while ($this->fieldSetCounter > 0) {
                 $this->BorderStop();
             }
             // look if the fieldnames are known, otherwise, get them...
             if (!count($this->dbFields) && $this->useDB) {
                 $this->getTableFields();
             }
             $fieldValues = array();
             // before we generate a query, make an array with the fields and there values
             foreach ($this->fieldNames as $field) {
                 if (!empty($field) && !in_array($field, $this->ignoreFields)) {
                     $fieldValues[$field] = $this->value($field);
                 }
             }
             // save the filename, but do not upload yet.. first save data..
             foreach ($this->uploadFields as $field => $config) {
                 if ($fn = $this->GetFilename($this->Value($field), $config)) {
                     $this->AddValue($field, $fn);
                 } else {
                     $this->IgnoreFields[] = $field;
                 }
             }
             // but the values enterd by the user (by using addvalue) into the array
             foreach ($this->addValues as $field => $value) {
                 $fieldValues[$field] = $value;
             }
             // call the oncorrect function
             if ($this->OnCorrect) {
                 if (!$this->OnSaved) {
                     $this->uploadFiles($fieldValues);
                 }
                 $handle = $this->callUserFunction($this->OnCorrect, $fieldValues);
             }
             // again, put the values enterd by the user (by using addvalue) into the array
             // (it's possible the user entered some values in the oncorrect function)
             foreach ($this->addValues as $field => $value) {
                 $fieldValues[$field] = $value;
             }
             // make the values ready for the query
             if (is_array($fieldValues)) {
                 foreach ($fieldValues as $field => $value) {
                     // if the field is not an upload field ... (the value can be an manual entered value!)
                     if (!$this->arrayKeyExists($field, $this->uploadFields) || $this->arrayKeyExists($field, $this->addValues)) {
                         $value = is_array($value) ? implode(", ", $value) : $value;
                         $queryValues[$field] = !in_array($field, $this->SQLFields) ? "'" . mysql_escape_string($value) . "'" : $value;
                     }
                 }
             }
             // make the query (update or insert) but check if there are values
             if ($this->editForm && isset($queryValues)) {
                 // make the update query
                 $query = "UPDATE {$this->dbTable} SET \n";
                 foreach ($queryValues as $field => $value) {
                     // check if the field exists in the table
                     if ($this->arrayKeyExists($field, $this->dbFields)) {
                         $query .= "{$field} = {$value}, \n";
                     }
                 }
                 // remove the last ", \n" ans put the WHERE part at the end
                 $query = substr($query, 0, -3) . " WHERE " . $this->getWhereClause();
             } elseif (isset($queryValues)) {
                 $fields = '';
                 $values = '';
                 foreach ($queryValues as $field => $value) {
                     // check if the field exists in the table
                     if ($this->arrayKeyExists($field, $this->dbFields)) {
                         $fields .= "{$field}, \n";
                         $values .= "{$value}, \n";
                     }
                 }
                 if (!strlen($fields) && !strlen($values)) {
                     $query = false;
                 } else {
                     // generate the query
                     $query = "INSERT INTO {$this->dbTable} (\n" . substr($fields, 0, -3) . ") VALUES (\n" . substr($values, 0, -3) . ")";
                 }
             } else {
                 $query = false;
             }
             // run the query
             //die($query); // <-- for debugging
             if ($query) {
                 $sql = $this->query($query, __FILE__, __LINE__);
             }
             // get the record id
             $this->recordId = $this->editForm ? $this->editId[0] : (isset($query) && $this->useDB ? mysql_insert_id() : "Database functions are not used...");
             // run the onSaved function
             if ($this->OnSaved) {
                 $this->uploadFiles($fieldValues);
                 if ($query === false || !$this->useDB) {
                     $this->error("You are using the function OnSaved but you don't use the database option! Use OnCorrect instead!", E_USER_WARNING, __FILE__, __LINE__);
                 } else {
                     $handle = $this->callUserFunction($this->OnSaved, $this->recordId, $fieldValues);
                 }
             }
             // if there are errors or the form isnt posted yet, show the form
         } else {
             $handle = false;
         }
         // get the form and table tags...
         $this->form = $this->getForm($this->form);
         // set the forcus
         if ($this->focusField) {
             $field = str_replace('[]', '', $this->focusField);
             if (in_array($field, $this->fieldNames)) {
                 $this->form .= "<script type=\"text/javascript\">\n" . "<!-- // hide javascript for older browsers \n" . "document.forms['{$this->formName}'].elements['{$field}'].focus();\n" . " //-->\n" . "</script>\n";
             } else {
                 $this->error("Can't put focus on the field {$field} because it's unknown!", E_USER_WARNING, __FILE__, __LINE__);
             }
         }
         // javascript for the listfields
         $javascript = '';
         if (count($this->ListFields) > 0) {
             $javascript .= "function changeValue(prefix, install) {\n" . "    // set the fields\n" . "    var FromField = document.forms['{$this->formName}'].elements[prefix+(install?\"_ListOff\":\"_ListOn\")];\n" . "    var ToField   = document.forms['{$this->formName}'].elements[prefix+(install?\"_ListOn\":\"_ListOff\")];\n\n" . "    // is a value selected?\n" . "    if(FromField.value != \"\") {\n" . "        // get the number of values from the selected list\n" . "        var len = ToField.options.length;\n\n" . "        // remove empty options\n" . "        for(i = 0; i < len; i++ ) {\n" . "            if(ToField.options[i].value == '') ToField.options[i] = null\n" . "         }\n" . "        // add the new option\n" . "        len = ToField.options.length;\n" . "        ToField.options[len] = new Option(FromField.options[FromField.selectedIndex].text);\n" . "        ToField.options[len].value = FromField.options[FromField.selectedIndex].value;\n" . "        ToField.options[len].selected = true;\n\n" . "        // delete the option from the 'old' list\n" . "        FromField.options[FromField.selectedIndex] = null;\n" . "        FromField.focus();\n" . "    }\n\n" . "    // update the hidden field which contains the selected values\n" . "    var InstalledVars = \" \";\n" . "    var Installed = document.forms['{$this->formName}'].elements[prefix+'_ListOn'];\n\n" . "    for(i = 0; i < Installed.options.length; i++) {\n" . "        InstalledVars += Installed.options[i].value + \", \";\n" . "    }\n" . "    document.forms['{$this->formName}'].elements[prefix+'_Value'].value = InstalledVars;\n" . "}\n";
         }
         // if a upload field is used, put the javascript in the form
         if (count($this->uploadFields)) {
             $javascript .= "function checkUpload(elem, ext) {\n" . "    var types = ext.split(' ');\n" . "    var fp = elem.value.split('.');\n" . "    var extension = fp[fp.length-1].toLowerCase();\n" . "    for(var i = 0; i < types.length; i++ ) {\n" . "        if(types[i] == extension) return true;\n" . "    }\n" . "    var message = \"" . HTMLSpecialChars($this->_uploadType) . "\"\n" . "    message = message.replace('%s', ext);\n" . "    alert(message);\n" . "    return false;\n" . "}\n";
         }
         // if isset some javascript, put it into these tags (javascript open and close tags)
         $javascript = !empty($javascript) ? "\n" . "<!-- \n" . "  NOTE: This form is automaticly generated by FormHandler.\n" . "  See for more info: http://www.FormHandler.nl\n" . "-->\n" . "<!-- required javascript for the form -->\n" . "<script type=\"text/javascript\">\n" . "<!-- // hide javascript for older browsers \n" . $javascript . " //-->\n" . "</script>\n" . "<!--  /required javascript for the form -->\n\n" : "";
     }
     // reset the original error_handler
     if (!is_null($this->orgErrorHandler)) {
         set_error_handler($this->orgErrorHandler);
     }
     // return or print the form...
     if (is_null($handle)) {
         $handle = true;
     }
     if (!$handle) {
         if (!isset($javascript)) {
             $javascript = '';
         }
         if ($returnTheForm) {
             return $errmsg . $javascript . $this->form;
         } else {
             echo $errmsg . $javascript . $this->form;
         }
     } else {
         $handle = !is_string($handle) ? '' : $handle;
         if ($returnTheForm) {
             return $errmsg . $handle;
         } else {
             echo $errmsg . $handle;
         }
     }
 }