Beispiel #1
0
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     $reloadPath = self::get_reload_path();
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\">\n";
     $r .= $auth['write'];
     data_entry_helper::$entity_to_load = array();
     if (!empty($_GET['termlists_term_id'])) {
         data_entry_helper::load_existing_record($auth['read'], 'termlists_term', $_GET['termlists_term_id']);
         // map fields to their appropriate supermodels
         data_entry_helper::$entity_to_load['term:term'] = data_entry_helper::$entity_to_load['termlists_term:term'];
         data_entry_helper::$entity_to_load['term:id'] = data_entry_helper::$entity_to_load['termlists_term:term_id'];
         data_entry_helper::$entity_to_load['meaning:id'] = data_entry_helper::$entity_to_load['termlists_term:meaning_id'];
         if (function_exists('hostsite_set_page_title')) {
             hostsite_set_page_title(lang::get('Edit {1}', data_entry_helper::$entity_to_load['term:term']));
         }
     }
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'website_id', 'default' => $args['website_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:id'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:termlist_id', 'default' => $args['termlist_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'termlists_term:preferred', 'default' => 't'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'term:id'));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'term:language_id', 'default' => $args['language_id']));
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'meaning:id'));
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $r .= data_entry_helper::text_input(array('label' => lang::get('Term'), 'fieldname' => 'term:term', 'helpText' => lang::get('Please provide the term'), 'validation' => array('required'), 'class' => 'control-width-5'));
     $r .= "<input type=\"submit\" name=\"form-submit\" id=\"delete\" value=\"Delete\" />\n";
     $r .= "<input type=\"submit\" name=\"form-submit\" value=\"Save\" />\n";
     $r .= '<form>';
     self::set_breadcrumb($args);
     return $r;
 }
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     data_entry_helper::enable_tabs(array('divId' => 'controls'));
     $r = "<form method=\"post\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $r .= data_entry_helper::get_auth($args['website_id'], $args['password']);
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     $r .= "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" id=\"record_status\" name=\"record_status\" value=\"C\" />\n";
     $r .= "<div id=\"controls\">\n";
     // Create a list which jQuery can parse to create the tabs.
     $r .= "<ul>\r\n      <li><a href=\"#recorder\"><span>Recorder</span></a></li>\r\n      <li><a href=\"#site\"><span>Site</span></a></li>\r\n      <li><a href=\"#species_tab_1\"><span>" . $args['tab_title_1'] . "</span></a></li>\n";
     if ($args['list_id_2']) {
         $r .= "<li><a href=\"#species_tab_2\"><span>" . $args['tab_title_2'] . "</span></a></li>\n";
     }
     if ($args['list_id_3']) {
         $r .= "<li><a href=\"#species_tab_3\"><span>" . $args['tab_title_3'] . "</span></a></li>\n";
     }
     if ($args['list_id_4']) {
         $r .= "<li><a href=\"#species_tab_4\"><span>" . $args['tab_title_4'] . "</span></a></li>\n";
     }
     $r .= "</ul>\n";
     $r .= "<div id=\"recorder\">\n";
     $r .= data_entry_helper::select(array('label' => 'Title', 'fieldname' => 'smpAttr:5', 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $readAuth + array('termlist_external_key' => 'indicia:titles')));
     $r .= data_entry_helper::text_input(array('label' => 'First name', 'fieldname' => 'smpAttr:6'));
     $r .= data_entry_helper::text_input(array('label' => 'Last name', 'fieldname' => 'smpAttr:7'));
     $r .= data_entry_helper::text_input(array('label' => 'Email', 'fieldname' => 'smpAttr:8'));
     // Postcode before address since entering the postcode auto-populates part of the address.
     $r .= data_entry_helper::postcode_textbox(array('label' => 'Postcode', 'fieldname' => 'smpAttr:10', 'linkedAddressBoxId' => 'address', 'hiddenFields' => false));
     $r .= data_entry_helper::textarea(array('label' => 'Address', 'fieldname' => 'smpAttr:9', 'id' => 'address'));
     $r .= "</div>\n";
     $r .= "<div id=\"site\">\n";
     $r .= data_entry_helper::map();
     $r .= data_entry_helper::date_picker(array('label' => 'Date', 'fieldname' => 'sample:date'));
     $r .= "</div>\n";
     $r .= "<div id=\"species_tab_1\">\n";
     $species_list_args = array('label' => 'Species', 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $readAuth + array('taxon_list_id' => $args['list_id_1']));
     $r .= data_entry_helper::species_checklist($species_list_args);
     $r .= "</div>\n";
     $r .= "</div>\n";
     $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     $r .= "</form>";
     return $r;
 }
 protected static function get_control_locationcode($auth, $args, $tabalias, $options)
 {
     return data_entry_helper::text_input(array_merge(array('label' => lang::get('LANG_Location_Code'), 'fieldname' => 'location:code', 'class' => 'control-width-5'), $options));
 }
echo data_entry_helper::text_input(array('label' => 'Period Start', 'fieldname' => 'summariser_definition:period_start', 'default' => html::initial_value($values, 'summariser_definition:period_start'), 'helpText' => 'Define the first day of each period. There are 2 options.<br/>' . "&nbsp;&nbsp;<strong>weekday=&lt;n&gt;</strong> where <strong>&lt;n&gt;</strong> is a number between 1 (for Monday) and 7 (for Sunday).<br/>" . "&nbsp;&nbsp;<strong>date=MMM/DD</strong> where <strong>MMM/DD</strong> is a month/day combination: e.g. choosing Apr-1 will start each week on the day of the week on which the 1st of April occurs.<br/>", 'validation' => 'required'));
echo data_entry_helper::text_input(array('label' => 'Period One Contains', 'fieldname' => 'summariser_definition:period_one_contains', 'default' => html::initial_value($values, 'summariser_definition:period_one_contains'), 'helpText' => 'Calculate week one as the week containing this date: value should be in the format <strong>MMM/DD</strong>, which is a month/day combination: e.g. choosing Apr-1 will mean week one contains the date of the 1st of April. Default is the Jan-01', 'validation' => 'required'));
echo data_entry_helper::select(array('label' => 'Attribute to Sum', 'fieldname' => 'summariser_definition:occurrence_attribute_id', 'lookupValues' => $other_data['occAttrs'], 'default' => html::initial_value($values, 'summariser_definition:occurrence_attribute_id'), 'helpText' => 'The occurrence attribute which is used as the count associated with the occurrence. If not provided then each occurrence has a count of one.'));
echo data_entry_helper::checkbox(array('label' => 'Calculate Estimates', 'fieldname' => 'summariser_definition:calculate_estimates', 'default' => html::initial_value($values, 'summariser_definition:calculate_estimates')));
?>
<fieldset><legend>Data Handling</legend>
<?php 
echo data_entry_helper::select(array('label' => 'Summary Data Combination method', 'fieldname' => 'summariser_definition:data_combination_method', 'lookupValues' => array('A' => 'Add all occurrences together', 'M' => 'Choose the value from the sample with the greatest count', 'L' => 'Average over all samples for that location during that period'), 'default' => html::initial_value($values, 'summariser_definition:data_combination_method'), 'helpText' => 'When data is aggregated for a location/period combination, this determines how.'));
echo data_entry_helper::select(array('label' => 'Data Rounding', 'fieldname' => 'summariser_definition:data_rounding_method', 'lookupValues' => array('N' => 'To the nearest integer, .5 rounds up', 'U' => 'Up: To the integer greater than or equal to the value', 'D' => 'Down: To the integer less than or equal to the value', 'X' => 'None (may result in non-integer values)'), 'default' => html::initial_value($values, 'summariser_definition:data_rounding_method'), 'helpText' => 'When data is averaged, this determines what rounding is carried out. Note that anything between 0 and 1 will be rounded up to 1.'));
?>
</fieldset><fieldset><legend>Estimate Generation</legend>
<p>Only one interpolation option (linear) available at the moment.</p>
<?php 
// Only one interpolation option at the moment. This may change in future. Keep hidden control until that point.
// 'L' = 'Linear interpolation'
echo data_entry_helper::hidden_text(array('fieldname' => 'summariser_definition:interpolation', 'default' => 'L'));
echo data_entry_helper::text_input(array('label' => 'Season Limits', 'fieldname' => 'summariser_definition:season_limits', 'default' => html::initial_value($values, 'summariser_definition:season_limits'), 'helpText' => 'This is a comma separated pair of the week numbers for the start and end of the season. When provided, and data is not entered for these weeks, the value is taken as zero, irrespective of the First/Last value processing. First/Last value processing is not carried out outwith these weeks.'));
echo data_entry_helper::select(array('label' => 'First Value Processing', 'fieldname' => 'summariser_definition:first_value', 'lookupValues' => array('X' => 'No special processing', 'H' => 'The entry for the previous week is half the entered value'), 'default' => html::initial_value($values, 'summariser_definition:first_value'), 'helpText' => 'When encountering the first entered value, this determines what happens.'));
echo data_entry_helper::select(array('label' => 'Last Value Processing', 'fieldname' => 'summariser_definition:last_value', 'lookupValues' => array('X' => 'No special processing', 'H' => 'The entry for the next week is half the entered value'), 'default' => html::initial_value($values, 'summariser_definition:last_value'), 'helpText' => 'When encountering the last entered value, this determines what happens.'));
?>
</fieldset>
<?php 
echo $metadata;
echo html::form_buttons($existing, false, false);
data_entry_helper::$dumped_resources[] = 'jquery';
data_entry_helper::$dumped_resources[] = 'jquery_ui';
data_entry_helper::$dumped_resources[] = 'fancybox';
echo data_entry_helper::dump_javascript();
?>
</fieldset>
</form>
Beispiel #5
0
function iform_mnhnl_recordernamesControl($node, $auth, $args, $tabalias, $options)
{
    $values = array();
    $userlist = array();
    $results = db_query('SELECT uid, name FROM {users}');
    while ($result = db_fetch_object($results)) {
        $account = user_load($result->uid);
        if ($account->uid != 1 && user_access($args['permission_name'], $account)) {
            $userlist[$result->name] = $result->name;
        }
    }
    if (isset(data_entry_helper::$entity_to_load['sample:recorder_names'])) {
        if (!is_array(data_entry_helper::$entity_to_load['sample:recorder_names'])) {
            $values = explode("\r\n", data_entry_helper::$entity_to_load['sample:recorder_names']);
        } else {
            $values = data_entry_helper::$entity_to_load['sample:recorder_names'];
        }
    }
    foreach ($values as $value) {
        // ensure all existing entries are in list.
        $userlist[$value] = $value;
    }
    if (isset($options['disabled']) && $options['disabled']) {
        return data_entry_helper::text_input(array_merge(array('id' => 'sample:recorder_names', 'fieldname' => 'sample:recorder_names[]', 'label' => lang::get('Recorder names'), 'default' => implode(', ', $values)), $options));
    }
    $r = data_entry_helper::listbox(array_merge(array('id' => 'sample:recorder_names', 'fieldname' => 'sample:recorder_names[]', 'label' => lang::get('Recorder names'), 'size' => 6, 'multiselect' => true, 'default' => $values, 'lookupValues' => $userlist, 'validation' => array('required')), $options));
    return $r . "<span id='RecorderInstructions'>" . lang::get('LANG_RecorderInstructions') . "</span><br />";
}
Beispiel #6
0
 /**
  * Outputs a pair of linked selects, for picking a prebuilt form from the library. The first select is for picking a form 
  * category and the second select is populated by AJAX for picking the actual form.
  * @param array $options Options array with the following possibilities:<ul>
  * <li><b>form</b><br/>
  * Optional. The name of the form to select as a default value.</li>
  * <li><b>includeOutputDiv</b><br/>
  * Set to true to generate a div after the controls which will receive the form parameter
  * controls when a form is selected.</li>
  * <li><b>needWebsiteInputs</b><br/>
  * Defaults to false. In this state, the website ID and password controls are not displayed
  * when both the values are already specified, though hidden inputs are put into the form.
  * When set to true, the website ID and password input controls are always included in the form output.
  * </li>
  * </ul>
  */
 public static function prebuilt_form_picker($options)
 {
     require_once 'data_entry_helper.php';
     form_helper::add_resource('jquery_ui');
     $path = dirname($_SERVER['SCRIPT_FILENAME']) . '/' . self::relative_client_helper_path();
     $r = '';
     if (!($dir = opendir($path . 'prebuilt_forms/'))) {
         throw new Exception('Cannot open path to prebuilt form library.');
     }
     while (false !== ($file = readdir($dir))) {
         $parts = explode('.', $file);
         if ($file != "." && $file != ".." && strtolower($parts[count($parts) - 1]) == 'php') {
             require_once $path . 'prebuilt_forms/' . $file;
             $file_tokens = explode('.', $file);
             ob_start();
             if (is_callable(array('iform_' . $file_tokens[0], 'get_' . $file_tokens[0] . '_definition'))) {
                 $definition = call_user_func(array('iform_' . $file_tokens[0], 'get_' . $file_tokens[0] . '_definition'));
                 $definition['title'] = lang::get($definition['title']);
                 $forms[$definition['category']][$file_tokens[0]] = $definition;
                 if (isset($options['form']) && $file_tokens[0] == $options['form']) {
                     $defaultCategory = $definition['category'];
                 }
             } elseif (is_callable(array('iform_' . $file_tokens[0], 'get_title'))) {
                 $title = call_user_func(array('iform_' . $file_tokens[0], 'get_title'));
                 $forms['Miscellaneous'][$file_tokens[0]] = array('title' => $title);
                 if (isset($options['form']) && $file_tokens[0] == $options['form']) {
                     $defaultCategory = 'Miscellaneous';
                 }
             }
             ob_end_clean();
         }
     }
     if (isset($defaultCategory)) {
         $availableForms = array();
         foreach ($forms[$defaultCategory] as $form => $def) {
             $availableForms[$form] = $def['title'];
         }
     } else {
         $defaultCategory = '';
         $availableForms = array('' => '&lt;Please select a category first&gt;');
     }
     closedir($dir);
     // makes an assoc array from the categories.
     $categories = array_merge(array('' => '&lt;Please select&gt;'), array_combine(array_keys($forms), array_keys($forms)));
     // translate categories
     foreach ($categories as $key => &$value) {
         $value = lang::get($value);
     }
     asort($categories);
     if (isset($options['needWebsiteInputs']) && !$options['needWebsiteInputs'] && !empty($options['website_id']) && !empty($options['password'])) {
         $r .= '<input type="hidden" id="website_id" name="website_id" value="' . $options['website_id'] . '">';
         $r .= '<input type="hidden" id="password" name="password" value="' . $options['password'] . '">';
     } else {
         $r .= data_entry_helper::text_input(array('label' => lang::get('Website ID'), 'fieldname' => 'website_id', 'helpText' => lang::get('Enter the ID of the website record on the Warehouse you are using.'), 'default' => isset($options['website_id']) ? $options['website_id'] : ''));
         $r .= data_entry_helper::text_input(array('label' => lang::get('Password'), 'fieldname' => 'password', 'helpText' => lang::get('Enter the password for the website record on the Warehouse you are using.'), 'default' => isset($options['password']) ? $options['password'] : ''));
     }
     $r .= data_entry_helper::select(array('id' => 'form-category-picker', 'label' => lang::get('Select Form Category'), 'helpText' => lang::get('Select the form category pick a form from.'), 'lookupValues' => $categories, 'default' => $defaultCategory));
     $r .= data_entry_helper::select(array('id' => 'form-picker', 'fieldname' => 'iform', 'label' => lang::get('Select Form'), 'helpText' => lang::get('Select the Indicia form you want to use.'), 'lookupValues' => $availableForms, 'default' => isset($options['form']) ? $options['form'] : ''));
     // div for the form instructions
     $details = '';
     if (isset($options['form'])) {
         if (isset($forms[$defaultCategory][$options['form']]['description'])) {
             $details .= '<p>' . $forms[$defaultCategory][$options['form']]['description'] . '</p>';
         }
         if (isset($forms[$defaultCategory][$options['form']]['helpLink'])) {
             $details .= '<p><a href="' . $forms[$defaultCategory][$options['form']]['helpLink'] . '">Find out more...</a></p>';
         }
         if ($details !== '') {
             $details = "<div class=\"ui-state-highlight ui-corner-all page-notice\">{$details}</div>";
         }
     }
     $r .= "<div id=\"form-def\">{$details}</div>\n";
     $r .= '<input type="button" value="' . lang::get('Load Settings Form') . '" id="load-params" disabled="disabled" />';
     if (isset($options['includeOutputDivs']) && $options['includeOutputDivs']) {
         $r .= '<div id="form-params"></div>';
     }
     self::add_form_picker_js($forms);
     return $r;
 }
 /** 
  * Get the location name control.
  */
 private static function get_control_locationname($auth, $args, $tabalias, $options)
 {
     return data_entry_helper::text_input(array_merge(array('label' => lang::get('LANG_Location_Name'), 'fieldname' => 'sample:location_name', 'class' => 'control-width-5'), $options));
 }
    /**
     * Return the generated form output.
     * @return Form HTML.
     */
    public static function get_form($args, $node)
    {
        global $user;
        // There is a language entry in the args parameter list: this is derived from the $language DRUPAL global.
        // It holds the 2 letter code, used to pick the language file from the lang subdirectory of prebuilt_forms.
        // There should be no explicitly output text in this file.
        // We must translate any field names and ensure that the termlists and taxonlists use the correct language.
        // For attributes, the caption is automatically translated by data_entry_helper.
        $logged_in = $user->uid > 0;
        $uid = $user->uid;
        $email = $user->mail;
        $username = $user->name;
        if (!user_access('IForm n' . $node->nid . ' access')) {
            return "<p>" . lang::get('LANG_Insufficient_Privileges') . "</p>";
        }
        $r = '';
        // Get authorisation tokens to update and read from the Warehouse.
        $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
        $svcUrl = data_entry_helper::$base_url . '/index.php/services';
        $language = iform_lang_iso_639_2($args['language']);
        drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
        data_entry_helper::link_default_stylesheet();
        data_entry_helper::add_resource('jquery_ui');
        if ($args['language'] != 'en') {
            data_entry_helper::add_resource('jquery_ui_' . $args['language']);
        }
        data_entry_helper::enable_validation('new-comments-form');
        // don't care about ID itself, just want resources
        $occID = '';
        $smpID = '';
        $userID = '';
        $mode = 'FILTER';
        if (array_key_exists('insect_id', $_GET)) {
            $occID = $_GET['insect_id'];
            $mode = 'INSECT';
        } else {
            if (array_key_exists('insect', $_GET)) {
                $occID = $_GET['insect'];
                $mode = 'INSECT';
            } else {
                if (array_key_exists('flower_id', $_GET)) {
                    $occID = $_GET['flower_id'];
                    $mode = 'FLOWER';
                } else {
                    if (array_key_exists('flower', $_GET)) {
                        $occID = $_GET['flower'];
                        $mode = 'FLOWER';
                    } else {
                        if (array_key_exists('collection_id', $_GET)) {
                            $smpID = $_GET['collection_id'];
                            $mode = 'COLLECTION';
                        } else {
                            if (array_key_exists('collection', $_GET)) {
                                $smpID = $_GET['collection'];
                                $mode = 'COLLECTION';
                            } else {
                                if (array_key_exists('user_id', $_GET)) {
                                    $userID = $_GET['user_id'];
                                } else {
                                    if (array_key_exists('user', $_GET)) {
                                        $userID = $_GET['user'];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        //	data_entry_helper::enable_validation('cc-1-collection-details'); // don't care about ID itself, just want resources
        // The only things that will be editable after the collection is saved will be the identifiaction of the flower/insects.
        // no id - just getting the attributes, rest will be filled in using AJAX
        $sample_attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $occurrence_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $location_attributes = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $defAttrOptions = array('extraParams' => $readAuth + array('orderby' => 'id'), 'lookUpListCtrl' => 'checkbox_group', 'lookUpKey' => 'meaning_id', 'booleanCtrl' => 'checkbox_group', 'sep' => ' &nbsp; ', 'language' => $language, 'suffixTemplate' => 'nosuffix', 'default' => '-1');
        // note we have to proxy the post. Every time a write transaction is carried out, the write nonce is trashed.
        // For security reasons we don't want to give the user the ability to generate their own nonce, so we use
        // the fact that the user is logged in to drupal as the main authentication/authorisation/identification
        // process for the user. The proxy also packages the post into the correct format
        // the controls for the filter include all taxa, not just the ones allowed for data entry, as does the one for checking the tool, just to be on the safe side.
        $flower_ctrl_args = array('label' => lang::get('LANG_Flower_Species'), 'fieldname' => 'flower:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order'), 'suffixTemplate' => 'nosuffix');
        $focus_flower_ctrl_args = $flower_ctrl_args;
        $focus_flower_ctrl_args['fieldname'] = 'determination:taxa_taxon_list_id';
        $focus_flower_ctrl_args['extraParams'] = $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order', 'allow_data_entry' => 't');
        $insect_ctrl_args = array('label' => lang::get('LANG_Insect_Species'), 'fieldname' => 'insect:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order'), 'suffixTemplate' => 'nosuffix');
        $focus_insect_ctrl_args = $insect_ctrl_args;
        $focus_insect_ctrl_args['fieldname'] = 'determination:taxa_taxon_list_id';
        $focus_insect_ctrl_args['extraParams'] = $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'view' => 'detail', 'orderby' => 'taxonomic_sort_order', 'allow_data_entry' => 't');
        $options = iform_map_get_map_options($args, $readAuth);
        $olOptions = iform_map_get_ol_options($args);
        // The maps internal projection will be left at its default of 900913.
        $options['initialFeatureWkt'] = null;
        $options['proxy'] = '';
        $options['suffixTemplate'] = 'nosuffix';
        if (lang::get('msgGeorefSelectPlace') != 'msgGeorefSelectPlace') {
            $options['msgGeorefSelectPlace'] = lang::get('msgGeorefSelectPlace');
        }
        if (lang::get('msgGeorefNothingFound') != 'msgGeorefNothingFound') {
            $options['msgGeorefNothingFound'] = lang::get('msgGeorefNothingFound');
        }
        $options2 = $options;
        $options['searchLayer'] = 'true';
        $options['editLayer'] = 'false';
        $options['layers'] = array('polygonLayer');
        $options2['divId'] = "map2";
        $options2['layers'] = array('locationLayer');
        $options2['height'] = $args['2nd_map_height'];
        data_entry_helper::$javascript .= "var flowerTaxa = [";
        $extraParams = $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'view' => 'list');
        $species_data_def = array('table' => 'taxa_taxon_list', 'extraParams' => $extraParams);
        $taxa = data_entry_helper::get_population_data($species_data_def);
        $first = true;
        foreach ($taxa as $taxon) {
            data_entry_helper::$javascript .= ($first ? '' : ',') . "{id: " . $taxon['id'] . ", taxon: \"" . htmlSpecialChars($taxon['taxon']) . "\"}\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "];\nvar insectTaxa = [";
        $extraParams['taxon_list_id'] = $args['insect_list_id'];
        $species_data_def['extraParams'] = $extraParams;
        $taxa = data_entry_helper::get_population_data($species_data_def);
        $first = true;
        foreach ($taxa as $taxon) {
            data_entry_helper::$javascript .= ($first ? '' : ',') . "{id: " . $taxon['id'] . ", taxon: \"" . htmlSpecialChars($taxon['taxon']) . "\"}\n";
            $first = false;
        }
        data_entry_helper::$javascript .= "];";
        // TBD Breadcrumb
        $r .= '<h1 id="poll-banner">' . lang::get('LANG_Main_Title') . '</h1>
<div id="refresh-message" style="display:none" ><p>' . lang::get('LANG_Please_Refresh_Page') . '</p></div>
<div id="filter" class="ui-accordion ui-widget ui-helper-reset">
	<div id="filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-accordion-content-active ui-corner-top">
	  	<div id="results-collections-title">
	  		<span>' . lang::get('LANG_Filter_Title') . '</span>
    	</div>
	</div>';
        if (user_access('IForm n' . $node->nid . ' save filter')) {
            $r .= '<div id="filter-save" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active"><div id="gallery-filter-retrieve-wrapper">
<div id="gallery-filter-retrieve-image"><img
src="/' . path_to_theme() . '/css/gallery_filter.png" 
alt="Mes filtres" title="Mes filtres" /></div> <div id="gallery-filter-retrieve"></div>
</div>
   <input value="' . lang::get('LANG_Enter_Filter_Name') . '" type="text" id="gallery-filter-save-name" /><input value="' . lang::get('LANG_Save_Filter_Button') . '" type="button" id="gallery-filter-save-button" /></div>';
        }
        $r .= '<div id="filter-spec" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	  <div class="ui-accordion ui-widget ui-helper-reset">
		<div id="name-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-name-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
	  		<div id="reset-name-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="general-filter-title">
		  		<span>' . lang::get('LANG_Name_Filter_Title') . '</span>
      		</div>
		</div>
	    <div id="name-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
	        ' . data_entry_helper::text_input(array('label' => lang::get('LANG_Name'), 'fieldname' => 'username', 'suffixTemplate' => 'nosuffix')) . '
  		</div>
		<div id="date-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-date-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
	  		<div id="reset-date-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="general-filter-title">
		  		<span>' . lang::get('LANG_Date_Filter_Title') . '</span>
      		</div>
		</div>
	    <div id="date-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
        	<label for="start_date" >' . lang::get('LANG_Created_Between') . ':</label>
  			<input type="text" size="10" id="start_date" name="start_date" value="' . lang::get('click here') . '" />
  			<input type="hidden" id="real_start_date" name="real_start_date" />
  			<label for="end_date" >' . lang::get('LANG_And') . ':</label>
  			<input type="text" size="10" id="end_date" name="end_date" value="' . lang::get('click here') . '" />
  			<input type="hidden" id="real_end_date" name="real_end_date" />
  		</div>
  		<div id="flower-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-flower-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
	  		<div id="reset-flower-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="flower-filter-title">
		  		<span>' . lang::get('LANG_Flower_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="flower-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
		  ' . data_entry_helper::select($flower_ctrl_args) . '
 		  <input type="text" name="flower:taxon_extra_info" class="taxon-info" value="' . lang::get('LANG_More_Precise') . '"
	 		onclick="if(this.value==\'' . lang::get('LANG_More_Precise') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
            onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_More_Precise') . '\'; this.style.color=\'#555\'}" />
		  ' . str_replace("\n", "", data_entry_helper::outputAttribute($occurrence_attributes[$args['flower_type_attr_id']], $defAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($location_attributes[$args['habitat_attr_id']], $defAttrOptions)) . '
    	</div>
		<div id="insect-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-insect-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
			<div id="reset-insect-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="insect-filter-title">
		  		<span>' . lang::get('LANG_Insect_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="insect-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
		  ' . data_entry_helper::select($insect_ctrl_args) . '
 		  <input type="text" name="insect:taxon_extra_info" class="taxon-info" value="' . lang::get('LANG_More_Precise') . '"
	 		onclick="if(this.value==\'' . lang::get('LANG_More_Precise') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
            onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_More_Precise') . '\'; this.style.color=\'#555\'}" />
		</div>
		<div id="conditions-filter-header" class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
	  		<div id="fold-conditions-button" class="ui-state-default ui-corner-all fold-button fold-button-folded">&nbsp;</div>
			<div id="reset-conditions-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="conditions-filter-title">
		  		<span>' . lang::get('LANG_Conditions_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="conditions-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all">
    	  ' . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['sky_state_attr_id']], $defAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['temperature_attr_id']], $defAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['wind_attr_id']], $defAttrOptions)) . str_replace("\n", "", data_entry_helper::outputAttribute($sample_attributes[$args['shade_attr_id']], $defAttrOptions)) . '
		</div>
		<div id="location-filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  		<div id="fold-location-button" class="ui-state-default ui-corner-all fold-button">&nbsp;</div>
			<div id="reset-location-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
			<div id="location-filter-title">
		  		<span>' . lang::get('LANG_Location_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="location-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-all">
		  <div id="location-entry">
		    ' . data_entry_helper::georeference_lookup(iform_map_get_georef_options($args)) . '
    		<span id="location-georef-notes" >' . lang::get('LANG_Georef_Notes') . '</span>
    		<label for="place:INSEE">' . lang::get('LANG_Or') . '</label>
 		    <input type="text" id="place:INSEE" name="place:INSEE" value="' . lang::get('LANG_INSEE') . '"
	 		  onclick="if(this.value==\'' . lang::get('LANG_INSEE') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
              onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_INSEE') . '\'; this.style.color=\'#555\'}" />
    	    <input type="button" id="search-insee-button" class="ui-corner-all ui-widget-content ui-state-default search-button" value="' . lang::get('search') . '" />
 	      </div>';
        // this is a bit of a hack, because the apply_template method is not public in data entry helper.
        $tempScript = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = '';
        $r .= data_entry_helper::map_panel($options, $olOptions);
        $map1JS = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = $tempScript;
        $r .= '
		</div>
      </div>
    </div>
    <div id="filter-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
	  <div id="search-insects-button" class="ui-state-default ui-corner-all search-button">' . lang::get('LANG_Search_Insects') . '</div>
      <div id="search-collections-button" class="ui-state-default ui-corner-all search-button">' . lang::get('LANG_Search_Collections') . '</div>
    </div>
	<div id="results-collections-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	  <div id="results-collections-title">
	  	<span>' . lang::get('LANG_Collections_Search_Results') . '</span>
      </div>
	</div>
	<div id="results-collections-results" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </div>
	<div id="results-insects-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	  <div id="results-insects-title">
	  	<span>' . lang::get('LANG_Insects_Search_Results') . '</span>
      </div>
	</div>
	<div id="results-insects-results" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </div>
</div>
<div id="focus-collection" class="ui-accordion ui-widget ui-helper-reset">
	<div id="fc-header" class="ui-accordion-content ui-helper-reset ui-state-active ui-corner-top ui-accordion-content-active">
	  <div id="fc-header-buttons">';
        if (user_access('IForm n' . $node->nid . ' add preferred collection')) {
            $r .= '<span id="fc-add-preferred" class="ui-state-default ui-corner-all preferred-button">' . lang::get('LANG_Add_Preferred_Collection') . '</span>';
        }
        $r .= '  
	    <span id="fc-prev-button" class="ui-state-default ui-corner-all previous-button">' . lang::get('LANG_Previous') . '</span>
	    <span id="fc-next-button" class="ui-state-default ui-corner-all next-button">' . lang::get('LANG_Next') . '</span>
	  	<span id="fc-filter-button" class="ui-state-default ui-corner-all collection-button">' . lang::get('LANG_List') . '</span>
	  </div>
	</div>
	<div id="collection-details" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
	  <div id="flower-image-container" ><div id="flower-image" class="flower-image"></div>
        <div id="show-flower-button" class="ui-state-default ui-corner-all display-button">' . lang::get('LANG_Display') . '</div>
      </div>
      <div id="environment-image" class="environment-image"></div>
      <div id="collection-description">
	    <p id="collection-date"></p>
	    <p id="collection-flower-name"></p>
	    <p>' . lang::get($occurrence_attributes[$args['flower_type_attr_id']]['caption']) . ': <span id="collection-flower-type" class=\\"collection-value\\"></span></p>
	    <p>' . lang::get($location_attributes[$args['habitat_attr_id']]['caption']) . ': <span id="collection-habitat" class=\\"collection-value\\"></span></p>
	    <p id="collection-locality"></p>
	    <p id="collection-user-name"></p>
	    <a id="collection-user-link">' . lang::get('LANG_User_Link') . '</a>
	  </div>
      <div id="map2_container">';
        // this is a bit of a hack, because the apply_template method is not public in data entry helper.
        $tempScript = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = '';
        $r .= data_entry_helper::map_panel($options2, $olOptions);
        $map2JS = data_entry_helper::$onload_javascript;
        data_entry_helper::$onload_javascript = $tempScript;
        $r .= '</div>
    </div>
	<div id="collection-insects">
    </div>
	<div id="fc-comments-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	    <div id="fc-new-comment-button" class="ui-state-default ui-corner-all new-comment-button">' . lang::get('LANG_New_Comment') . '</div>
		<span>' . lang::get('LANG_Comments_Title') . '</span>
	</div>
	<div id="fc-new-comment" class="ui-accordion-content ui-helper-reset ui-widget-content">
		<form id="fc-new-comment-form" action="' . iform_ajaxproxy_url($node, 'smp-comment') . '" method="POST">
		    <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    		<input type="hidden" name="sample_comment:sample_id" value="" />
    		<label for="sample_comment:person_name">' . lang::get('LANG_Username') . ':</label>
		    <input type="text" name="sample_comment:person_name" value="' . $username . '" readonly="readonly" />  
    		<label for="sample_comment:email_address">' . lang::get('LANG_Email') . ':</label>
		    <input type="text" name="sample_comment:email_address" value="' . $email . '" readonly="readonly" />
		    ' . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'sample_comment:comment', 'class' => 'required', 'suffixTemplate' => 'nosuffix')) . '
    		<input type="submit" id="fc_comment_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Submit_Comment') . '" />
    	</form>
	</div>
	<div id="fc-comment-list" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	</div>
</div>
<div id="focus-occurrence" class="ui-accordion ui-widget ui-helper-reset">
	<div id="fo-header" class="ui-accordion-content ui-helper-reset ui-state-active ui-corner-top ui-accordion-content-active">
	  <div id="fo-header-buttons">
 	    <span id="fo-collection-button" class="ui-state-default ui-corner-all collection-button">' . lang::get('LANG_Collection') . '</span>
	    <span id="fo-prev-button" class="ui-state-default ui-corner-all previous-button">' . lang::get('LANG_Previous') . '</span>
	    <span id="fo-next-button" class="ui-state-default ui-corner-all next-button">' . lang::get('LANG_Next') . '</span>
	  	<span id="fo-filter-button" class="ui-state-default ui-corner-all collection-button">' . lang::get('LANG_List') . '</span>
	  </div>
	</div>
	<div id="fo-picture" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	  <div id="fo-warning"></div>
	  <div id="fo-image">
      </div>
    </div>
	<div id="fo-identification" class="ui-accordion-header ui-helper-reset ui-corner-top ui-state-active">
	  <div id="fo-id-title">
	  	<span>' . lang::get('LANG_Indentification_Title') . '</span>
      </div>
    </div>
	<div id="fo-current-id" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	</div>
	<div id="fo-new-insect-id" class="ui-accordion-content ui-helper-reset ui-widget-content">
	  <form id="fo-new-insect-id-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
    	<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />';
        if (user_access('IForm n' . $node->nid . ' insect expert')) {
            $r .= '		<select name="determination:determination_type" />
			<option value="C" selected>' . lang::get('LANG_Det_Type_C') . '</option>
			<option value="X">' . lang::get('LANG_Det_Type_X') . '</option>
		</select>';
        } else {
            $r .= '		<input type="hidden" name="determination:determination_type" value="A" />';
        }
        $r .= '		<div class="id-tool-group">
          <input type="hidden" name="determination:taxon_details" />
          <span id="insect-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>
		  <span id="insect-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>
 	      <p id="insect_taxa_list"></p>
 	    </div>
 	    <div class="id-specified-group">
 	      ' . data_entry_helper::select($focus_insect_ctrl_args) . '
          <label for="insect:taxon_extra_info" class="follow-on">' . lang::get('LANG_More_Precise') . ' </label> 
          <input type="text" id="insect:taxon_extra_info" name="determination:taxon_extra_info" class="taxon-info" />
        </div>
 	    <div class="id-comment">
          <label for="insect:comment" class="follow-on">' . lang::get('LANG_ID_Comment') . ' </label>
          <textarea id="insect:comment" name="determination:comment" class="taxon-comment" rows="5" ></textarea>
        </div>
        <input type="submit" id="insect_id_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>
    <div id="fo-new-flower-id" class="ui-accordion-content ui-helper-reset ui-widget-content">
	  <form id="fo-new-flower-id-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
    	<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />';
        if (user_access('IForm n' . $node->nid . ' flower expert')) {
            $r .= '		<select name="determination:determination_type" />
			<option value="C" selected>' . lang::get('LANG_Det_Type_C') . '</option>
			<option value="X">' . lang::get('LANG_Det_Type_X') . '</option>
		</select>';
        } else {
            $r .= '		<input type="hidden" name="determination:determination_type" value="A" />';
        }
        $r .= '		<div class="id-tool-group">
          <input type="hidden" name="determination:taxon_details" />
          <span id="flower-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>
		  <span id="flower-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>
 	      <p id="flower_taxa_list" class="taxa_list" ></p>
 	    </div>
 	    <div class="id-specified-group">
 	      ' . data_entry_helper::select($focus_flower_ctrl_args) . '
          <label for="flower:taxon_extra_info" class="follow-on">' . lang::get('LANG_More_Precise') . ' </label> 
          <input type="text" id="flower:taxon_extra_info" name="determination:taxon_extra_info" class="taxon-info" />
        </div>
 	    <div class="id-comment">
          <label for="flower:comment" class="follow-on">' . lang::get('LANG_ID_Comment') . ' </label>
          <textarea id="flower:comment" name="determination:comment" class="taxon-comment" rows="5" ></textarea>
        </div>
        <input type="submit" id="flower_id_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>
	<div id="fo-express-doubt" class="ui-accordion-content ui-helper-reset ui-widget-content">
	  <form id="fo-express-doubt-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
    	<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />
    	<input type="hidden" name="determination:determination_type" value="B" />
        <input type="hidden" name="determination:taxon_extra_info" />
        <input type="hidden" name="determination:taxa_taxon_list_id" />
 	    <div class="doubt-comment">
          <label for="determination:comment" class="follow-on">' . lang::get('LANG_Doubt_Comment') . ' </label>
          <textarea id="determination:comment" name="determination:comment" class="taxon-comment" rows="5" ></textarea>
        </div>
        <input type="submit" id="doubt_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>
	
	<div id="fo-id-history" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active"></div>
	<div id="fo-id-buttons" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
		<div id="fo-new-insect-id-button" class="ui-state-default ui-corner-all new-id-button">' . lang::get('LANG_New_ID') . '</div>
		<div id="fo-new-flower-id-button" class="ui-state-default ui-corner-all new-id-button">' . lang::get('LANG_New_ID') . '</div>
		<div id="fo-doubt-button" class="ui-state-default ui-corner-all doubt-button">' . lang::get('LANG_Doubt') . '</div>
    </div>	
	<div id="fo-insect-addn-info" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	    <span class="addn-info-title">' . lang::get('LANG_Additional_Info_Title') . '</span>
	    <p>' . lang::get('LANG_Date') . ': <span id="fo-insect-date"></span></p>
	    <p>' . lang::get('LANG_Time') . ': <span id="fo-insect-start-time"></span> ' . lang::get('LANG_To') . ' <span id="fo-insect-end-time"></span></p>
	    <p>' . $sample_attributes[$args['sky_state_attr_id']]['caption'] . ': <span id="fo-insect-sky"></span></p>
	    <p>' . $sample_attributes[$args['temperature_attr_id']]['caption'] . ': <span id="fo-insect-temp"></span></p>
	    <p>' . $sample_attributes[$args['wind_attr_id']]['caption'] . ': <span id="fo-insect-wind"></span></p>
	    <p>' . $sample_attributes[$args['shade_attr_id']]['caption'] . ': <span id="fo-insect-shade"></span></p>
	</div>
	<div id="fo-flower-addn-info" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	    <p>' . $occurrence_attributes[$args['flower_type_attr_id']]['caption'] . ': <span id="focus-flower-type"></span></p>
	    <p>' . $location_attributes[$args['habitat_attr_id']]['caption'] . ': <span id="focus-habitat"></span></p>
	</div>
	<div id="fo-comments-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	    <div id="fo-new-comment-button" class="ui-state-default ui-corner-all new-comment-button">' . lang::get('LANG_New_Comment') . '</div>
		<span>' . lang::get('LANG_Comments_Title') . '</span>
	</div>
	<div id="fo-new-comment" class="ui-accordion-content ui-helper-reset ui-widget-content">
		<form id="fo-new-comment-form" action="' . iform_ajaxproxy_url($node, 'occ-comment') . '" method="POST">
		    <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    		<input type="hidden" name="occurrence_comment:occurrence_id" value="" />
    		<label for="occurrence_comment:person_name">' . lang::get('LANG_Username') . ':</label>
		    <input type="text" name="occurrence_comment:person_name" value="' . $username . '" readonly="readonly" />  
    		<label for="occurrence_comment:email_address">' . lang::get('LANG_Email') . ':</label>
		    <input type="text" name="occurrence_comment:email_address" value="' . $email . '" readonly="readonly" />
		    ' . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence_comment:comment', 'class' => 'required', 'suffixTemplate' => 'nosuffix')) . '
    		<input type="submit" id="comment_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Submit_Comment') . '" />
    	</form>
	</div>
	<div id="fo-comment-list" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	</div>
</div>
';
        data_entry_helper::$javascript .= "\n// We need to leave the AJAX calls for the search alone, but abort other focus-on calls,\n// so we put a dummy REMOVEABLEJSONP in the URL, and search on that. This is ignored by the service call itself.\najaxStack = [];\nabortAjax = function()\n{\n\tjQuery('script').each(function(){\n\t\tif(this.src.indexOf('REMOVEABLEJSONP')>0){\n\t\t\tvar test = this.src.match(/jsonp\\d*/);\n\t\t\twindow[test] = function(){};\n\t\t\tjQuery(this).remove();\n\t\t}\n\t});\n\t// This deals with any non cross domain calls.\n\twhile(ajaxStack.length > 0){\n\t\tvar request = ajaxStack.shift();\n\t\tif(!(typeof request == 'undefined')) request.abort();\n\t}\n}\n\n\nalertIndiciaError = function(data){\n\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\tif(data.error){\terrorString = errorString + ' : ' + data.error;\t}\n\tif(data.errors){\n\t\tfor (var i in data.errors){\n\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t}\t\t\t\t\n\t}\n\talert(errorString);\n\t// the most likely cause is authentication failure - eg the read authentication has timed out.\n\t// prevent further use of the form:\n\tjQuery('#filter,#focus-occurrence,#focus-collection').hide();\n\tjQuery('#refresh-message').show();\n};\n\njQuery('#imp-georef-search-btn').removeClass('indicia-button').addClass('search-button');\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\n\n// remove the (don't know) entry from flower type filter.\njQuery('[name=occAttr\\:" . $args['flower_type_attr_id'] . "]').filter('[value=" . $args['flower_type_dont_know'] . "]').parent().remove();\n \njQuery('#start_date').datepicker({\n  dateFormat : 'dd/mm/yy',\n  constrainInput: false,\n  maxDate: '0',\n  altField : '#real_start_date',\n  altFormat : 'yy-mm-dd'\n});\njQuery('#end_date').datepicker({\n  dateFormat : 'dd/mm/yy',\n  constrainInput: false,\n  maxDate: '0',\n  altField : '#real_end_date',\n  altFormat : 'yy-mm-dd'\n});\n\nmyScrollTo = function(selector){\n\tjQuery(selector).filter(':visible').each(function(){\n\t\twindow.scroll(0, jQuery(this).offset().top);\n\t});\n};\n\njQuery('#reset-name-button').click(function(){\n\tjQuery('[name=username]').val('');\n});\njQuery('#fold-name-button').click(function(){\n\tjQuery('#name-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-name-button').toggleClass('fold-button-folded');\n\tjQuery('#name-filter-body').toggleClass('ui-accordion-content-active');\n});\njQuery('#reset-date-button').click(function(){\n\tjQuery('[name=start_date]').val('" . lang::get('click here') . "');\n\tjQuery('[name=real_start_date]').val('');\n\tjQuery('[name=end_date]').val('" . lang::get('click here') . "');\n\tjQuery('[name=real_end_date]').val('');\n});\njQuery('#fold-date-button').click(function(){\n\tjQuery('#date-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-date-button').toggleClass('fold-button-folded');\n\tjQuery('#date-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#reset-flower-button').click(function(){\n\tjQuery('[name=flower\\:taxa_taxon_list_id]').val('');\n\tjQuery('[name=flower\\:taxon_extra_info]').val(\"" . lang::get('LANG_More_Precise') . "\");\n\tjQuery('#flower-filter-body').find(':checkbox').removeAttr('checked');\n});\njQuery('#fold-flower-button').click(function(){\n\tjQuery('#flower-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-flower-button').toggleClass('fold-button-folded');\n\tjQuery('#flower-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#reset-insect-button').click(function(){\n\tjQuery('[name=insect\\:taxa_taxon_list_id]').val('');\n\tjQuery('[name=insect\\:taxon_extra_info]').val(\"" . lang::get('LANG_More_Precise') . "\");\n\tjQuery('#insect-filter-body').find(':checkbox').removeAttr('checked');\n});\n\njQuery('#fold-insect-button').click(function(){\n\tjQuery('#insect-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-insect-button').toggleClass('fold-button-folded');\n\tjQuery('#insect-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#reset-conditions-button').click(function(){\n\tjQuery('#conditions-filter-body').find(':checkbox').removeAttr('checked');\n});\n\njQuery('#fold-conditions-button').click(function(){\n\tjQuery('#conditions-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-conditions-button').toggleClass('fold-button-folded');\n\tjQuery('#conditions-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#reset-location-button').click(function(){\n\tpolygonLayer.destroyFeatures();\n\tpolygonLayer.map.searchLayer.destroyFeatures();\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroyFeatures();\n\tjQuery('#imp-georef-search').val('');\n\tjQuery('[name=place\\:INSEE]').val('" . lang::get('LANG_INSEE') . "');\n\tvar div = jQuery('#map')[0];\n\tvar center = new OpenLayers.LonLat(" . $args['map_centroid_long'] . ", " . $args['map_centroid_lat'] . ");\n\tcenter.transform(div.map.displayProjection, div.map.projection);\n\tdiv.map.setCenter(center, " . (int) $args['map_zoom'] . ");\n});\njQuery('#fold-location-button').click(function(){\n\tjQuery('#location-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-location-button').toggleClass('fold-button-folded');\n\tjQuery('#location-filter-body').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#flower-image').click(function(){\n\tif(jQuery('#flower-image').data('occID') != 'none'){\n\t\tloadFlower(jQuery('#flower-image').data('occID'), jQuery('#flower-image').data('collectionIndex'));\n\t}\n});\njQuery('#show-flower-button').click(function(){\n\tif(jQuery('#flower-image').data('occID') != 'none'){\n\t\tloadFlower(jQuery('#flower-image').data('occID'), jQuery('#flower-image').data('collectionIndex'));\n\t}\n});\n\njQuery('#fo-doubt-button').click(function(){\n\tjQuery('#fo-new-insect-id,#fo-new-flower-id').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-express-doubt [name=determination\\:comment]').val(\"" . lang::get('LANG_Default_Doubt_Comment') . "\");\n\tjQuery('#fo-express-doubt').toggleClass('ui-accordion-content-active');\n});\n\njQuery('#fc-next-button,#fc-prev-button').click(function(){\n\tvar index = jQuery(this).data('index');\n\tvar id = searchResults.features[index].attributes.collection_id;\n\tloadCollection(id, index);\n});\n\njQuery('#fc-filter-button,#fo-filter-button').click(function(){\n    jQuery('#filter').show();\n\tjQuery('#focus-occurrence,#focus-collection,#results-insects-header,#results-collections-header,#results-insects-results,#results-collections-results').hide();\n    loadFilter();\n    if(searchResults != null){\n    \tif(searchResults.type == 'C')\n    \t\tjQuery('#results-collections-header,#results-collections-results').show();\n    \telse \n    \t\tjQuery('#results-insects-header,#results-insects-results').show();\n\t}\n});\n\nhtmlspecialchars = function(value){\n\treturn value.replace(/[<>\"'&]/g, function(m){return replacechar(m)})\n};\n\nreplacechar = function(match){\n\tif (match==\"<\") return \"&lt;\"\n\telse if (match==\">\") return \"&gt;\"\n\telse if (match=='\"') return \"&quot;\"\n\telse if (match==\"'\") return \"&#039;\"\n\telse if (match==\"&\") return \"&amp;\"\n};\n\nconvertDate = function(dateStr, incTime){\n\tvar retDate = '';\n\t// assume date is in in YYYY/MM/DD[+Time] format.\n\t// if language is french convert to DD/MM/YYYY[+Time] format.\n\tif('" . $args['language'] . "' == 'fr'){\n\t\tretDate = dateStr.slice(8,10)+'-'+dateStr.slice(5,7)+'-'+dateStr.slice(0,4);\n\t\tif(incTime) retDate = retDate+dateStr.slice(10);\n\t} else if(incTime)\n\t\tretDate = dateStr;\n\telse\n\t\tretDate = dateStr.slice(0,10);\n\treturn retDate;\n} \n\nloadCollection = function(id, index){\n\tabortAjax();\n    jQuery('[name=sample_comment\\:sample_id]').val(id);\n\tjQuery('#fc-add-preferred').attr('smpID', id);\n\tcollection_preferred_object.collection_id = id;\n\tjQuery('#fc-new-comment-button')." . (user_access('IForm n' . $node->nid . ' create collection comment') ? "show()" : "hide()") . ";\n    jQuery('#focus-occurrence,#filter,#fc-next-button,#fc-prev-button').hide();\n    jQuery('#focus-collection').show();\n    if(index != null){\n    \tif(index < (searchResults.features.length-1) )\n    \t\tjQuery('#fc-next-button').show().data('index', index+1);\n    \tif(index > 0)\n    \t\tjQuery('#fc-prev-button').show().data('index', index-1);\n    }\n    if(jQuery('#map2').children().length == 0) {\n    \tlocationLayer = new OpenLayers.Layer.Vector('Location Layer',{displayInLayerSwitcher: false});\n    \t" . $map2JS . "\n \t};\n    locationLayer.destroyFeatures();\n \tjQuery('#map2').width('auto');\n\tjQuery('#flower-image').data('occID', 'none').data('collectionIndex', index);\n\tjQuery('#collection-insects,#collection-date,#collection-flower-name,#collection-flower-type,#collection-habitat,#collection-user-name').empty();\n\tloadComments(id, '#fc-comment-list', 'sample_comment', 'sample_id', 'sample-comment-block', 'sample-comment-body', true);\n\t// only need to reset the timeout on the first fetch as rest follow on quickly.\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence\" +\n\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\"&sample_id=\"+id+\"&deleted=f&REMOVEABLEJSONP&callback=?\", function(flowerData) {\n   \t\tif(!(flowerData instanceof Array)){\n   \t\t\talertIndiciaError(flowerData);\n   \t\t} else if (flowerData.length>0) {\n   \t\t\tloadImage('occurrence_image', 'occurrence_id', flowerData[0].id, '#flower-image', " . $args['Flower_Image_Ratio'] . ", function(imageRecord){collection_preferred_object.flower_image_path = imageRecord.path}, 'med-', false);\n\t\t\tjQuery('#flower-image').data('occID', flowerData[0].id);\n\t\t\tcollection_preferred_object.flower_id = flowerData[0].id;\n\t\t\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t\"&occurrence_id=\" + flowerData[0].id + \"&deleted=f&orderby=id&REMOVEABLEJSONP&callback=?\", function(detData) {\n   \t\t\t\tif(!(detData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(detData);\n   \t\t\t\t} else if (detData.length>0) {\n   \t\t\t\t\tvar i = detData.length-1;\n\t\t\t\t\tvar string = '';\n\t\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\t\tstring = detData[i].taxon;\n\t\t  \t\t\t}\n\t\t\t\t\tif(detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != null){\n\t\t\t\t\t\tdetData[i].taxa_taxon_list_id_list;\n\t\t\t  \t\t\tvar resultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t\t\t\tif(resultsIDs[0] != '') {\n\t\t\t\t\t\t\tfor(var j=0; j < resultsIDs.length; j++){\n\t\t\t\t\t\t\t\tfor(k = 0; k< flowerTaxa.length; k++){\n\t\t\t\t\t\t\t\t\tif(flowerTaxa[k].id == resultsIDs[j]){\n\t\t\t\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + flowerTaxa[k].taxon;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t  \t\t}\n\t\t\t\t\t  \t}\n\t\t\t\t\t}\n\t\t  \t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\t\t\tstring = (string == '' ? '' : string + ' ') + '('+detData[i].taxon_extra_info+')';\n\t\t\t\t\t}\n\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Flower_Name') . ": <span class=\"collection-value\">'+htmlspecialchars(string)+'</span></span>').appendTo('#collection-flower-name');\n\t\t\t\t}}));\n\t\t\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence_attribute_value\"  +\n   \t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&occurrence_id=\" + flowerData[0].id + \"&iso=" . $language . "&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\t\t\tif(!(attrdata instanceof Array)){\n   \t\t\t\t\talertIndiciaError(attrdata);\n   \t\t\t\t} else if (attrdata.length>0) {\n   \t\t\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\t\t\tswitch(parseInt(attrdata[i].occurrence_attribute_id)){\n\t\t\t\t\t\t\t\tcase " . $args['flower_type_attr_id'] . ":\n\t\t\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+'</span>').appendTo('#collection-flower-type');\n\t\t\t\t\t\t\t\t\tbreak;\n  \t\t\t}}}}}));\n\t\t\t\t\n\t\t}\n\t}));\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample_attribute_value\"  +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&sample_id=\" + id + \"&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].sample_attribute_id)){\n\t\t\t\t\t\tcase " . $args['username_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Comment_By') . "'+attrdata[i].value+'</span>').appendTo('#collection-user-name');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase " . $args['uid_attr_id'] . ":\n\t\t\t\t\t\t\tcollection_preferred_object.user_id = attrdata[i].value\n\t\t\t       \t\t    jQuery('#collection-user-link').attr('href', '" . url('node/' . $node->nid) . "?user_id='+attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n    }}}}}));\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample/\" +id+\n\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\"&REMOVEABLEJSONP&callback=?\", function(collectionData) {\n   \t\tif(!(collectionData instanceof Array)){\n   \t\t\talertIndiciaError(collectionData);\n   \t\t} else if (collectionData.length>0) {\n\t\t\tif(collectionData[0].date_start == collectionData[0].date_end){\n\t\t\t\tcollection_preferred_object.date = collectionData[0].date_start.slice(0,10);\n\t\t\t\tjQuery('<span>'+convertDate(collectionData[0].date_start, false)+'</span>').appendTo('#collection-date');\n\t\t\t} else {\n\t\t\t\tcollection_preferred_object.date = collectionData[0].date_start.slice(0,10)+' - '+collectionData[0].date_end.slice(0,10);\n\t\t\t\tjQuery('<span>'+convertDate(collectionData[0].date_start, false)+' - '+convertDate(collectionData[0].date_end, false)+'</span>').appendTo('#collection-date');\n\t\t\t}\n\t\t\tjQuery('#poll-banner').empty().append(collectionData[0].location_name);\n\t  \t\tcollection_preferred_object.collection_name = collectionData[0].location_name;\n\t        ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/location/\" +collectionData[0].location_id +\n\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\t\t\"&REMOVEABLEJSONP&callback=?\", function(locationData) {\n   \t\t\t\tif(!(locationData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(locationData);\n   \t\t\t\t} else if (locationData.length>0) {\n\t\t\t\t\tloadImage('location_image', 'location_id', locationData[0].id, '#environment-image', " . $args['Environment_Image_Ratio'] . ", function(imageRecord){collection_preferred_object.environment_image_path = imageRecord.path}, 'med-', false);\n\t\t\t\t\tvar parser = new OpenLayers.Format.WKT();\n\t\t\t\t\tvar feature = parser.read(locationData[0].centroid_geom);\n\t\t\t\t\tlocationLayer.addFeatures([feature]);\n\t\t\t\t\tvar bounds=locationLayer.getDataExtent();\n\t\t\t\t\tlocationLayer.map.setCenter(bounds.getCenterLonLat(), 13);\n\t\t\t        var filter = new OpenLayers.Filter.Spatial({\n  \t\t\t\t\t\ttype: OpenLayers.Filter.Spatial.CONTAINS ,\n    \t\t\t\t\tproperty: 'the_geom',\n    \t\t\t\t\tvalue: feature.geometry\n\t\t\t\t  \t});\n\t\t\t\t\tvar locality = jQuery('#collection-locality');\n\t\t\t\t  \tvar scope = {target: locality};\n\t\t\t\t\tinseeProtocol.read({filter: filter, callback: fillLocationDetails, scope: scope});\n\t\t\t\t}\n\t\t\t}));\n\t        ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/location_attribute_value\"  +\n   \t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&location_id=\" + collectionData[0].location_id + \"&iso=" . $language . "&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\t\t\tif(!(attrdata instanceof Array)){\n   \t\t\t\t\talertIndiciaError(attrdata);\n   \t\t\t\t} else if (attrdata.length>0) {\n\t\t\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\t\t\tswitch(parseInt(attrdata[i].location_attribute_id)){\n\t\t\t\t\t\t\t\tcase " . $args['habitat_attr_id'] . ":\n\t\t\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+' / </span>').appendTo('#collection-habitat');\n\t\t\t\t\t\t\t\t\tbreak;\n  \t\t\t}}}}}));\n\t\t}\n\t}));\n\t// we want to tag end of row pictuure, so we need to keep track of its position in list.\n\tcollection_preferred_object.insects = [];\n\tajaxStack.push(jQuery.ajax({\n\t\turl: \"" . $svcUrl . "/data/sample?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&REMOVEABLEJSONP&callback=?&parent_id=\"+id,\n\t\tdataType: 'json',\n\t\tmyIndex: index,\n\t\tsuccess: function(sessiondata) {\n          if(!(sessiondata instanceof Array)){\n   \t\t\talertIndiciaError(sessiondata);\n   \t\t  } else if (sessiondata.length>0) {\n   \t\t\tvar sessList=[];\n   \t\t\t// code has been changed to fetch all insects at once, so we can now go async\n\t\t\tfor (var i=0;i<sessiondata.length;i++)\n\t\t\t\tsessList.push(sessiondata[i].id);\n\t\t\t\tajaxStack.push(jQuery.ajax({\n\t\t\t\t\turl: \"" . $svcUrl . "/data/occurrence?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&deleted=f&orderby=id&REMOVEABLEJSONP&callback=?&query=\"+escape(JSON.stringify({'in': ['sample_id', sessList]})),\n\t\t\t\t\tdataType: 'json',\n\t\t\t\t\tmyIndex: this.myIndex,\n\t\t\t\t\tsuccess: function(insectData) {\n\t\t\t\t\t  if(!(insectData instanceof Array)){\n   \t\t\t\t\t\talertIndiciaError(insectData);\n   \t\t  \t\t\t  } else if (insectData.length>0) {\n\t\t\t\t\t\tfor (var j=0;j<insectData.length;j++){\n\t\t\t\t\t\t\tvar insect=jQuery('<div class=\"ui-widget-content ui-corner-all collection-insect\" />').attr('occID', insectData[j].id).appendTo('#collection-insects');\n\t\t\t\t\t\t\tif((j+1)/" . $args['insectsPerRow'] . " == parseInt((j+1)/" . $args['insectsPerRow'] . "))\n\t\t\t\t\t\t\t\tinsect.addClass('end-of-row');\n\t\t\t\t\t\t\tjQuery('<p class=\"insect-tag insect-unknown\" />').appendTo(insect);\n\t\t\t\t\t\t\tvar image = jQuery('<div class=\"insect-image empty\" />').appendTo(insect).data('occID',insectData[j].id)\n\t\t\t\t\t\t\t\t\t.data('collectionIndex',this.myIndex).click(function(){\n\t\t\t\t\t\t\t\tloadInsect(jQuery(this).data('occID'),jQuery(this).data('collectionIndex'),null,'C');\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tjQuery('<p class=\"insect-determination empty\" />').appendTo(insect);\n\t\t\t\t\t\t\tjQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>')\n\t\t\t\t\t\t\t\t\t.appendTo(insect).attr('occID',insectData[j].id).data('collectionIndex',this.myIndex).data('collectionInsectIndex',j).click(function(){\n\t\t\t\t\t\t\t\tloadInsect(jQuery(this).attr('occID'),jQuery(this).data('collectionIndex'),null,'C');\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tloadImage('occurrence_image', 'occurrence_id', insectData[j].id, image, " . $args['Insect_Image_Ratio'] . ", function(imageRecord){collection_preferred_object.insects.push({insect_id: imageRecord.occurrence_id, insect_image_path: imageRecord.path})}, 'med-',\n\t\t\t\t\t\t\t\tfunction(img){\n\t\t\t\t\t\t\t\t\tvar group = jQuery('#collection-insects').find('.collection-insect');\n\t\t\t\t\t\t\t\t\tjQuery(img).parent().removeClass('empty');\n\t\t\t\t\t\t\t\t\tif(group.find('.empty').length == 0){\n\t\t\t\t\t\t\t\t\t\tvar tallest = 0;\n\t\t\t\t\t\t\t\t\t\tgroup.each(function(){ tallest = Math.max(\$(this).height(), tallest); });\n\t\t\t\t\t\t\t\t\t\tgroup.each(function(){ \$(this).height(Math.max(\$(this).height(), tallest)); }); // have synchronicity problems.\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tajaxStack.push(jQuery.ajax({\n\t\t\t\t\t\t\t\turl: \"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t    \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t    \t\t\t\"&occurrence_id=\" + insectData[j].id + \"&deleted=f&orderby=id&REMOVEABLEJSONP&callback=?\",\n\t\t\t\t\t\t\t\tdataType: 'json',\n\t\t\t\t\t\t\t\tmyID: insectData[j].id,\n\t\t\t\t\t\t\t\tsuccess: function(detData) {\n   \t\t\t\t\t\t\t\t  if(!(detData instanceof Array)){\n   \t\t\t\t\t\t\t\t\talertIndiciaError(detData);\n   \t\t  \t\t\t  \t\t\t  } else {\n   \t\t  \t\t\t  \t\t\t   if (detData.length>0) {\n\t\t\t\t\t    \t\t\tvar insect = jQuery('.collection-insect').filter('[occID='+detData[0].occurrence_id+']');\n\t\t\t\t\t    \t\t\tvar tag = insect.find('.insect-tag');\n\t\t\t\t\t    \t\t\tvar det = insect.find('.insect-determination');\n\t\t\t\t\t\t\t\t\tvar i = detData.length-1;\n\t\t\t\t\t\t\t\t\tvar string = '';\n\t\t\t\t\t\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\t\t\t\t\t\tstring = detData[i].taxon;\n\t\t\t\t\t\t  \t\t\t}\n\t\t\t\t\t\t\t\t\tif(detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != null){\n\t\t\t\t\t\t\t\t\t\tdetData[i].taxa_taxon_list_id_list;\n\t\t\t\t\t\t\t\t\t  \tvar resultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t\t\t\t\t\t\t\tif(resultsIDs[0] != '') {\n\t\t\t\t\t\t\t\t\t\t\tfor(var j=0; j < resultsIDs.length; j++){\n\t\t\t\t\t\t\t\t\t\t\t\tfor(var k = 0; k< insectTaxa.length; k++){\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(insectTaxa[k].id == resultsIDs[j]){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + insectTaxa[k].taxon;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t  \t\t}\n\t\t\t\t\t\t\t\t\t}\t\n\t\t\t\t\t\t\t\t\tif(string != '')\n\t\t\t\t\t\t\t\t\t\tjQuery('<div><p>" . lang::get('LANG_Last_ID') . ":</p><p><strong>'+string+'</strong></p></div>').addClass('insect-id').appendTo(det);\n\t\t\t\t\t\t\t\t\tif(detData[i].determination_type == 'B' || detData[i].determination_type == 'I' || detData[i].determination_type == 'U'){\n\t\t\t\t\t\t\t\t\t\ttag.removeClass('insect-unknown').addClass('insect-dubious');\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\ttag.removeClass('insect-unknown').addClass('insect-ok');\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t   }\n\t\t\t\t\t\t\t\t\tvar group = jQuery('#collection-insects').find('.collection-insect');\n\t\t\t\t\t\t\t\t\tgroup.filter('[occID='+this.myID+']').find('.insect-determination').removeClass('empty');\n\t\t\t\t\t\t\t\t\tif(group.find('.empty').length == 0){\n\t\t\t\t\t\t\t\t\t\tvar tallest = 0;\n\t\t\t\t\t\t\t\t\t\tgroup.each(function(){ tallest = Math.max(\$(this).height(), tallest); });\n\t\t\t\t\t\t\t\t\t\tgroup.each(function(){ \$(this).height(Math.max(\$(this).height(), tallest)); }); // have synchronicity problems.\n\t\t\t\t\t\t\t}}}}));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t  }})); \n\t\t\t}}\n\t    }));\n\tmyScrollTo('#poll-banner');\n};\nfillLocationDetails = function(a1)\n{\n\tjQuery(this.target).empty();\n\tcollection_preferred_object.location_description = '';\n\tif(a1.features.length > 0) {\n\t   \tvar text = a1.features[0].attributes.NOM+' ('+a1.features[0].attributes.INSEE_NEW+'), '+a1.features[0].attributes.DEPT_NOM+' ('+a1.features[0].attributes.DEPT_NUM+'), '+a1.features[0].attributes.REG_NOM+' ('+a1.features[0].attributes.REG_NUM+')';\n\t\tcollection_preferred_object.location_description = text;\n\t   \tjQuery('<span>'+text+'</span>').appendTo(this.target);\n  }\n}\naddCollection = function(index, attributes, geom, first){\n\t// first the text, then the flower and environment picture, then the small insect pictures, then the afficher button\n\tvar collection=jQuery('<div class=\"ui-widget-content ui-corner-all filter-collection\" />').appendTo('#results-collections-results');\n\tvar details = jQuery('<div class=\"collection-details\" />').appendTo(collection); \n\tvar flower = jQuery('<div class=\"collection-image collection-flower\" />').data('occID', attributes.flower_id).\n\t\tdata('collectionIndex', index).click(function(){\n\t\t\tloadFlower(jQuery(this).data('occID'), jQuery(this).data('collectionIndex'));\n\t});\n\tvar filter = new OpenLayers.Filter.Spatial({\n  \t\t\ttype: OpenLayers.Filter.Spatial.CONTAINS ,\n    \t\tproperty: 'the_geom',\n    \t\tvalue: geom\n  \t});\n\tflower.appendTo(collection);\n\tinsertImage('med-'+attributes.image_de_la_fleur, flower, " . $args['Flower_Image_Ratio'] . ", false);\n\tvar location = jQuery('<div class=\"collection-image collection-environment\" />').appendTo(collection);\n\tinsertImage('med-'+attributes.image_de_environment, location, " . $args['Environment_Image_Ratio'] . ", false);\n\tjQuery('<div class=\"collection-photoreel\"></div>').attr('collID', attributes.collection_id).appendTo(collection);\n\tvar displayButtonContainer = jQuery('<div class=\"collection-buttons\"></div>').appendTo(collection);\n\tjQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>').click(function(){\n\t\tloadCollection(jQuery(this).data('value'), jQuery(this).data('index'));\n\t}).appendTo(displayButtonContainer).data('value',attributes.collection_id).data('index',index);\n\tif(attributes.datedebut == attributes.datefin){\n\t  jQuery('<p class=\"collection-date\">'+convertDate(attributes.datedebut,false)+'</p>').appendTo(details);\n    } else {\n\t  jQuery('<p class=\"collection-date\">'+convertDate(attributes.datedebut,false)+' - '+convertDate(attributes.datefin,false)+'</p>').appendTo(details);\n    }\n\tjQuery('<p class=\"collection-name\">'+attributes.nom+'</p>').appendTo(details);\n\tvar locality = jQuery('<p  class=\"collection-locality\"></p>').appendTo(details);\n\tvar scope = {target: locality};\n\tinseeProtocol.read({filter: filter, callback: fillLocationDetails, scope: scope});\n\tjQuery.getJSON(\"" . $svcUrl . "/data/sample?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + (first ? \"&reset_timeout=true\" : \"\") + \"&callback=?&parent_id=\"+attributes.collection_id,\n        function(sessiondata) {\n\t\t  if(!(sessiondata instanceof Array)){\n   \t\t\talertIndiciaError(sessiondata);\n   \t\t  } else for (var i=0;i<sessiondata.length;i++){\n   \t\t  \tvar photoreel = jQuery('.collection-photoreel').filter('[collID='+sessiondata[i].parent_id+']');\n   \t\t  \tjQuery('<span class=\"photoreel-session\"></span>').attr('sessID', sessiondata[i].id).appendTo(photoreel);\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&orderby=id\" +\n\t\t\t\t\t\"&sample_id=\"+sessiondata[i].id+\"&deleted=f&callback=?\", function(insectData) {\n\t\t    \tif(!(insectData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(insectData);\n   \t\t\t\t} else if (insectData.length>0) {\n \t\t\t\t\tfor (var j=0;j<insectData.length;j++){\n\t\t\t\t\t\tvar container = jQuery('<div/>').addClass('thumb').attr('occID', insectData[j].id.toString()).data('collectionIndex',index).click(function () {\n\t\t\t\t\t\t\tloadInsect(jQuery(this).attr('occID'),jQuery(this).data('collectionIndex'),null,'P');\n\t\t\t\t\t\t});\n\t\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Unknown') . "</span>').addClass('thumb-text').appendTo(container);\n\t\t\t\t\t\tjQuery('.photoreel-session').filter('[sessID='+insectData[j].sample_id+']').append(container);\n\t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_image\" +\n\t\t\t\t\t   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\t\t\t\"&occurrence_id=\" + insectData[j].id + \"&callback=?\", function(imageData) {\n\t\t\t\t\t\t\t  if(!(imageData instanceof Array)){\n   \t\t\t\t\t\t\t\talertIndiciaError(imageData);\n   \t\t\t\t\t\t\t  } else if (imageData.length>0) {\n\t\t\t\t\t\t      \tvar container = jQuery('.thumb').filter('[occID='+imageData[0].occurrence_id.toString()+']');\n\t\t\t\t\t\t\t    var img = new Image();\n\t\t\t\t\t\t\t    // thumbs are fixed in size, and small - dont worry about ratios\n\t\t\t\t\t\t\t\tjQuery(img).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "thumb-'+imageData[0].path)\n\t\t\t    \t\t\t\t\t.attr('width', container.width()).attr('height', container.height()).addClass('thumb-image').appendTo(container);\n\t\t\t\t\t\t\t  }}); \n\t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t    \t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t    \t\t\"&occurrence_id=\" + insectData[j].id + \"&orderby=id&deleted=f&callback=?\", function(detData) {\n\t\t\t\t\t\t      if(!(detData instanceof Array)){\n   \t\t\t\t\t\t\t\talertIndiciaError(detData);\n   \t\t\t\t\t\t\t  } else if (detData.length>0) {\n\t\t\t\t\t\t        var container = jQuery('.thumb').filter('[occID='+detData[0].occurrence_id.toString()+']');\n\t\t\t\t\t\t        if(detData[detData.length-1].determination_type == 'B' || detData[detData.length-1].determination_type == 'I' || detData[detData.length-1].determination_type == 'U'){\n\t\t\t\t\t\t        \tcontainer.find('.thumb-text').remove();\n\t\t\t\t\t\t        \tjQuery('<span>" . lang::get('LANG_Dubious') . "</span>').addClass('thumb-text').appendTo(container);\n\t\t\t\t\t\t\t  \t} else {\n\t\t\t\t\t\t\t\t\tcontainer.find('.thumb-text').remove();\n\t\t\t\t\t\t\t  \t}\n  \t\t\t\t\t\t}});  \t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t}});\n\t\t}});\n};\naddInsect = function(index, attributes, endOfRow, first){\n\tvar container=jQuery('<div class=\"ui-widget-content ui-corner-all filter-insect\" />').attr('occID',attributes.insect_id).appendTo('#results-insects-results');\n\tif(endOfRow) container.addClass('end-of-row');\n\tjQuery('<div />').addClass('insect-unknown').appendTo(container); // flag\n\tvar insect = jQuery('<div class=\"insect-image empty\" />').data('occID',attributes.insect_id).data('insectIndex',index).click(function(){\n\t\tloadInsect(jQuery(this).data('occID'), null, jQuery(this).data('insectIndex'), 'S');\n\t});\n\tinsect.appendTo(container);\n\tjQuery('<div class=\"insect-determinationX empty\" />').attr('occID',attributes.insect_id).appendTo(container).append(\"<p>" . lang::get('LANG_No_Determinations') . "</p>\");\n\tinsertImage('med-'+attributes.image_d_insecte, insect, " . $args['Insect_Image_Ratio'] . ", function(img){\n\t\t\tvar group = jQuery('#results-insects-results').find('.filter-insect');\n\t\t\tjQuery(img).parent().removeClass('empty');\n\t\t\tif(group.find('.empty').length == 0){\n\t\t\t\tvar tallest = 0;\n\t\t\t\tgroup.each(function(){ tallest = Math.max(\$(this).height(), tallest); });\n\t\t\t\tgroup.each(function(){ \$(this).height(Math.max(\$(this).height(), tallest)); }); // have synchronicity problems.\n\t\t\t}\n\t\t});\n\tjQuery.ajax({\n\t\turl: \"" . $svcUrl . "/data/determination?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + (first ? \"&reset_timeout=true\" : \"\") + \"&orderby=id&callback=?&occurrence_id=\" + attributes.insect_id,\n\t\tdataType: 'json',\n\t\tmyID: attributes.insect_id,\n\t\tsuccess: function(detData) {\n   \t\t  if(!(detData instanceof Array)){\n   \t\t\talertIndiciaError(detData);\n   \t\t  } else {\n   \t\t   if (detData.length>0) {\n\t\t\tvar i = detData.length-1;\n   \t\t\tvar string = '';\n\t\t\tvar determination = jQuery('.insect-determinationX').filter('[occID='+detData[i].occurrence_id+']').empty();\n\t\t\tvar flag = determination.parent().find('.insect-unknown');\n\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\tstring = detData[i].taxon;\n\t\t\t}\n\t\t\tif(detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != null && detData[i].taxa_taxon_list_id_list != '{}'){\n\t\t\t\tdetData[i].taxa_taxon_list_id_list;\n\t\t\t\tvar resultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t\tif(resultsIDs[0] != '') {\n\t\t\t\t\tfor(var j=0; j < resultsIDs.length; j++){\n\t\t\t\t\t\tfor(var k = 0; k< insectTaxa.length; k++){\n\t\t\t\t\t\t\tif(insectTaxa[k].id == resultsIDs[j]){\n\t\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + insectTaxa[k].taxon;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tjQuery('<p>'+string+'</p>').appendTo(determination)\n\t\t\tif(detData[i].determination_type == 'B' || detData[i].determination_type == 'I' || detData[i].determination_type == 'U'){\n\t\t\t\tflag.removeClass('insect-unknown').addClass('insect-dubious');\n\t\t\t} else \n\t\t\t\tflag.removeClass('insect-unknown').addClass('insect-ok');\n\t\t   }\n\t\t   var group = jQuery('#results-insects-results').find('.filter-insect');\n\t\t   group.filter('[occID='+this.myID+']').find('.insect-determinationX').removeClass('empty');\n\t\t   if(group.find('.empty').length == 0){\n\t\t\t\tvar tallest = 0;\n\t\t\t\tgroup.each(function(){ tallest = Math.max(\$(this).height(), tallest); });\n\t\t\t\tgroup.each(function(){ \$(this).height(Math.max(\$(this).height(), tallest)); }); // have synchronicity problems.\n\t\t   \n  \t\t  }}\n\t}});\n\tjQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>').click(function(){\n\t\tloadInsect(jQuery(this).attr('occID'), null, jQuery(this).data('insectIndex'), 'S');\n\t}).appendTo(container).attr('occID',attributes.insect_id).data('insectIndex',index);\n};\n\n\nsetCollectionPage = function(pageNum){\n\tvar no_units = 4;\n\tvar no_tens = 2;\n\tvar no_hundreds = 1;\n\tjQuery('#results-collections-results').empty();\n\tvar numPages = Math.ceil(searchResults.features.length/" . $args['collectionsPerPage'] . ");\n\tif(numPages > 1) {\n\t\tvar item;\n\t\tvar itemList = jQuery('<div class=\"item-list\"></div>').appendTo('#results-collections-results');\n\t\tvar pageCtrl = jQuery('<ul>').addClass('pager').appendTo(itemList);\n\t\tfor (var j = pageNum - no_units; j<= pageNum + no_units; j++){\n\t\t\tif(j <= numPages && j >= 1){\n\t\t\t\tif(j == pageNum)\n\t\t\t\t\tjQuery('<li class=\"pager-current\">'+pageNum+'</li>').appendTo(pageCtrl);\n\t\t\t\telse {\n\t\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t\t}\n  \t\t\t}\n\t\t}\n\t\tvar start = Math.ceil(j/10)*10;\n\t\tfor (j = start; j< start + no_tens*10; j=j+10){\n\t\t\tif(j <= numPages){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tstart = Math.ceil(j/100)*100;\n\t\tfor (j = start; j< start + no_hundreds*100; j=j+100){\n\t\t\tif(j <= numPages){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tif(pageNum != numPages){\n\t\t\titem = jQuery('<li class=\"pager-next\"></li>').attr('value',pageNum+1).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t\titem = jQuery('<li class=\"pager-last\"></li>').attr('value',numPages).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">'+numPages+'</a>').appendTo(item);\n  \t\t}\n\t\tstart = Math.floor((pageNum - no_units -1)/10)*10;\n\t\tfor (j = start; j> start - no_tens*10; j=j-10){\n\t\t\tif(j >= 1){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tstart = Math.floor(j/100)*100;\n\t\tfor (j = start; j> start - no_hundreds*100; j=j-100){\n\t\t\tif(j >= 1){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tif(pageNum != 1){\n\t\t\titem = jQuery('<li class=\"pager-previous\"></li>').attr('value',pageNum-1).click(function(){setCollectionPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t\titem = jQuery('<li class=\"pager-first\"></li>').click(function(){setCollectionPage(1)}).prependTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t}\n  \t\tpageCtrl.find('li').filter(':first').addClass('first');\n  \t\tpageCtrl.find('li').filter(':last').addClass('last');\n\t}\n    for (var i = (pageNum-1)*" . $args['collectionsPerPage'] . ", first = true; i < searchResults.features.length && i < pageNum*" . $args['collectionsPerPage'] . "; i++, first = false){\n\t\taddCollection(i, searchResults.features[i].attributes,searchResults.features[i].geometry, first);\n\t}\n\tif(numPages > 1) {\n\t\titemList.clone(true).appendTo('#results-collections-results');\n\t}\n}\nsetInsectPage = function(pageNum){\n\tjQuery('#results-insects-results').empty();\n\tvar numPages = Math.ceil(searchResults.features.length/(" . $args['insectsRowsPerPage'] . "*" . $args['insectsPerRow'] . "));\n\tvar no_units = 4;\n\tvar no_tens = 2;\n\tvar no_hundreds = 1;\n\tif(numPages > 1) {\n\t\tvar item;\n\t\tvar itemList = jQuery('<div class=\"item-list\"></div>').appendTo('#results-insects-results');\n\t\tvar pageCtrl = jQuery('<ul>').addClass('pager').appendTo(itemList);\n\t\tfor (var j = pageNum - no_units; j<= pageNum + no_units; j++){\n\t\t\tif(j <= numPages && j >= 1){\n\t\t\t\tif(j == pageNum)\n\t\t\t\t\tjQuery('<li class=\"pager-current\">'+pageNum+'</li>').appendTo(pageCtrl);\n\t\t\t\telse {\n\t\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t\t}\n  \t\t\t}\n\t\t}\n\t\tvar start = Math.ceil(j/10)*10;\n\t\tfor (j = start; j< start + no_tens*10; j=j+10){\n\t\t\tif(j <= numPages){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tstart = Math.ceil(j/100)*100;\n\t\tfor (j = start; j< start + no_hundreds*100; j=j+100){\n\t\t\tif(j <= numPages){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tif(pageNum != numPages){\n\t\t\titem = jQuery('<li class=\"pager-next\"></li>').attr('value',pageNum+1).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t\titem = jQuery('<li class=\"pager-last\"></li>').attr('value',numPages).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">'+numPages+'</a>').appendTo(item);\n  \t\t}\n\t\tstart = Math.floor((pageNum - no_units -1)/10)*10;\n\t\tfor (j = start; j> start - no_tens*10; j=j-10){\n\t\t\tif(j >= 1){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tstart = Math.floor(j/100)*100;\n\t\tfor (j = start; j> start - no_hundreds*100; j=j-100){\n\t\t\tif(j >= 1){\n\t\t\t\titem = jQuery('<li class=\"pager-item\"></li>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\t\tjQuery('<a class=\"active\">'+j+'</a>').appendTo(item);\n\t\t\t}\n\t\t}\n\t\tif(pageNum != 1){\n\t\t\titem = jQuery('<li class=\"pager-previous\"></li>').attr('value',pageNum-1).click(function(){setInsectPage(jQuery(this).attr('value'))}).prependTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t\titem = jQuery('<li class=\"pager-first\"></li>').click(function(){setInsectPage(1)}).prependTo(pageCtrl);\n\t\t\tjQuery('<a class=\"active\">&nbsp;</a>').appendTo(item);\n  \t\t}\n  \t\tpageCtrl.find('li').filter(':first').addClass('first');\n  \t\tpageCtrl.find('li').filter(':last').addClass('last');\n\t}\n    for (var i = (pageNum-1)*" . $args['insectsRowsPerPage'] . "*" . $args['insectsPerRow'] . ", first = true; i < searchResults.features.length && i < pageNum*" . $args['insectsRowsPerPage'] . "*" . $args['insectsPerRow'] . "; i++, first = false){\n\t\taddInsect(i, searchResults.features[i].attributes, (i+1)/" . $args['insectsPerRow'] . " == parseInt((i+1)/" . $args['insectsPerRow'] . "), first);\n\t}\n\tif(numPages > 1) {\n\t\titemList.clone(true).appendTo('#results-insects-results');\n\t}\n}\n\n// searchLayer in map is used for georeferencing.\n// map editLayer is switched off. TODO: need to switch off click control\nsearchLayer = null;\ninseeLayer = null;\npolygonLayer = null;     \nlocationLayer = null;\ninseeProtocol = new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n              featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['NOM', 'INSEE_NEW', 'DEPT_NUM', 'DEPT_NOM', 'REG_NUM', 'REG_NOM']\n});\n\n\nflowerIDstruc = {\n\ttype: 'flower',\n\tmainForm: 'form#fo-new-flower-id-form',\n\ttimeOutTimer: null,\n\tpollTimer: null,\n\tpollFile: '',\n\tinvokeURL: '" . $args['ID_tool_flower_url'] . "',\n\tpollURL: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_flower_poll_dir']) . "',\n\tname: 'flowerIDstruc',\n\tdeterminationType: '" . (user_access('IForm n' . $node->nid . ' flower expert') ? 'C' : 'A') . "',\n\ttaxaList: flowerTaxa\n};\n\ntoolPoller = function(toolStruct){\n\tif(toolStruct.pollFile == '') return;\n\ttoolStruct.pollTimer = setTimeout('toolPoller('+toolStruct.name+');', " . $args['ID_tool_poll_interval'] . ");\n\tjQuery.ajax({\n\t url: toolStruct.pollURL+toolStruct.pollFile,\n\t toolStruct: toolStruct,\n\t success: function(data){\n\t  pollReset(this.toolStruct);\n\t  var da = data.split('\\n');\n      jQuery(this.toolStruct.mainForm+' [name=determination\\:taxon_details]').val(da[2]); // Stores the state of identification, which details how the identification was arrived at within the tool.\n\t  da[1] = da[1].replace(/\\\\\\\\i\\{\\}/g, '').replace(/\\\\\\\\i0\\{\\}/g, '').replace(/\\\\/g, '');\n\t  var items = da[1].split(':');\n\t  var count = items.length;\n\t  if(items[count-1] == '') count--;\n\t  if(items[count-1] == '') count--;\n\t  if(count <= 0){\n\t  \t// no valid stuff so blank it all out.\n\t  \tjQuery('#'+this.toolStruct.type+'_taxa_list').append(\"" . lang::get('LANG_Taxa_Unknown_In_Tool') . "\");\n\t  \tjQuery(this.toolStruct.mainForm+' [name=determination\\:determination_type]').val('X'); // Unidentified.\n      } else {\n      \tvar resultsIDs = [];\n      \tvar resultsText = \"" . lang::get('LANG_Taxa_Returned') . "<br />{ \";\n      \tvar notFound = '';\n\t\tfor(var j=0; j < count; j++){\n\t\t\tvar found = false;\n\t\t\titemText = items[j].replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\t\t\tfor(i = 0; i< this.toolStruct.taxaList.length; i++){\n\t\t\t\tif(this.toolStruct.taxaList[i].taxon == itemText){\n\t\t\t\t\tresultsIDs.push(this.toolStruct.taxaList[i].id);\n\t\t\t\t\tresultsText = resultsText + (j == 0 ? '' : '<br />&nbsp;&nbsp;') + itemText;\n\t\t\t\t\tfound = true;\n  \t\t\t\t}\n  \t\t\t};\n  \t\t\tif(!found){\n  \t\t\t\tnotFound = (notFound == '' ? '' : notFound + ', ') + itemText;\n  \t\t\t}\n  \t\t}\n\t\tjQuery('#'+this.toolStruct.type+'_taxa_list').append(resultsText+ ' }');\n\t\tjQuery('#'+this.toolStruct.type+'-id-button').data('toolRetValues', resultsIDs);\n\t  \tif(notFound != ''){\n\t\t\tvar comment = jQuery(this.toolStruct.mainForm+' [name=determination\\:comment]');\n\t\t\tcomment.val('" . lang::get('LANG_ID_Unrecognised') . " '+notFound+' '+comment.val());\n\t\t}\n  \t  }\n  \t }\n    });\n};\n\npollReset = function(toolStruct){\n\tclearTimeout(toolStruct.timeOutTimer);\n\tclearTimeout(toolStruct.pollTimer);\n\tjQuery('#'+toolStruct.type+'-id-cancel').hide();\n\tjQuery('#'+toolStruct.type+'-id-button').show();\n\ttoolStruct.pollFile='';\n\ttoolStruct.timeOutTimer = null;\n\ttoolStruct.pollTimer = null;\n};\n\nidButtonPressed = function(toolStruct){\n\tjQuery(toolStruct.mainForm+' [name=determination\\:determination_type]').val(toolStruct.determinationType);\n\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', []);\n\tjQuery(toolStruct.mainForm+' [name=determination\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\tjQuery(toolStruct.mainForm+' [name=determination\\:taxa_taxon_list_id]').val('');\n\tjQuery('#'+toolStruct.type+'-id-cancel').show();\n\tjQuery('#'+toolStruct.type+'-id-button').hide();\n\tvar d = new Date;\n\tvar s = d.getTime();\n\ttoolStruct.pollFile = '" . session_id() . "_'+s.toString()\n\tclearTimeout(toolStruct.timeOutTimer);\n\tclearTimeout(toolStruct.pollTimer);\n\twindow.open(toolStruct.invokeURL+toolStruct.pollFile,'','');\n\ttoolStruct.pollTimer = setTimeout('toolPoller('+toolStruct.name+');', " . $args['ID_tool_poll_interval'] . ");\n\ttoolStruct.timeOutTimer = setTimeout('toolReset('+toolStruct.name+');', " . $args['ID_tool_poll_timeout'] . ");\n};\njQuery('#flower-id-button').click(function(){\n\tidButtonPressed(flowerIDstruc);\n});\njQuery('#flower-id-cancel').click(function(){\n\tpollReset(flowerIDstruc);\n});\n\njQuery('#flower-id-cancel').hide();\n\ntaxonChosen = function(toolStruct){\n\tjQuery('#'+toolStruct.type+'-id-button').data('toolRetValues', []);\n\tjQuery(toolStruct.mainForm+' [name=determination\\:taxon_details]').val('');\n\tjQuery('#'+toolStruct.type+'_taxa_list').empty();\n\tjQuery(toolStruct.mainForm+' [name=determination\\:comment]').val('');\n  \tjQuery(toolStruct.mainForm+' [name=determination\\:determination_type]').val(toolStruct.determinationType);\n};\njQuery('form#fo-new-flower-id-form select[name=determination\\:taxa_taxon_list_id]').change(function(){\n\tpollReset(flowerIDstruc);\n\ttaxonChosen(flowerIDstruc);\n});\n\ninsectIDstruc = {\n\ttype: 'insect',\n\tmainForm: 'form#fo-new-insect-id-form',\n\ttimeOutTimer: null,\n\tpollTimer: null,\n\tpollFile: '',\n\tinvokeURL: '" . $args['ID_tool_insect_url'] . "',\n\tpollURL: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['ID_tool_insect_poll_dir']) . "',\n\tname: 'insectIDstruc',\n\tdeterminationType: '" . (user_access('IForm n' . $node->nid . ' insect expert') ? 'C' : 'A') . "',\n\ttaxaList: insectTaxa\n};\n\njQuery('#insect-id-button').click(function(){\n\tidButtonPressed(insectIDstruc);\n});\njQuery('#insect-id-cancel').click(function(){\n\tpollReset(insectIDstruc);\n});\njQuery('#insect-id-cancel').hide();\njQuery('form#fo-new-insect-id-form select[name=determination\\:taxa_taxon_list_id]').change(function(){\n\tpollReset(insectIDstruc);\n\ttaxonChosen(insectIDstruc);\n});\n\njQuery('#search-insee-button').click(function(){\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroy();\n\tpolygonLayer.map.searchLayer.destroyFeatures();\n\tpolygonLayer.destroyFeatures();\n\tvar filters = [];\n  \tvar place = jQuery('input[name=place\\:INSEE]').val();\n  \tif(place == '" . lang::get('LANG_INSEE') . "') return;\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_NEW',\n    \t\tvalue: place\n  \t\t}));\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_OLD',\n    \t\tvalue: place\n  \t\t}));\n\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tvar styleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Red\",\n                    strokeColor: \"Red\",\n                    fillOpacity: 0,\n                    strokeWidth: 1\n                  })\n\t});\n\tinseeLayer = new OpenLayers.Layer.Vector('INSEE Layer', {\n\t\t  styleMap: styleMap,\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n\t          featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['the_geom']\n  \t\t\t})\n    });\n\tinseeLayer.events.register('featuresadded', {}, function(a1){\n\t\tvar div = jQuery('#map')[0];\n\t\tdiv.map.searchLayer.destroyFeatures();\n\t\tvar bounds=inseeLayer.getDataExtent();\n    \tvar dy = (bounds.top-bounds.bottom)/10;\n    \tvar dx = (bounds.right-bounds.left)/10;\n    \tbounds.top = bounds.top + dy;\n    \tbounds.bottom = bounds.bottom - dy;\n    \tbounds.right = bounds.right + dx;\n    \tbounds.left = bounds.left - dx;\n    \t// if showing a point, don't zoom in too far\n    \tif (dy===0 && dx===0) {\n    \t\tdiv.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n    \t} else {\n    \t\tdiv.map.zoomToExtent(bounds);\n    \t}\n    });\n\tinseeLayer.events.register('loadend', {}, function(){\n\t\tif(inseeLayer.features.length == 0){\n\t\t\talert(\"" . lang::get('LANG_NO_INSEE') . "\");\n\t\t}\n    });\n    jQuery('#map')[0].map.addLayer(inseeLayer);\n\tstrategy.load({filter: new OpenLayers.Filter.Logical({\n\t\t\t      type: OpenLayers.Filter.Logical.OR,\n\t\t\t      filters: filters\n\t\t  \t  })});\n});\n\njQuery('#search-collections-button').click(function(){\n\tjQuery('#results-insects-header,#results-insects-results').hide();\n\tjQuery('#results-collections-header,#results-collections-results').show();\n\tjQuery('#results-collections-header').addClass('ui-state-active').removeClass('ui-state-default');\n\trunSearch(true);\n});\njQuery('#search-insects-button').click(function(){\n\tjQuery('#results-collections-header,#results-collections-results').hide();\n\tjQuery('#results-insects-header,#results-insects-results').show();\n\tjQuery('#results-insects-header').addClass('ui-state-active').removeClass('ui-state-default');\n\trunSearch(false);\n});\n\ncombineOR = function(ORgroup){\n\tif(ORgroup.length > 1){\n\t\treturn new OpenLayers.Filter.Logical({\n\t\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\t\tfilters: ORgroup\n\t\t\t});\n\t}\n\treturn ORgroup[0];\n};\n\nencodeMap = function(){\n\tvar features = [];\n\tif(inseeLayer != null && inseeLayer.features.length > 0)\n\t\tfeatures = inseeLayer.features;\n\telse if(polygonLayer != null && polygonLayer.features.length > 0)\n\t\tfeatures = polygonLayer.features\n\telse {\n\t\tvar mapBounds = jQuery('#map')[0].map.getExtent();\n\t\tvar feature = new OpenLayers.Feature.Vector(mapBounds.toGeometry());\n\t\tfeatures = [feature];\n\t}\n      var format=new OpenLayers.Format.GML.v2({featureName: 'user', featureType: 'user',\n          featureNS: 'user', featurePrefix: 'user'});\n      return format.write(features);\n    }\n\ndecodeMap = function(string){\n      var format=new OpenLayers.Format.GML.v2({featureName: 'user', featureType: 'user',\n          featureNS: 'user', featurePrefix: 'user'});\n      var features=format.read(string);\n\tif(inseeLayer != null) inseeLayer.destroyFeatures();\n\tif(polygonLayer!= null) polygonLayer.destroyFeatures();\n\tvar div = jQuery('#map')[0];\n\tdiv.map.searchLayer.destroyFeatures();\n\tpolygonLayer.addFeatures(features, {});\n\tvar bounds= polygonLayer.getDataExtent();\n    div.map.zoomToExtent(bounds);\n\n}\n    \nrunSearch = function(forCollections){\n  \tvar ORgroup = [];\n  \tif(searchLayer != null)\n\t\tsearchLayer.destroy();\n    jQuery('#results-collections-results,#results-insects-results').empty();\n\tjQuery('#focus-occurrence,#focus-collection').hide();\n\tvar filters = [];\n\n\t// By default restrict selection to area displayed on map. When using the georeferencing system the map searchLayer\n\t// will contain a single point zoomed in appropriately.\n\tvar mapBounds = jQuery('#map')[0].map.getExtent();\n\tif (mapBounds != null) filters.push(new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.BBOX, property: 'geom', value: mapBounds}));\n\t// should only be one entry in the inseeLayer\n\tif(inseeLayer != null)\n  \t\tif(inseeLayer.features.length > 0)\n\t\t\tfilters.push(new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.WITHIN, property: 'geom',value: inseeLayer.features[0].geometry}));\n\tif(polygonLayer != null)\n  \t\tif(polygonLayer.features.length > 0){\n  \t\t\tORgroup = [];\n  \t\t\tfor(i=0; i< polygonLayer.features.length; i++)\n\t\t\t\tORgroup.push(new OpenLayers.Filter.Spatial({type: OpenLayers.Filter.Spatial.WITHIN, property: 'geom', value: polygonLayer.features[i].geometry}));\n\t\t  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n\t\t}\n\n  \t// filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'survey_id', value: '" . $args['survey_id'] . "' }));\n\n  \tvar user = jQuery('input[name=username]').val();\n  \tif(user != '') filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'username', value: user}));\n  \tvar start_date = jQuery('input[name=real_start_date]').val();\n  \tvar end_date = jQuery('input[name=real_end_date]').val();\n  \tif(start_date != '" . lang::get('click here') . "' && start_date != '')\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO, property: 'datefin', value: start_date}));\n  \tif(end_date != '" . lang::get('click here') . "' && end_date != '')\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO, property: 'datedebut', value: end_date}));\n \t\n  \tvar flower = jQuery('select[name=flower\\:taxa_taxon_list_id]').val();\n  \tif(flower != '') filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'flower_taxon_ids', value: '*|'+flower+'|*'}));\n  \tflower = jQuery('[name=flower\\:taxon_extra_info]').val();\n  \tif(flower != '' && flower != '" . lang::get('LANG_More_Precise') . "')\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'taxons_fleur_precise', value: '*'+flower+'*' }));\n\n  \tORgroup = [];\n  \tjQuery('#flower-filter-body').find('[name^=occAttr:" . $args['flower_type_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO, property: 'flower_type_id', value: elem.value}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \tORgroup = [];\n  \tjQuery('#flower-filter-body').find('[name^=locAttr:" . $args['habitat_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'habitat_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n\n  \tvar insect = jQuery('select[name=insect\\:taxa_taxon_list_id]').val();\n  \tif(insect != '') filters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'insect_taxon_ids', value: '*|'+insect+'|*'}));\n  \tinsect = jQuery('[name=insect\\:taxon_extra_info]').val();\n  \tif(insect != '' && insect != '" . lang::get('LANG_More_Precise') . "')\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'taxons_insecte_precise', value: '*'+insect+'*'}));\n\n  \tORgroup = [];\n  \tjQuery('#conditions-filter-body').find('[name^=smpAttr:" . $args['sky_state_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'sky_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \t\n  \tORgroup = [];\n  \tjQuery('#conditions-filter-body').find('[name^=smpAttr:" . $args['temperature_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'temp_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \t\n  \tORgroup = [];\n  \tjQuery('#conditions-filter-body').find('[name^=smpAttr:" . $args['wind_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'wind_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \t\n  \tORgroup = [];\n  \tjQuery('#conditions-filter-body').find('[name^=smpAttr:" . $args['shade_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LIKE, property: 'shade_ids', value: '*|'+elem.value+'|*'}));\n  \t});\n  \tif(ORgroup.length >= 1) filters.push(combineOR(ORgroup));\n  \tif(forCollections){\n\t\tproperties = ['collection_id','datedebut','datefin','geom','nom','image_de_environment','image_de_la_fleur','flower_id']\n\t\tfeature = 'spipoll_collections_cache_view';\n  \t} else {\n  \t\tfeature = 'spipoll_insects_cache_view';\n  \t\tproperties = ['insect_id','collection_id','geom','image_d_insecte'];\n  \t}\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tsearchLayer = new OpenLayers.Layer.Vector('Search Layer', {\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['search_url']) . "',\n              featurePrefix: '" . $args['search_prefix'] . "',\n              featureType: feature,\n              geometryName:'geom',\n              featureNS: '" . $args['search_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0',   \n              maxFeatures: " . $args['max_features'] . ",\n              propertyNames: properties,\n              sortBy: 'datedebut' // not supported by Openlayers, so have to use orderby in a DB view.\n\t\t  })\n\t});\n\tif(forCollections) {\n\t\tjQuery('#results-collections-results').empty().append('<div class=\"collection-loading-panel\" ><img src=\"" . helper_config::$base_url . "media/images/ajax-loader2.gif\" />" . lang::get('loading') . "...</div>');\n\t\tsearchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tsearchResults = a1;\n\t\t\tsearchResults.type = 'C';\n\t\t\tif(searchResults.features.length >= " . $args['max_features'] . "){\n\t\t\t\talert(\"" . lang::get('LANG_Max_Features_Reached') . "\");\n\t\t\t}\n\t\t\tsetCollectionPage(1);\n\t\t});\n\t\tsearchLayer.events.register('loadend', {}, function(){\n\t\t\tif(searchLayer.features.length == 0){\n\t\t\t\tjQuery('#results-collections-results').empty().text('" . lang::get('LANG_No_Collection_Results') . "');\n\t\t\t}\n\t\t});\n\t} else {\n\t\tjQuery('#results-insects-results').empty().append('<div class=\"insect-loading-panel\" ><img src=\"" . helper_config::$base_url . "media/images/ajax-loader2.gif\" />" . lang::get('loading') . "...</div>');\n\t\tsearchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tsearchResults = a1;\n\t\t\tsearchResults.type = 'I';\n\t\t\tif(searchResults.features.length >= " . $args['max_features'] . "){\n\t\t\t\talert(\"" . lang::get('LANG_Max_Features_Reached') . "\");\n\t\t\t}\n\t\t\tsetInsectPage(1);\n\t\t});\n\t\tsearchLayer.events.register('loadend', {}, function(){\n\t\t\tif(searchLayer.features.length == 0){\n\t\t\t\tjQuery('#results-insects-results').empty().text('" . lang::get('LANG_No_Insect_Results') . "');\n\t\t\t}\n\t\t});\n\t}\n\tjQuery('#map')[0].map.addLayer(searchLayer);\n\tstrategy.load({filter: new OpenLayers.Filter.Logical({\n\t\t\t      type: OpenLayers.Filter.Logical.AND,\n\t\t\t      filters: filters\n\t\t  \t  })});\n};\n\nsearchResults = null;  \ncollection = '';\n\nerrorPos = null;\nclearErrors = function(formSel) {\n\tjQuery(formSel).find('.inline-error').remove();\n\terrorPos = null;\n};\n\nmyScrollToError = function(){\n\tjQuery('.inline-error,.error').filter(':visible').prev().each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\n\nvalidateRequiredField = function(name, formSel){\n    var control = jQuery(formSel).find('[name='+name+']');\n    if(control.val() == '') {\n        var label = \$('<p/>')\n\t\t\t\t.attr({'for': name})\n\t\t\t\t.addClass('inline-error')\n\t\t\t\t.html(\$.validator.messages.required);\n\t\tlabel.insertBefore(control);\n\t\treturn false;\n    }\n    return true;\n}\n\nvar insect_alert_object = {\n\tinsect_id: null,\n\tinsect_image_path: null,\n\tdate: null,\n\tuser_id: null,\n\tcollection_user_id: null,\n\tdetails: []\n};\nvar flower_alert_object = {\n\tflower_id: null,\n\tflower_image_path: null,\n\tdate: null,\n\tuser_id: null,\n\tcollection_user_id: null,\n\tdetails: []\n};\n\nvar collection_preferred_object = {\n\tcollection_id: null,\n\tcollection_name: null,\n\tflower_id: null,\n\tflower_image_path: null,\n\tenvironment_image_path: null,\n\tdate: null,\n\tlocation_description: null,\n\tuser_id: null,\n\tinsects: []\n};\n\njQuery('form#fo-express-doubt-form').ajaxForm({\n\tasync: false,\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif(!confirm(\"" . lang::get('LANG_Confirm_Express_Doubt') . "\")){\n\t\t\treturn FALSE;\n\t\t}\t\n\t\tvar toolValues = jQuery('#fo-doubt-button').data('toolRetValues');\n\t\tif(toolValues.length == 0)\n\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: ''});\n\t\telse {\n\t\t\tfor(var i = 0; i<toolValues.length; i++){\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: toolValues[i]});\n\t\t\t}\n\t\t}\n  \t\tjQuery('#doubt_submit_button').addClass('loading-button');\n   \t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('#fo-express-doubt').removeClass('ui-accordion-content-active');\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id', insect_alert_object.insect_id == null ? 'form#fo-new-flower-id-form' : 'form#fo-new-insect-id-form', function(args, type){\n\t\t\t";
        if ($args['alert_js_function'] != '') {
            data_entry_helper::$javascript .= "\n\t\t\t\tif(type == 'F'){\n\t\t\t\t\tflower_alert_object.details = [];\n\t\t\t\t\tfor(i=0; i< args.length && i < 5; i++){\n\t\t\t\t\t\tflower_alert_object.details.push({flower_taxa: args[i].taxa, date: args[i].date, user_id: args[i].user_id});\n\t\t\t\t\t\tflower_alert_object.date = flower_alert_object.details[0].date;\n\t\t\t\t\t}\n\t\t\t\t\tflower_alert_object.details = JSON.stringify(flower_alert_object.details);\n\t\t\t\t\t" . $args['alert_js_function'] . "({alert_type: 'D', type: 'F', flower: flower_alert_object});\n\t\t\t\t} else {\n\t\t\t\t\tinsect_alert_object.details = [];\n\t\t\t\t\tfor(i=0; i< args.length && i < 5; i++){\n\t\t\t\t\t\tinsect_alert_object.details.push({insect_taxa: args[i].taxa, date: args[i].date, user_id: args[i].user_id});\n\t\t\t\t\t\tinsect_alert_object.date = insect_alert_object.details[0].date;\n\t\t\t\t\t}\n\t\t\t\t\tinsect_alert_object.details = JSON.stringify(insect_alert_object.details);\n\t\t\t\t\t" . $args['alert_js_function'] . "({alert_type: 'D', type: 'I', insect: insect_alert_object});\n\t\t\t\t}";
        }
        data_entry_helper::$javascript .= "\n\t\t\t}, insect_alert_object.insect_id == null ? " . (user_access('IForm n' . $node->nid . ' flower expert') ? '1' : '0') . " : " . (user_access('IForm n' . $node->nid . ' insect expert') ? '1' : '0') . ",\n\t\t\tinsect_alert_object.insect_id == null ? " . (user_access('IForm n' . $node->nid . ' flag dubious flower') ? '1' : '0') . " : " . (user_access('IForm n' . $node->nid . ' flag dubious insect') ? '1' : '0') . ",\n\t\t\tinsect_alert_object.insect_id == null ? flowerTaxa : insectTaxa,\n\t\t\tinsect_alert_object.insect_id == null ? 'F' : 'I');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t},\n\tcomplete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t} \n});\n\njQuery('form#fo-new-insect-id-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tvar valid = true;\n\t\tclearErrors('form#fo-new-insect-id-form');\n\t\tif (!jQuery('form#fo-new-insect-id-form input').valid()) { valid = false; }\n\t\tif (jQuery('form#fo-new-insect-id-form [name=determination\\:taxon_details]').val() == ''){\n\t\t\tif (!validateRequiredField('determination\\:taxa_taxon_list_id', '#fo-new-insect-id-form')) {\n\t\t\t\tvalid = false;\n  \t\t\t} else {\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: ''});\n  \t\t\t}\n\t\t} else {\n\t\t\tvar toolValues = jQuery('#insect-id-button').data('toolRetValues');\n\t\t\tfor(var i = 0; i<toolValues.length; i++){\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: toolValues[i]});\n\t\t\t}\t\t\t\n\t\t}\n   \t\tif ( valid == false ) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n  \t\tjQuery('#insect_id_submit_button').addClass('loading-button');\n   \t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery(insectIDstruc.mainForm+' [name=determination\\:determination_type]').val(insectIDstruc.determinationType);\n\t\t\tjQuery(insectIDstruc.mainForm+' [name=determination\\:taxa_taxon_list_id],[name=determination\\:comment],[name=determination\\:taxon_details],[name=determination\\:taxon_extra_info]').val('');\n\t\t\tjQuery('#insect_taxa_list').empty();\n\t\t\tjQuery('#fo-new-insect-id').removeClass('ui-accordion-content-active');\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id', 'form#fo-new-insect-id-form', function(args, type){\n\t\t\t";
        if ($args['alert_js_function'] != '') {
            data_entry_helper::$javascript .= "\n\t\t\t\tinsect_alert_object.details = [];\n\t\t\t\tfor(i=0; i< args.length && i < 5; i++){\n\t\t\t\t\tinsect_alert_object.details.push({insect_taxa: args[i].taxa, date: args[i].date, user_id: args[i].user_id});\n\t\t\t\t\tinsect_alert_object.date = insect_alert_object.details[0].date;\n\t\t\t\t}\n\t\t\t\tinsect_alert_object.details = JSON.stringify(insect_alert_object.details);\n\t\t\t\t" . $args['alert_js_function'] . "({alert_type: 'R', type: 'I', insect: insect_alert_object});";
        }
        data_entry_helper::$javascript .= "\n\t\t\t  \t\t\t}, " . (user_access('IForm n' . $node->nid . ' insect expert') ? '1' : '0') . ", " . (user_access('IForm n' . $node->nid . ' flag dubious insect') ? '1' : '0') . ", insectTaxa, 'I');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t},\n\tcomplete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n\t\n});\njQuery('form#fo-new-flower-id-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tvar valid = true;\n\t\tclearErrors('form#fo-new-flower-id-form');\n\t\tif (!jQuery('form#fo-new-flower-id-form input').valid()) { valid = false; }\n\t\tif (jQuery('form#fo-new-flower-id-form [name=determination\\:taxon_details]').val() == ''){\n\t\t\tif (!validateRequiredField('determination\\:taxa_taxon_list_id', '#fo-new-flower-id-form')) {\n\t\t\t\tvalid = false;\n  \t\t\t} else {\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: ''});\n  \t\t\t}\n\t\t} else {\n\t\t\tvar toolValues = jQuery('#flower-id-button').data('toolRetValues');\n\t\t\tfor(var i = 0; i<toolValues.length; i++){\n\t\t\t\tdata.push({name: 'determination\\:taxa_taxon_list_id_list[]', value: toolValues[i]});\n\t\t\t}\t\t\t\n\t\t}\n   \t\tif ( valid == false ) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n  \t\tjQuery('#flower_id_submit_button').addClass('loading-button');\n   \t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery(flowerIDstruc.mainForm+' [name=determination\\:determination_type]').val(flowerIDstruc.determinationType);\n\t\t\tjQuery(flowerIDstruc.mainForm+' [name=determination\\:taxa_taxon_list_id],[name=determination\\:comment],[name=determination\\:taxon_details],[name=determination\\:taxon_extra_info]').val('');\n\t\t\tjQuery('#flower_taxa_list').empty();\n\t\t\tjQuery('#fo-new-flower-id').removeClass('ui-accordion-content-active');\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id', 'form#fo-new-flower-id-form', function(args, type){\n\t\t\t";
        if ($args['alert_js_function'] != '') {
            data_entry_helper::$javascript .= "\n\t\t\t\tflower_alert_object.details = [];\n\t\t\t\tfor(i=0; i< args.length && i < 5; i++) {\n\t\t\t\t\tflower_alert_object.details.push({flower_taxa: args[i].taxa, date: args[i].date, user_id: args[i].user_id});\n\t\t\t\t\tflower_alert_object.date = flower_alert_object.details[0].date;\n\t\t\t\t}\n\t\t\t\tflower_alert_object.details = JSON.stringify(flower_alert_object.details);\n\t\t\t\t" . $args['alert_js_function'] . "({alert_type: 'R', type: 'F', flower: flower_alert_object});";
        }
        data_entry_helper::$javascript .= "\n\t\t\t  \t\t\t}, " . (user_access('IForm n' . $node->nid . ' flower expert') ? '1' : '0') . ", " . (user_access('IForm n' . $node->nid . ' flag dubious flower') ? '1' : '0') . ", flowerTaxa, 'F');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t},\n\tcomplete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n\t\n});\njQuery('#fo-new-comment-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n\t// success identifies the function to invoke when the server response \n\t// has been received \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fo-new-comment-form').valid()) { return false; }\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('[name=occurrence_comment\\:comment]').val('');\n\t\t\tjQuery('#fo-new-comment').removeClass('ui-accordion-content-active');\n\t\t\tloadComments(jQuery('[name=occurrence_comment\\:occurrence_id]').val(), '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body', true);\n  \t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('#fc-new-comment-form').ajaxForm({ \n\tasync: false,\n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fc-new-comment-form').valid()) { return false; }\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('[name=sample_comment\\:comment]').val('');\n\t\t\tjQuery('#fc-new-comment').removeClass('ui-accordion-content-active');\n\t\t\tloadComments(jQuery('[name=sample_comment\\:sample_id]').val(), '#fc-comment-list', 'sample_comment', 'sample_id', 'sample-comment-block', 'sample-comment-body', true);\n  \t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\n\nloadSampleAttributes = function(keyValue){\n    jQuery('#fo-insect-start-time,#fo-insect-end-time,#fo-insect-sky,#fo-insect-temp,#fo-insect-wind,#fo-insect-shade').empty();\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample_attribute_value\"  +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&sample_id=\" + keyValue + \"&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id && (attrdata[i].iso == null || attrdata[i].iso == '' || attrdata[i].iso == '" . $language . "')){\n\t\t\t\t\tswitch(parseInt(attrdata[i].sample_attribute_id)){\n\t\t\t\t\t\tcase " . $args['start_time_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-start-time').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase " . $args['end_time_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-end-time').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['sky_state_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-sky').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['temperature_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-temp').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['wind_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-wind').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['shade_attr_id'] . ":\n  \t\t\t\t\t\t\tif(attrdata[i].value == '1'){\n\t\t\t\t\t\t\t\tjQuery('#fo-insect-shade').append(\"" . lang::get('Yes') . "\");\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery('#fo-insect-shade').append(\"" . lang::get('No') . "\");\n  \t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}));\n}\nloadOccurrenceAttributes = function(keyValue){\n    jQuery('#focus-flower-type').empty();\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence_attribute_value\"  +\n\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&occurrence_id=\" + keyValue + \"&iso=" . $language . "&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].occurrence_attribute_id)){\n\t\t\t\t\t\tcase " . $args['flower_type_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+'</span>').appendTo('#focus-flower-type');\n\t\t\t\t\t\t\tbreak;\n  \t}}}}}));\n}\nloadLocationAttributes = function(keyValue){\n    jQuery('#focus-habitat').empty();\n\tajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/location_attribute_value\"  +\n\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&location_id=\" + keyValue + \"&iso=" . $language . "&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n   \t\t\tvar habitat_string = '';\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].location_attribute_id)){\n\t\t\t\t\t\tcase " . $args['habitat_attr_id'] . ":\n\t\t\t\t\t\t\thabitat_string = (habitat_string == '' ? attrdata[i].value : (habitat_string + ' | ' + attrdata[i].value));\n\t\t\t\t\t\t\tbreak;\n\t\t\t}}}\n\t\t\tjQuery('<span>'+habitat_string+'</span>').appendTo('#focus-habitat');\n  }}));\n}\n\ninsertImage = function(path, target, ratio, callback){\n    var img = new Image();\n\tjQuery(img).load(function () {\n        target.append(this);\n        if(this.width/this.height > ratio){\n\t    \tjQuery(this).css('width', '100%').css('height', 'auto').css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n  \t\t} else {\n\t        jQuery(this).css('width', (100*this.width/(this.height*ratio))+'%').css('height', 'auto').css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n  \t\t}\n  \t\tif(callback)\n  \t\t\tcallback(this);\n\t}).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "'+path);\n}\n\nloadImage = function(imageTable, key, keyValue, target, imageRatio, callback, prepend, imgCallback){\n    jQuery(target).empty();\n    ajaxStack.push(jQuery.ajax({ \n        type: \"GET\",\n        myTarget: target,\n        myCallback: callback,\n        myPrepend: prepend,\n        myImgCallback: imgCallback,\n        url: \"" . $svcUrl . "/data/\" + imageTable +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&REMOVEABLEJSONP&callback=?\", \n        success: function(imageData) {\n\t\t  if(!(imageData instanceof Array)){\n   \t\t\talertIndiciaError(imageData);\n   \t\t  } else if (imageData.length>0) {\n \t\t\tinsertImage(this.myPrepend+imageData[0].path, jQuery(this.myTarget), imageRatio, this.myImgCallback);\n\t\t\tif(this.myCallback) this.myCallback(imageData[0]);\n\t\t  }},\n\t\tdataType: 'json'\n\t}));\n}\n\nloadDeterminations = function(keyValue, historyID, currentID, lookup, callback, expert, can_doubt, taxaList, type){\n    jQuery(historyID).empty().append('<strong>" . lang::get('LANG_History_Title') . "</strong>');\n\tjQuery(currentID).empty();\n\tjQuery('#poll-banner').empty();\n\tjQuery('#fo-doubt-button').hide();\n\tjQuery('#fo-express-doubt-form').find('[name=determination:taxon_extra_info]').val('');\n\tjQuery('#fo-express-doubt-form').find('[name=determination:taxa_taxon_list_id]').val('');\n\tjQuery('#fo-doubt-button').data('toolRetValues',[]);\n\tjQuery('.poll-id-button').data('toolRetValues',[]);\n\tjQuery('#fo-warning').addClass('occurrence-ok').removeClass('occurrence-dubious').removeClass('occurrence-unknown');\n\tjQuery('.taxa_list').empty();\n    ajaxStack.push(jQuery.ajax({ \n        type: \"GET\", \n        url: \"" . $svcUrl . "/data/determination?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&reset_timeout=true&orderby=id&REMOVEABLEJSONP&callback=?&occurrence_id=\" + keyValue,\n        myCurrentID: currentID,\n        myHistoryID: historyID,\n        myCallback: callback,\n        myLookup: lookup,\n\t\tdataType: 'json',\n        success: function(detData) {\n   \t\t  var callbackArgs = [];\n   \t\t  if(!(detData instanceof Array)){\n   \t\t\talertIndiciaError(detData);\n   \t\t  } else if (detData.length>0) {\n\t\t\tvar i = detData.length-1;\n\t\t\tvar callbackEntry = {date: detData[i].updated_on, user_id: detData[i].cms_ref, taxa: []};\n   \t\t\tjQuery('#fo-express-doubt-form').find('[name=determination\\:occurrence_id]').val(detData[i].occurrence_id);\n   \t\t\tvar string = '';\n   \t\t\tvar resultsText = \"" . lang::get('LANG_Taxa_Returned') . "<br />{ \";\n\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\tstring = detData[i].taxon;\n\t\t\t\tcallbackEntry.taxa.push(detData[i].taxon);\n  \t\t\t}\n\t\t\tjQuery('#fo-express-doubt-form').find('[name=determination\\:taxa_taxon_list_id]').val(detData[i].taxa_taxon_list_id);\n\t\t\tjQuery(this.myLookup).find('[name=determination:taxa_taxon_list_id]').val(detData[i].taxa_taxon_list_id);\n\t\t\tif(detData[i].taxa_taxon_list_id_list != null && detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != '{}'){\n\t\t\t  \tresultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t  \tfor(j=0; j < resultsIDs.length; j++){\n\t\t\t\t\tfor(k = 0; k< taxaList.length; k++)\n\t\t\t\t\t\tif(taxaList[k].id == resultsIDs[j]) {\n\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + taxaList[k].taxon;\n\t\t\t\t\t\t\tcallbackEntry.taxa.push(taxaList[k].taxon);\n\t\t\t\t\t\t\tresultsText = resultsText + (j == 0 ? '' : '<br />&nbsp;&nbsp;') + taxaList[k].taxon;\n  \t\t\t\t\t\t}\n\t\t  \t\t}\n\t  \t\t\tif(resultsIDs.length>1 || resultsIDs[0] != '') {\n\t\t\t\t\tjQuery('#fo-doubt-button').data('toolRetValues',resultsIDs);\n\t\t\t\t\tjQuery('.poll-id-button').data('toolRetValues',resultsIDs);\n\t\t\t\t\tjQuery('.taxa_list').append(resultsText+ ' }');\n\t\t\t\t}\n\t\t\t}\n\t\t\tcallbackArgs.push(callbackEntry);\n\t\t\tjQuery('#poll-banner').append(string);\n\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\tstring = (string == '' ? '' : string + ' ') + '('+detData[i].taxon_extra_info+')';\n\t\t\t}\n\t\t\tjQuery('#fo-express-doubt-form').find('[name=determination\\:taxon_extra_info]').val(detData[i].taxon_extra_info);\n\t\t\tjQuery(this.myLookup).find('[name=determination:taxon_extra_info]').val(detData[i].taxon_extra_info);\n\t\t\tif(string != '')\n\t\t\t\tjQuery('<p><strong>'+string+ '</strong> " . lang::get('LANG_Comment_By') . "' + detData[i].person_name + ' ' + convertDate(detData[i].updated_on,false) + '</p>').appendTo(this.myCurrentID)\n\t\t\telse\n\t\t\t\tjQuery('<p>" . lang::get('LANG_Comment_By') . "' + detData[i].person_name + ' ' + convertDate(detData[i].updated_on,false) + '</p>').appendTo(this.myCurrentID)\n\t\t\tif(detData[i].determination_type == 'A' && (expert || can_doubt)){\n\t\t\t\tjQuery('#fo-doubt-button').show();\n\t\t\t} else if(detData[i].determination_type == 'B'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Doubt_Expressed') . "</p>\").appendTo(this.myCurrentID);\n\t\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-dubious');\n\t\t\t} else if(detData[i].determination_type == 'C'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Valid') . "</p>\").appendTo(this.myCurrentID);\n\t\t\t\tif(!expert)\n\t\t\t\t\tjQuery('.new-id-button').hide();\n\t\t\t} else if(detData[i].determination_type == 'I'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Incorrect') . "</p>\").appendTo(this.myCurrentID);\n\t\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-dubious');\n\t\t\t} else if(detData[i].determination_type == 'U'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Unconfirmed') . "</p>\").appendTo(this.myCurrentID);\n\t\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-dubious');\n\t\t\t} else if(detData[i].determination_type == 'X'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Unknown') . "</p>\").appendTo(this.myCurrentID);\n//\t\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-unknown');\n\t\t\t}\n\t\t\tif(detData[i].comment != '' && detData[i].comment != null){\n\t\t\t\tjQuery('<p>'+detData[i].comment+'</p>').appendTo(this.myCurrentID);\n\t\t\t}\n\t\t\t\n\t\t\tfor(i=detData.length - 2; i >= 0; i--){ // deliberately miss last one, in reverse order\n\t\t\t\tcallbackEntry = {date: detData[i].updated_on, user_id: detData[i].cms_ref, taxa: []};\n\t\t\t\tstring = '';\n\t\t\t\tvar item = jQuery('<div></div>').addClass('history-item').appendTo(this.myHistoryID);\n\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\tstring = detData[i].taxon;\n\t\t  \t\t\tcallbackEntry.taxa.push(detData[i].taxon);\n  \t\t\t\t}\n\t\t\t\tif(detData[i].taxa_taxon_list_id_list != '' && detData[i].taxa_taxon_list_id_list != null && detData[i].taxa_taxon_list_id_list != '{}'){\n\t\t\t\t\tvar resultsIDs = detData[i].taxa_taxon_list_id_list.substring(1, detData[i].taxa_taxon_list_id_list.length - 1).split(',');\n\t\t\t\t\tfor(j=0; j < resultsIDs.length; j++){\n\t\t\t\t\t\tfor(k = 0; k< taxaList.length; k++)\n\t\t\t\t\t\t\tif(taxaList[k].id == resultsIDs[j]) {\n\t\t\t\t\t\t\t\tstring = (string == '' ? '' : string + ', ') + taxaList[k].taxon;\n\t\t\t\t\t\t\t\tcallbackEntry.taxa.push(taxaList[k].taxon);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\t\tstring = (string == '' ? '' : string + ' ') + '('+detData[i].taxon_extra_info+')' ;\n\t\t\t\t}\n\t\t\t\tstring = convertDate(detData[i].updated_on,false) + ' : ' + string;\n\t\t\t\tjQuery('<p><strong>'+string+ '</strong> " . lang::get('LANG_Comment_By') . "' + detData[i].person_name+'</p>').appendTo(item)\n\t\t\t\tif(detData[i].determination_type == 'B'){\n\t\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Doubt_Expressed') . "</p>\").appendTo(item)\n\t\t\t\t} else if(detData[i].determination_type == 'I'){\n\t\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Incorrect') . "</p>\").appendTo(item)\n\t\t\t\t} else if(detData[i].determination_type == 'U'){\n\t\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Unconfirmed') . "</p>\").appendTo(item)\n\t\t\t\t} else if(detData[i].determination_type == 'X'){\n\t\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Determination_Unknown') . "</p>\").appendTo(item)\n\t\t\t\t}\n\t\t\t\tif(detData[i].comment != '' && detData[i].comment != null){\n\t\t\t\t\tjQuery('<p>'+detData[i].comment+'</p>').appendTo(item);\n\t\t\t\t}\n\t\t\t\tcallbackArgs.push(callbackEntry);\n  \t\t\t}\n\t\t\t\n\t\t  } else {\n\t\t\tjQuery('#fo-doubt-button').hide();\n\t\t\tjQuery('#fo-warning').removeClass('occurrence-ok').addClass('occurrence-unknown');\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Determinations') . "</p>')\n\t\t\t\t\t.appendTo(this.myHistoryID);\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Determinations') . "</p>')\n\t\t\t\t\t.appendTo(this.myCurrentID);\n\t\t  }\n\t\t  if(this.myCallback) this.myCallback(callbackArgs, type);\n\t\t}  \n\t}));\n\t// when the occurrence is loaded (eg in loadInsect) all determination:occurrence_ids are set.\n\tjQuery(lookup).find('[name=determination\\:determination_type]').val(expert ? 'C' : 'A');\n};\n\nloadComments = function(keyValue, block, table, key, blockClass, bodyClass, reset_timeout){\n    jQuery(block).empty();\n    ajaxStack.push(jQuery.ajax({ \n        type: \"GET\",\n        url: \"" . $svcUrl . "/data/\" + table + \"?mode=json&view=list\" +\n        \t(reset_timeout ? \"&reset_timeout=true\" : \"\") + \"&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&REMOVEABLEJSONP&callback=?\", \n        myBlock: block,\n        myBlockClass: blockClass,\n        myBodyClass: bodyClass,\n\t\tdataType: 'json',\n        success: function(commentData) {\n   \t\t  if(!(commentData instanceof Array)){\n   \t\t\talertIndiciaError(commentData);\n   \t\t  } else if (commentData.length>0) {\n   \t\t\tfor(i=commentData.length - 1; i >= 0; i--){\n\t   \t\t\tvar newCommentDetails = jQuery('<div class=\"'+this.myBlockClass+'\"/>')\n\t\t\t\t\t.appendTo(block);\n\t\t\t\tjQuery('<span>" . lang::get('LANG_Comment_By') . "' + commentData[i].person_name + ' ' + convertDate(commentData[i].updated_on,false) + '</span>')\n\t\t\t\t\t.appendTo(newCommentDetails);\n\t   \t\t\tvar newComment = jQuery('<div class=\"'+bodyClass+'\"/>')\n\t\t\t\t\t.appendTo(this.myBlock);\n\t\t\t\tjQuery('<p>' + commentData[i].comment + '</p>')\n\t\t\t\t\t.appendTo(newComment);\n\t\t\t}\n\t\t  } else {\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Comments') . "</p>')\n\t\t\t\t\t.appendTo(this.myBlock);\n\t\t  }\n\t\t}\n    }));\n};\n\ncollectionProcessing = function(keyValue, expert){\n    ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample_attribute_value\"  +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&sample_id=\" + keyValue + \"&REMOVEABLEJSONP&callback=?\", function(attrdata) {\n\t\tif(!(attrdata instanceof Array)){\n   \t\t\talertIndiciaError(attrdata);\n   \t\t} else if (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].sample_attribute_id)){\n\t\t\t\t\t\tcase " . $args['uid_attr_id'] . ":\n\t\t\t\t\t\t\tinsect_alert_object.collection_user_id = attrdata[i].value;\n\t\t\t\t\t\t\tflower_alert_object.collection_user_id = attrdata[i].value;\n\t\t\t\t\t\t\tif(!expert && parseInt(attrdata[i].value) != " . $uid . ")\n\t\t\t\t\t\t\t\tjQuery('.new-id-button').hide();\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n    }));\n}\n\nloadInsectAddnInfo = function(keyValue, collectionIndex){\n    // TODO convert buttons into thumbnails\n\tcollection = '';\t\n\t// fetch occurrence details first to get the sample_id.\n\t// Get the sample to get the parent_id.\n\t// get all the samples (sessions) with the same parent_id;\n\t// fetch all the occurrences of the sessions.\n    ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" + keyValue +\n   \t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&REMOVEABLEJSONP&callback=?\", function(occData) {\n   \t\tif(!(occData instanceof Array)){\n   \t\t\talertIndiciaError(occData);\n   \t\t} else if (occData.length > 0) {\n            ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample/\" + occData[0].sample_id +\n   \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&REMOVEABLEJSONP&callback=?\", function(smpData) {\n   \t\t\t\tif(!(smpData instanceof Array)){\n   \t\t\t\t\talertIndiciaError(smpData);\n   \t\t\t\t} else if (smpData.length > 0) {\n   \t\t\t\t\tcollection = smpData[0].parent_id;\n\t\t\t\t\tcollectionProcessing(collection, " . (user_access('IForm n' . $node->nid . ' insect expert') ? "true" : "false") . ");\n\t\t\t\t\tjQuery('#fo-insect-date').empty().append(convertDate(smpData[0].date_start,false));\n\t\t\t\t\tloadSampleAttributes(smpData[0].id);\n\t\t\t\t\tjQuery('#fo-collection-button').data('smpID',smpData[0].parent_id).data('collectionIndex', collectionIndex).show();\n  \t\t\t\t}\n   \t\t   \t  }));\n   \t\t}\n    }));\n}\nloadFlowerAddnInfo = function(keyValue, collectionIndex){\n    // fetch occurrence details first to get the collection id.\n    loadOccurrenceAttributes(keyValue);\n    ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" + keyValue +\n   \t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&REMOVEABLEJSONP&callback=?\", function(occData) {\n   \t\tif(!(occData instanceof Array)){\n   \t\t\talertIndiciaError(occData);\n   \t\t} else if (occData.length > 0) {\n\t\t\tjQuery('#fo-collection-button').data('smpID',occData[0].sample_id).data('collectionIndex',collectionIndex).show();\n\t\t\tcollectionProcessing(occData[0].sample_id, " . (user_access('IForm n' . $node->nid . ' flower expert') ? "true" : "false") . ");\n            ajaxStack.push(\$.getJSON(\"" . $svcUrl . "/data/sample/\" + occData[0].sample_id +\n   \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&REMOVEABLEJSONP&callback=?\", function(collection) {\n   \t\t\t\tif(!(collection instanceof Array)){\n   \t\t\t\t\talertIndiciaError(collection);\n   \t\t\t\t} else if (collection.length > 0) {\n\t\t\t\t\tloadLocationAttributes(collection[0].location_id);\n  \t\t\t\t}\n   \t\t   \t  }));\n   \t\t}\n    }));\n}\n\nloadInsect = function(insectID, collectionIndex, insectIndex, type){\n    abortAjax();\n\tjQuery('#fo-prev-button,#fo-next-button').hide();\n\tjQuery('#fo-filter-button').show();\n\tif(type == 'S'){ // called from search\n\t\tif(insectIndex > 0)\n\t\t\tjQuery('#fo-prev-button').show().data('occID', searchResults.features[insectIndex-1].attributes.insect_id).data('collectionIndex', null).data('insectIndex', insectIndex-1).data('type', 'S');\n\t\tif(insectIndex < searchResults.features.length-1)\n\t\t\tjQuery('#fo-next-button').show().data('occID', searchResults.features[insectIndex+1].attributes.insect_id).data('collectionIndex', null).data('insectIndex', insectIndex+1).data('type', 'S');\n\t} else if(type == 'C'){ // called from collection\n\t\tjQuery('#fo-filter-button').hide();\n\t\tvar myThumb = jQuery('.collection-insect').filter('[occID='+insectID+']').prev();\n\t\tif(myThumb.length > 0)\n\t\t\tjQuery('#fo-prev-button').show().data('occID', myThumb.attr('occID')).data('collectionIndex', collectionIndex).data('insectIndex', null).data('type', 'C');\n\t\tmyThumb = jQuery('.collection-insect').filter('[occID='+insectID+']').next();\n\t\tif(myThumb.length > 0)\n\t\t\tjQuery('#fo-next-button').show().data('occID', myThumb.attr('occID')).data('collectionIndex', collectionIndex).data('insectIndex', null).data('type', 'C');\t\t\n  \t} else if(type == 'P'){ // called from photoreel\n\t\tvar myThumb = jQuery('.thumb').filter('[occID='+insectID+']').prev();\n\t\tif(myThumb.length > 0)\n\t\t\tjQuery('#fo-prev-button').show().data('occID', myThumb.attr('occID')).data('collectionIndex', collectionIndex).data('insectIndex', null).data('type', 'P');\n\t\tmyThumb = jQuery('.thumb').filter('[occID='+insectID+']').next();\n\t\tif(myThumb.length > 0)\n\t\t\tjQuery('#fo-next-button').show().data('occID', myThumb.attr('occID')).data('collectionIndex', collectionIndex).data('insectIndex', null).data('type', 'P');\t\t\n\t}\n\tinsect_alert_object.insect_id = insectID;\n\tinsect_alert_object.user_id = \"" . $uid . "\";\n\tflower_alert_object.flower_id = null;\n\tjQuery('#focus-collection,#filter,#fo-flower-addn-info').hide();\n    jQuery('#focus-occurrence,#fo-addn-info-header,#fo-insect-addn-info').show();\n\tjQuery('[name=determination\\:occurrence_id]').val(insectID);\n\tjQuery('[name=occurrence_comment\\:occurrence_id]').val(insectID);\n\tjQuery('#fo-new-comment,#fo-new-insect-id,#fo-new-flower-id,#fo-express-doubt').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-new-insect-id-button').show();\n\tjQuery('#fo-new-flower-id-button').hide();\n\tjQuery('#fo-new-comment-button')." . (user_access('IForm n' . $node->nid . ' insect expert') || user_access('IForm n' . $node->nid . ' create insect comment') ? "show()" : "hide()") . ";\n\tloadDeterminations(insectID, '#fo-id-history', '#fo-current-id', 'form#fo-new-insect-id-form', null, " . (user_access('IForm n' . $node->nid . ' insect expert') ? '1' : '0') . ", " . (user_access('IForm n' . $node->nid . ' flag dubious insect') ? '1' : '0') . ", insectTaxa, 'I');\n\tloadImage('occurrence_image', 'occurrence_id', insectID, '#fo-image', " . $args['Insect_Image_Ratio'] . ", function(imageRecord){insect_alert_object.insect_image_path = imageRecord.path}, '', false);\n\tloadInsectAddnInfo(insectID, collectionIndex);\n\tloadComments(insectID, '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body', false);\n\tmyScrollTo('#poll-banner');\n}\nloadFlower = function(flowerID, collectionIndex){\n    abortAjax();\n\tinsect_alert_object.insect_id = null;\n\tflower_alert_object.flower_id = flowerID;\n\tflower_alert_object.user_id = \"" . $uid . "\";\n\tjQuery('#fo-filter-button').show();\n\tjQuery('#fo-prev-button,#fo-next-button').hide(); // only one flower per collection, and don't search flowers: no next or prev buttons.\n\tjQuery('#focus-collection,#filter,#fo-insect-addn-info').hide();\n\tjQuery('#focus-occurrence,#fo-addn-info-header,#fo-flower-addn-info').show();\n\tjQuery('#fo-new-comment,#fo-new-insect-id,#fo-new-flower-id,#fo-express-doubt').removeClass('ui-accordion-content-active');\n\tjQuery('[name=determination\\:occurrence_id]').val(flowerID);\n\tjQuery('[name=occurrence_comment\\:occurrence_id]').val(flowerID);\n\tjQuery('#fo-new-flower-id-button').show();\n\tjQuery('#fo-new-insect-id-button').hide();\n\tjQuery('#fo-new-comment-button')." . (user_access('IForm n' . $node->nid . ' flower expert') || user_access('IForm n' . $node->nid . ' create flower comment') ? "show()" : "hide()") . ";\n\tloadDeterminations(flowerID, '#fo-id-history', '#fo-current-id', 'form#fo-new-flower-id-form', null, " . (user_access('IForm n' . $node->nid . ' flower expert') ? '1' : '0') . ", " . (user_access('IForm n' . $node->nid . ' flag dubious flower') ? '1' : '0') . ", flowerTaxa, 'F');\n\tloadImage('occurrence_image', 'occurrence_id', flowerID, '#fo-image', " . $args['Flower_Image_Ratio'] . ", function(imageRecord){flower_alert_object.flower_image_path = imageRecord.path}, '', false);\n\tloadFlowerAddnInfo(flowerID, collectionIndex);\n\tloadComments(flowerID, '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body', false);\n\tmyScrollTo('#poll-banner');\n}\n\naddDrawnGeomToSelection = function(geometry) {\n   \t// Create the polygon as drawn\n   \tvar feature = new OpenLayers.Feature.Vector(geometry, {});\n   \tpolygonLayer.addFeatures([feature]);\n};\n\nMyEditingToolbar=OpenLayers.Class(\n\t\tOpenLayers.Control.Panel,{\n\t\t\tinitialize:function(layer,options){\n\t\t\t\tOpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);\n\t\t\t\tthis.addControls([new OpenLayers.Control.Navigation()]);\n\t\t\t\tvar controls=[new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon', drawFeature: addDrawnGeomToSelection})];\n\t\t\t\tthis.addControls(controls);\n\t\t\t},\n\t\t\tdraw:function(){\n\t\t\t\tvar div=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);\n\t\t\t\tthis.activateControl(this.controls[0]);\n\t\t\t\treturn div;\n\t\t\t},\n\tCLASS_NAME:\"MyEditingToolbar\"});\n\nloadFilter = function(){\n    if(jQuery('#map').children().length == 0) {\n    \tpolygonLayer = new OpenLayers.Layer.Vector('Polygon Layer', {\n\t\t\tstyleMap: new OpenLayers.StyleMap({\n                \t\t\"default\": new OpenLayers.Style({\n                    \t\tfillColor: \"Red\",\n        \t\t            strokeColor: \"Red\",\n\t\t                    fillOpacity: 0,\n                \t\t    strokeWidth: 1\n        \t\t          })\n\t\t\t}),\n\t\t\tdisplayInLayerSwitcher: false\n\t\t});\n\t\tpolygonLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tpolygonLayer.map.searchLayer.destroyFeatures();\n\t\t\tif(inseeLayer != null)\n\t\t\t\tinseeLayer.destroyFeatures();\n\t\t});\n    \t" . $map1JS . "\n    \teditControl = new MyEditingToolbar(polygonLayer, {'displayClass':'olControlEditingToolbar'});\n\t\tpolygonLayer.map.addControl(this.editControl);\n\t\teditControl.activate();\n\t\tpolygonLayer.map.searchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tif(inseeLayer != null)\n\t\t\t\tinseeLayer.destroyFeatures();\n\t\t\tpolygonLayer.destroyFeatures();\n\t\t});\n\t}\n}\n\njQuery('#fc-add-preferred').click(function(){\n\tif(collection_preferred_object.collection_id == null) return;\n\tvar newObj = {};\n\tfor (i in collection_preferred_object) {\n\t\tnewObj[i] = collection_preferred_object[i]\n\t};\n\tnewObj.insects = JSON.stringify(newObj.insects);";
        if ($args['preferred_js_function'] != '') {
            data_entry_helper::$javascript .= "\n\t\t" . $args['preferred_js_function'] . "({type: 'C', collection: newObj});";
        }
        data_entry_helper::$javascript .= "\n});\njQuery('#fc-new-comment-button').click(function(){ \n\tjQuery('#fc-new-comment').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-comment-button').click(function(){ \n\tjQuery('#fo-new-comment').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-insect-id-button').click(function(){ \n\tjQuery('#fo-express-doubt').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-new-insect-id [name=determination\\:comment]').val(\"" . lang::get('LANG_Default_ID_Comment') . "\");\n\tjQuery('#fo-new-insect-id').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-flower-id-button').click(function(){ \n\tjQuery('#fo-express-doubt').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-new-flower-id [name=determination\\:comment]').val(\"" . lang::get('LANG_Default_ID_Comment') . "\");\n\tjQuery('#fo-new-flower-id').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-collection-button').click(function(){\n\tloadCollection(jQuery(this).data('smpID'), jQuery(this).data('collectionIndex'));\n});\njQuery('#fo-prev-button,#fo-next-button').click(function(){\n\tloadInsect(jQuery(this).data('occID'), // my occurrence id.\n\t\tjQuery(this).data('collectionIndex'), // index of my collection within search results. Used when called from a focus on collection or from search collection photoreel thumbnail\n\t\tjQuery(this).data('insectIndex'), // index of me within search results. Used when called from search\n\t\tjQuery(this).data('type') // type: 'P' from photoreel, 'S' from search, 'C' from collection, 'X' NA\n\t);\n});\n  ";
        switch ($mode) {
            case 'INSECT':
                data_entry_helper::$onload_javascript .= "loadInsect(" . $occID . ", null, null, 'X');";
                break;
            case 'FLOWER':
                data_entry_helper::$onload_javascript .= "loadFlower(" . $occID . ", null);";
                break;
            case 'COLLECTION':
                data_entry_helper::$onload_javascript .= "loadCollection(" . $smpID . ", null);";
                break;
            default:
                data_entry_helper::$onload_javascript .= "\n    \t\tjQuery('#focus-occurrence,#focus-collection,#results-insects-header,#results-collections-header,#results-insects-results,#results-collections-results').hide();\n    \t\tloadFilter();";
                if ($userID != '') {
                    $thisuser = user_load($userID);
                    data_entry_helper::$onload_javascript .= "jQuery('[name=username]').val('" . $thisuser->name . "');\n    \t\t\tjQuery('#fold-name-button').click();";
                }
                data_entry_helper::$onload_javascript .= "jQuery('#search-collections-button').click();";
                break;
        }
        return $r;
    }
 /**
  * A set of input controls for defining the transect.
  */
 protected static function get_control_latlongs($auth, $args, $tabAlias, $options)
 {
     $r = data_entry_helper::text_input(array('label' => 'Transect start', 'fieldname' => 'gpsstart', 'helpText' => lang::get('Transect start, GPS coordinate (decimal WGS84 latitude and longitude). Click once on the map to set.')));
     $r .= data_entry_helper::text_input(array('label' => 'Transect end', 'fieldname' => 'gpsend', 'helpText' => lang::get('Transect end, GPS coordinate (decimal WGS84 latitude and longitude). Click again on the map to set.')));
     return $r;
 }
    /**
     * Return the generated form output.
     * @return Form HTML.
     */
    public static function get_form($args, $node)
    {
        global $user;
        // There is a language entry in the args parameter list: this is derived from the $language DRUPAL global.
        // It holds the 2 letter code, used to pick the language file from the lang subdirectory of prebuilt_forms.
        // There should be no explicitly output text in this file.
        // We must translate any field names and ensure that the termlists and taxonlists use the correct language.
        // For attributes, the caption is automatically translated by data_entry_helper.
        $logged_in = $user->uid > 0;
        $uid = $user->uid;
        $email = $user->mail;
        $username = $user->name;
        if (!user_access('IForm n' . $node->nid . ' access')) {
            return "<p>" . lang::get('LANG_Insufficient_Privileges') . "</p>";
        }
        $r = '';
        // Get authorisation tokens to update and read from the Warehouse.
        $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
        $svcUrl = data_entry_helper::$base_url . '/index.php/services';
        drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
        data_entry_helper::link_default_stylesheet();
        data_entry_helper::add_resource('jquery_ui');
        data_entry_helper::enable_validation('new-comments-form');
        // don't care about ID itself, just want resources
        $occID = '';
        $smpID = '';
        $userID = '';
        $mode = 'FILTER';
        if (array_key_exists('insect_id', $_GET)) {
            $occID = $_GET['insect_id'];
            $mode = 'INSECT';
        } else {
            if (array_key_exists('insect', $_GET)) {
                $occID = $_GET['insect'];
                $mode = 'INSECT';
            } else {
                if (array_key_exists('flower_id', $_GET)) {
                    $occID = $_GET['flower_id'];
                    $mode = 'FLOWER';
                } else {
                    if (array_key_exists('flower', $_GET)) {
                        $occID = $_GET['flower'];
                        $mode = 'FLOWER';
                    } else {
                        if (array_key_exists('collection_id', $_GET)) {
                            $smpID = $_GET['collection_id'];
                            $mode = 'COLLECTION';
                        } else {
                            if (array_key_exists('collection', $_GET)) {
                                $smpID = $_GET['collection'];
                                $mode = 'COLLECTION';
                            } else {
                                if (array_key_exists('user_id', $_GET)) {
                                    $userID = $_GET['user_id'];
                                } else {
                                    if (array_key_exists('user', $_GET)) {
                                        $userID = $_GET['user'];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        //	data_entry_helper::enable_validation('cc-1-collection-details'); // don't care about ID itself, just want resources
        // The only things that will be editable after the collection is saved will be the identifiaction of the flower/insects.
        // no id - just getting the attributes, rest will be filled in using AJAX
        $sample_attributes = data_entry_helper::getAttributes(array('valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $occurrence_attributes = data_entry_helper::getAttributes(array('valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $location_attributes = data_entry_helper::getAttributes(array('valuetable' => 'location_attribute_value', 'attrtable' => 'location_attribute', 'key' => 'location_id', 'fieldprefix' => 'locAttr', 'extraParams' => $readAuth, 'survey_id' => $args['survey_id']));
        $language = iform_lang_iso_639_2($args['language']);
        $defAttrOptions = array('extraParams' => $readAuth, 'lookUpListCtrl' => 'checkbox_group', 'booleanCtrl' => 'checkbox', 'sep' => ' &nbsp; ', 'language' => $language, 'suffixTemplate' => 'nosuffix', 'default' => '-1');
        // note we have to proxy the post. Every time a write transaction is carried out, the write nonce is trashed.
        // For security reasons we don't want to give the user the ability to generate their own nonce, so we use
        // the fact that the user is logged in to drupal as the main authentication/authorisation/identification
        // process for the user. The proxy packages the post into the correct format
        $flower_ctrl_args = array('label' => lang::get('LANG_Flower_Species'), 'fieldname' => 'flower:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $readAuth + array('taxon_list_id' => $args['flower_list_id'], 'orderby' => 'taxon'), 'suffixTemplate' => 'nosuffix');
        $focus_flower_ctrl_args = $flower_ctrl_args;
        $focus_flower_ctrl_args['fieldname'] = 'determination:taxa_taxon_list_id';
        $insect_ctrl_args = array('label' => lang::get('LANG_Insect_Species'), 'fieldname' => 'insect:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'blankText' => lang::get('LANG_Choose_Taxon'), 'extraParams' => $readAuth + array('taxon_list_id' => $args['insect_list_id'], 'orderby' => 'taxon'), 'suffixTemplate' => 'nosuffix');
        $focus_insect_ctrl_args = $insect_ctrl_args;
        $focus_insect_ctrl_args['fieldname'] = 'determination:taxa_taxon_list_id';
        $options = iform_map_get_map_options($args, $readAuth);
        $olOptions = iform_map_get_ol_options($args);
        // The maps internal projection will be left at its default of 900913.
        $options['initialFeatureWkt'] = null;
        $options['proxy'] = '';
        $options['suffixTemplate'] = 'nosuffix';
        $options2 = $options;
        $options['searchLayer'] = 'true';
        $options['editLayer'] = 'false';
        $options['layers'] = array('polygonLayer');
        $options2['divId'] = "map2";
        $options2['layers'] = array('locationLayer');
        // TBD Breadcrumb
        $r .= '
<div id="filter" class="ui-accordion ui-widget ui-helper-reset">
	<div id="filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-accordion-content-active ui-corner-top">
	  	<div id="results-collections-title">
	  		<span>' . lang::get('LANG_Filter_Title') . '</span>
    	</div>
	</div>
	<div id="filter-spec" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	  <div class="ui-accordion ui-widget ui-helper-reset">
		<div id="name-filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  		<div id="fold-name-button" class="ui-state-default ui-corner-all fold-button">&nbsp;</div>
	  		<div id="reset-name-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="general-filter-title">
		  		<span>' . lang::get('LANG_Name_Filter_Title') . '</span>
      		</div>
		</div>
	    <div id="name-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-all">
	        ' . data_entry_helper::text_input(array('label' => lang::get('LANG_Name'), 'fieldname' => 'username', 'suffixTemplate' => 'nosuffix')) . '
  		</div>
		<div id="date-filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  		<div id="fold-date-button" class="ui-state-default ui-corner-all fold-button">&nbsp;</div>
	  		<div id="reset-date-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="general-filter-title">
		  		<span>' . lang::get('LANG_Date_Filter_Title') . '</span>
      		</div>
		</div>
	    <div id="date-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-all">
        	<label for="start_date" >' . lang::get('LANG_Created_Between') . ':</label>
  			<input type="text" size="10" id="start_date" name="start_date" value="' . lang::get('click here') . '" />
       		<label for="start_date" >' . lang::get('LANG_And') . ':</label>
  			<input type="text" size="10" id="end_date" name="end_date" value="' . lang::get('click here') . '" />
  		</div>
  		<div id="flower-filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  		<div id="fold-flower-button" class="ui-state-default ui-corner-all fold-button">&nbsp;</div>
	  		<div id="reset-flower-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="flower-filter-title">
		  		<span>' . lang::get('LANG_Flower_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="flower-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-all">
		  ' . data_entry_helper::select($flower_ctrl_args) . data_entry_helper::outputAttribute($occurrence_attributes[$args['flower_type_attr_id']], $defAttrOptions) . data_entry_helper::outputAttribute($location_attributes[$args['habitat_attr_id']], $defAttrOptions) . '
    	</div>
		<div id="insect-filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  		<div id="fold-insect-button" class="ui-state-default ui-corner-all fold-button">&nbsp;</div>
			<div id="reset-insect-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
	  		<div id="insect-filter-title">
		  		<span>' . lang::get('LANG_Insect_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="insect-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-all">
		  ' . data_entry_helper::select($insect_ctrl_args) . data_entry_helper::outputAttribute($sample_attributes[$args['sky_state_attr_id']], $defAttrOptions) . data_entry_helper::outputAttribute($sample_attributes[$args['temperature_attr_id']], $defAttrOptions) . data_entry_helper::outputAttribute($sample_attributes[$args['wind_attr_id']], $defAttrOptions) . data_entry_helper::outputAttribute($sample_attributes[$args['shade_attr_id']], $defAttrOptions) . '
		</div>
		<div id="location-filter-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  		<div id="fold-location-button" class="ui-state-default ui-corner-all fold-button">&nbsp;</div>
			<div id="reset-location-button" class="ui-state-default ui-corner-all reset-button">' . lang::get('LANG_Reset_Filter') . '</div>
			<div id="location-filter-title">
		  		<span>' . lang::get('LANG_Location_Filter_Title') . '</span>
      		</div>
		</div>
		<div id="location-filter-body" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-all">
		  <div id="location-entry">
            ' . data_entry_helper::georeference_lookup(array('label' => lang::get('LANG_Georef_Label'), 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'suffixTemplate' => 'nosuffix')) . '
 	        <label for="place:INSEE">' . lang::get('LANG_Or') . '</label>
 		    <input type="text" id="place:INSEE" name="place:INSEE" value="' . lang::get('LANG_INSEE') . '"
	 		  onclick="if(this.value==\'' . lang::get('LANG_INSEE') . '\'){this.value=\'\'; this.style.color=\'#000\'}"  
              onblur="if(this.value==\'\'){this.value=\'' . lang::get('LANG_INSEE') . '\'; this.style.color=\'#555\'}" />
    	    <input type="button" id="search-insee-button" class="ui-corner-all ui-widget-content ui-state-default search-button" value="Search" />
 	      </div>
	  		' . data_entry_helper::map_panel($options, $olOptions) . '
		</div>
      </div>
    </div>
    <div id="filter-footer" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
	  <div id="search-insects-button" class="ui-state-default ui-corner-all search-button">' . lang::get('LANG_Search_Insects') . '</div>
      <div id="search-collections-button" class="ui-state-default ui-corner-all search-button">' . lang::get('LANG_Search_Collections') . '</div>
    </div>
	<div id="results-collections-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	  <div id="results-collections-title">
	  	<span>' . lang::get('LANG_Collections_Search_Results') . '</span>
      </div>
	</div>
	<div id="results-collections-results" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </div>
	<div id="results-insects-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	  <div id="results-insects-title">
	  	<span>' . lang::get('LANG_Insects_Search_Results') . '</span>
      </div>
	</div>
	<div id="results-insects-results" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </div>
</div>
<div id="focus-collection" class="ui-accordion ui-widget ui-helper-reset">
	<div id="collection-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  <div id="collection-title">
	  	<span> </span>
      </div>
	</div>
	<div id="collection-details" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-top">
	  <div id="flower-image">
      </div>
	  <div id="collection-description">
	    <p id="collection-date"></p>
	    <p id="collection-name"></p>
	    <p id="collection-flower-name"></p>
	    <p>' . $occurrence_attributes[$args['flower_type_attr_id']]['caption'] . ': <span id="collection-flower-type"></span></p>
	    <p>' . $location_attributes[$args['habitat_attr_id']]['caption'] . ': <span id="collection-habitat"></span></p>
	    <p id="collection-locality"></p>
	    <p id="collection-user-name"></p>
	  </div>
	  <div id="environment-image">
      </div>
      <div id="map2_container">' . data_entry_helper::map_panel($options2, $olOptions) . '
      </div>
    </div>
	<div id="collection-insects" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active ui-corner-bottom">
    </div>
	<div id="fc-comments-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top">
	    <div id="fc-new-comment-button" class="ui-state-default ui-corner-all new-comment-button">' . lang::get('LANG_New_Comment') . '</div>
		<span>' . lang::get('LANG_Comments_Title') . '</span>
	</div>
	<div id="fc-new-comment" class="ui-accordion-content ui-helper-reset ui-widget-content">
		<form id="fc-new-comment-form" action="' . iform_ajaxproxy_url($node, 'smp-comment') . '" method="POST">
		    <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    		<input type="hidden" name="sample_comment:sample_id" value="" />
    		<label for="sample_comment:person_name">' . lang::get('LANG_Username') . ':</label>
		    <input type="text" name="sample_comment:person_name" value="' . $username . '" readonly="readonly" />  
    		<label for="sample_comment:email_address">' . lang::get('LANG_Email') . ':</label>
		    <input type="text" name="sample_comment:email_address" value="' . $email . '" readonly="readonly" />
		    ' . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'sample_comment:comment', 'class' => 'required', 'suffixTemplate' => 'nosuffix')) . '
    		<input type="submit" id="fc_comment_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Submit_Comment') . '" />
    	</form>
	</div>
	<div id="fc-comment-list" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	</div>
</div>
<div id="focus-occurrence" class="ui-accordion ui-widget ui-helper-reset">
	<h1 id="fo-taxon"></h1>
	<div id="fo-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  <div id="fo-header-buttons">
 	      <span id="fo-collection-button" class="ui-state-default ui-corner-all collection-button">' . lang::get('LANG_Collection') . '</span>
	      <span id="fo-prev-button" class="ui-state-default ui-corner-all previous-button">' . lang::get('LANG_Previous') . '</span>
	      <span id="fo-next-button" class="ui-state-default ui-corner-all next-button">' . lang::get('LANG_Next') . '</span>
	  </div>
	  <div id="fo-breadcrumb">
	  	<span> </span>
      </div>
	</div>
	<div id="fo-warning" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-top ui-accordion-content-active"></div>
	<div id="fo-picture" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	  <div id="fo-image">
      </div>
    </div>
	<div id="fo-identification" class="ui-accordion-header ui-helper-reset ui-state-active">';
        if (user_access('IForm n' . $node->nid . ' insect expert')) {
            $r .= '<div id="fo-new-insect-id-button" class="ui-state-default ui-corner-all new-id-button">' . lang::get('LANG_New_ID') . '</div>';
        }
        if (user_access('IForm n' . $node->nid . ' flower expert')) {
            $r .= '<div id="fo-new-flower-id-button" class="ui-state-default ui-corner-all new-id-button">' . lang::get('LANG_New_ID') . '</div>';
        }
        $r .= ' 
	  <div id="fo-doubt-button" class="ui-state-default ui-corner-all doubt-button">' . lang::get('LANG_Doubt') . '</div>
	  <div id="fo-id-title">
	  	<span>' . lang::get('LANG_Indentification_Title') . '</span>
      </div>
    </div>
	<div id="fo-current-id" class="ui-accordion-content ui-helper-reset ui-widget-content ui-accordion-content-active">
	</div>';
        if (user_access('IForm n' . $node->nid . ' insect expert')) {
            $r .= '
	<div id="fo-new-insect-id" class="ui-accordion-content ui-helper-reset ui-widget-content">
	  <form id="fo-new-insect-id-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
    	<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />
		' . ($args['ID_tool_insect_url'] != '' && $args['ID_tool_insect_poll_dir'] ? '<label for="insect-id-button">' . lang::get('LANG_Insect_ID_Key_label') . ' :</label><span id="insect-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>' : '') . '<span id="insect-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>' . data_entry_helper::select($focus_insect_ctrl_args) . '
        <input type="submit" id="id_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>';
        }
        if (user_access('IForm n' . $node->nid . ' flower expert')) {
            $r .= '
    <div id="fo-new-flower-id" class="ui-accordion-content ui-helper-reset ui-widget-content">
	  <form id="fo-new-flower-id-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
		<input type="hidden" name="determination:cms_ref" value="' . $uid . '" />  
    	<input type="hidden" name="determination:person_name" value="' . $username . '" />  
		<input type="hidden" name="determination:email_address" value="' . $email . '" />
		' . ($args['ID_tool_flower_url'] != '' && $args['ID_tool_flower_poll_dir'] ? '<label for="flower-id-button">' . lang::get('LANG_Flower_ID_Key_label') . ' :</label><span id="flower-id-button" class="ui-state-default ui-corner-all poll-id-button" >' . lang::get('LANG_Launch_ID_Key') . '</span>' : '') . '<span id="flower-id-cancel" class="ui-state-default ui-corner-all poll-id-cancel" >' . lang::get('LANG_Cancel_ID') . '</span>
        ' . data_entry_helper::select($focus_flower_ctrl_args) . '
        <input type="submit" id="id_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Validate') . '" />
      </form>
	</div>';
        }
        $r .= '
	<div id="fo-id-history" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active">
	</div>
	<div id="fo-addn-info-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	  <div id="fo-addn-info-title">
	  	<span>' . lang::get('LANG_Additional_Info_Title') . '</span>
      </div>
	</div>
	<div id="fo-insect-addn-info" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all ui-accordion-content-active">
	    <p>' . lang::get('LANG_Date') . ': <span id="fo-insect-date"></span></p>
	    <p>' . lang::get('LANG_Time') . ': <span id="fo-insect-start-time"></span> ' . lang::get('LANG_To') . ' <span id="fo-insect-end-time"></span></p>
	    <p>' . $sample_attributes[$args['sky_state_attr_id']]['caption'] . ': <span id="fo-insect-date"></span></p>
	    <p>' . $sample_attributes[$args['temperature_attr_id']]['caption'] . ': <span id="fo-insect-temp"></span></p>
	    <p>' . $sample_attributes[$args['wind_attr_id']]['caption'] . ': <span id="fo-insect-wind"></span></p>
	    <p>' . $sample_attributes[$args['shade_attr_id']]['caption'] . ': <span id="fo-insect-sahed"></span></p>
	</div>
	<div id="fo-flower-addn-info" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all ui-accordion-content-active">
	    <p>' . $occurrence_attributes[$args['flower_type_attr_id']]['caption'] . ': <span id="focus-flower-type"></span></p>
	    <p>' . $location_attributes[$args['habitat_attr_id']]['caption'] . ': <span id="focus-habitat"></span></p>
	</div>
	<div id="fo-comments-header" class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-all">
	    <div id="fo-new-comment-button" class="ui-state-default ui-corner-all new-comment-button">' . lang::get('LANG_New_Comment') . '</div>
		<span>' . lang::get('LANG_Comments_Title') . '</span>
	</div>
	<div id="fo-new-comment" class="ui-accordion-content ui-helper-reset ui-corner-all ui-widget-content">
		<form id="fo-new-comment-form" action="' . iform_ajaxproxy_url($node, 'occ-comment') . '" method="POST">
		    <input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    		<input type="hidden" name="occurrence_comment:occurrence_id" value="" />
    		<label for="occurrence_comment:person_name">' . lang::get('LANG_Username') . ':</label>
		    <input type="text" name="occurrence_comment:person_name" value="' . $username . '" readonly="readonly" />  
    		<label for="occurrence_comment:email_address">' . lang::get('LANG_Email') . ':</label>
		    <input type="text" name="occurrence_comment:email_address" value="' . $email . '" readonly="readonly" />
		    ' . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence_comment:comment', 'class' => 'required', 'suffixTemplate' => 'nosuffix')) . '
    		<input type="submit" id="comment_submit_button" class="ui-state-default ui-corner-all submit-button" value="' . lang::get('LANG_Submit_Comment') . '" />
    	</form>
	</div>
	<div id="fo-comment-list" class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-all ui-accordion-content-active">
	</div>
	<div style="display:none" />
      <form id="fo-doubt-form" action="' . iform_ajaxproxy_url($node, 'determination') . '" method="POST">
		<input type="hidden" name="website_id" value="' . $args['website_id'] . '" />
    	<input type="hidden" name="determination:occurrence_id" value="" />
    	<input type="hidden" name="determination:id" value="" />
    	<input type="hidden" name="determination:dubious" value="Y" />
      </form>
    </div>	
</div>
';
        data_entry_helper::$javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\njQuery('#start_date').datepicker({\n  dateFormat : 'yy-mm-dd',\n  constrainInput: false,\n  maxDate: '0'\n});\njQuery('#end_date').datepicker({\n  dateFormat : 'yy-mm-dd',\n  constrainInput: false,\n  maxDate: '0'\n});\n  \njQuery('#filter-header').click(function(){\n    jQuery('#filter-header').addClass('ui-state-active').removeClass('ui-state-default').addClass('ui-corner-top').removeClass('ui-corner-all');\n\tjQuery('#filter-spec,#filter-footer').removeClass('filter-hide');\n    jQuery('#results-collections-header,#results-insects-header').removeClass('ui-state-active').addClass('ui-state-default');\n    jQuery('#focus-occurrence,#focus-flower,#focus-collection,#results-insects-results,#results-collections-results').addClass('filter-hide');\n});\njQuery('#results-collections-header').click(function(){\n    jQuery('#results-collections-header').addClass('ui-state-active').removeClass('ui-state-default');\n\tjQuery('#results-collections-results').removeClass('filter-hide');\n    jQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n\tjQuery('#filter-spec,#filter-footer,#focus-occurrence,#focus-flower,#focus-collection,#results-insects-results').addClass('filter-hide');\n});\njQuery('#reset-name-button').click(function(){\n\tjQuery('[name=username]').val('');\n});\njQuery('#fold-name-button').click(function(){\n\tjQuery('#name-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-name-button').toggleClass('fold-button-folded');\n\tjQuery('#name-filter-body').toggleClass('filter-hide');\n});\njQuery('#reset-date-button').click(function(){\n\tjQuery('[name=start_date]').val('" . lang::get('click here') . "');\n\tjQuery('[name=end_date]').val('" . lang::get('click here') . "');\n});\njQuery('#fold-date-button').click(function(){\n\tjQuery('#date-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-date-button').toggleClass('fold-button-folded');\n\tjQuery('#date-filter-body').toggleClass('filter-hide');\n});\n\njQuery('#reset-flower-button').click(function(){\n\tjQuery('[name=flower\\:taxa_taxon_list_id]').val('');\n\tjQuery('#flower-filter-body').find(':checkbox').removeAttr('checked');\n});\njQuery('#fold-flower-button').click(function(){\n\tjQuery('#flower-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-flower-button').toggleClass('fold-button-folded');\n\tjQuery('#flower-filter-body').toggleClass('filter-hide');\n});\n\njQuery('#reset-insect-button').click(function(){\n\tjQuery('[name=insect\\:taxa_taxon_list_id]').val('');\n\tjQuery('#insect-filter-body').find(':checkbox').removeAttr('checked');\n});\n\njQuery('#fold-insect-button').click(function(){\n\tjQuery('#insect-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-insect-button').toggleClass('fold-button-folded');\n\tjQuery('#insect-filter-body').toggleClass('filter-hide');\n});\n\njQuery('#reset-location-button').click(function(){\n\tpolygonLayer.destroyFeatures();\n\tpolygonLayer.map.searchLayer.destroyFeatures();\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroyFeatures();\n\tjQuery('#imp-georef-search').val('');\n\tjQuery('[name=place\\:INSEE]').val('" . lang::get('LANG_INSEE') . "');\n});\njQuery('#fold-location-button').click(function(){\n\tjQuery('#location-filter-header').toggleClass('ui-state-active').toggleClass('ui-state-default');\n\tjQuery('#fold-location-button').toggleClass('fold-button-folded');\n\tjQuery('#location-filter-body').toggleClass('filter-hide');\n});\n\njQuery('#flower-image').click(function(){\n\tif(jQuery('#flower-image').attr('occID') != 'none'){\n\t\tloadFlower(jQuery('#flower-image').attr('occID'));\n\t}\n});\n\njQuery('#fo-doubt-button').click(function(){\n\tif(confirm(\"" . lang::get('LANG_Confirm_Express_Doubt') . "\")){\n\t\tjQuery('#fo-doubt-form').submit();\n\t}\n});\n\n\n\nloadCollection = function(id){\n    jQuery('[name=sample_comment\\:sample_id]').val(id);\n    locationLayer.destroyFeatures();\n\tjQuery('#fc-new-comment-button')." . (user_access('IForm n' . $node->nid . ' create collection comment') ? "show()" : "hide()") . ";\n    jQuery('#focus-occurrence,#filter-spec,#filter-footer,#results-insects-header,#results-insects-results,#results-collections-results').addClass('filter-hide');\n    jQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n    jQuery('#focus-collection').removeClass('filter-hide');\n\tjQuery('#map2').width(jQuery('#map2_container').width());\n\tjQuery('#flower-image').attr('occID', 'none');\n\tjQuery('#collection-insects,#collection-date,#collection-name,#collection-flower-name,#collection-flower-type,#collection-habitat,#collection-user-name').empty();\n\t// this has a fixed target so can be done asynchronously.\n\t\$.getJSON(\"" . $svcUrl . "/data/occurrence\" +\n\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\"&sample_id=\"+id+\"&callback=?\", function(flowerData) {\n   \t\tif (flowerData.length>0) {\n\t\t\tloadImage('occurrence_image', 'occurrence_id', flowerData[0].id, '#flower-image');\n\t\t\tjQuery('#flower-image').attr('occID', flowerData[0].id);\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t\"&occurrence_id=\" + flowerData[0].id + \"&deleted=f&callback=?\", function(detData) {\n   \t\t\t\tif (detData.length>0) {\n\t\t\t\t\tvar i = detData.length-1;\n\t\t\t\t\tvar string = '';\n\t\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\t\tstring = string + detData[i].taxon + ', ';\n\t\t\t\t\t}\n\t\t\t\t\tif(detData[i].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\t\t\tstring = string + detData[i].taxon_text_description + ', ';\n\t\t\t\t\t}\n\t\t\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\t\t\tstring = string + detData[i].taxon_extra_info;\n\t\t\t\t\t}\n\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Flower_Name') . ": '+string+'</span>').appendTo('#collection-flower-name');\n\t\t\t\t}});\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_attribute_value\"  +\n   \t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&occurrence_id=\" + flowerData[0].id + \"&iso=" . $language . "&callback=?\", function(attrdata) {\n\t\t\t\tif (attrdata.length>0) {\n\t\t\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\t\t\tswitch(parseInt(attrdata[i].occurrence_attribute_id)){\n\t\t\t\t\t\t\t\tcase " . $args['flower_type_attr_id'] . ":\n\t\t\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+'</span>').appendTo('#collection-flower-type');\n\t\t\t\t\t\t\t\t\tbreak;\n  \t\t\t}}}}});\n\t\t\t\t\n\t\t}\n\t});\n\t\$.getJSON(\"" . $svcUrl . "/data/sample_attribute_value\"  +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&sample_id=\" + id + \"&callback=?\", function(attrdata) {\n\t\tif (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].sample_attribute_id)){\n\t\t\t\t\t\tcase " . $args['username_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Comment_By') . "'+attrdata[i].value+'</span>').appendTo('#collection-user-name');\n\t\t\t\t\t\t\tbreak;\n  \t}}}}});\n  \t\n\t// this has a fixed target so can be done asynchronously.\n\t\$.getJSON(\"" . $svcUrl . "/data/sample/\" +id+\n\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\"&callback=?\", function(collectionData) {\n   \t\tif (collectionData.length>0) {\n\t\t\tif(collectionData[0].date_start == collectionData[0].date_end){\n\t  \t\t\tjQuery('<span>'+collectionData[0].date_start.substring(0,10)+'</span>').appendTo('#collection-date');\n    \t\t} else {\n\t  \t\t\tjQuery('<span>'+collectionData[0].date_start+' - '+collectionData[0].date_end+'</span>').appendTo('#collection-date');\n    \t\t}\n\t  \t\tjQuery('<span>'+collectionData[0].location_name+'</span>').appendTo('#collection-name');\n   \t\t    \$.getJSON(\"" . $svcUrl . "/data/location/\" +collectionData[0].location_id +\n\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\t\t\"&callback=?\", function(locationData) {\n   \t\t\t\tif (locationData.length>0) {\n\t\t\t\t\tloadImage('location_image', 'location_id', locationData[0].id, '#environment-image');\n\t\t\t\t\tvar parser = new OpenLayers.Format.WKT();\n\t\t\t\t\tvar feature = parser.read(locationData[0].centroid_geom);\n\t\t\t\t\tlocationLayer.addFeatures([feature]);\n\t\t\t\t\tvar bounds=locationLayer.getDataExtent();\n\t\t\t        locationLayer.map.setCenter(bounds.getCenterLonLat(), 13);\n\t\t\t        var filter = new OpenLayers.Filter.Spatial({\n  \t\t\t\t\t\ttype: OpenLayers.Filter.Spatial.CONTAINS ,\n    \t\t\t\t\tproperty: 'the_geom',\n    \t\t\t\t\tvalue: feature.geometry\n\t\t\t\t  \t});\n\t\t\t\t\tvar locality = jQuery('#collection-locality');\n\t\t\t\t  \tvar scope = {target: locality};\n\t\t\t\t\tinseeProtocol.read({filter: filter, callback: test, scope: scope, async: false});\n\t\t\t\t}\n\t\t\t});\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/location_attribute_value\"  +\n   \t\t\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&location_id=\" + collectionData[0].location_id + \"&iso=" . $language . "&callback=?\", function(attrdata) {\n\t\t\t\tif (attrdata.length>0) {\n\t\t\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\t\t\tswitch(parseInt(attrdata[i].location_attribute_id)){\n\t\t\t\t\t\t\t\tcase " . $args['habitat_attr_id'] . ":\n\t\t\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+' / </span>').appendTo('#collection-habitat');\n\t\t\t\t\t\t\t\t\tbreak;\n  \t\t\t}}}}});\n\t\t}\n\t});\n\t\$.getJSON(\"" . $svcUrl . "/data/sample\" + \n\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&parent_id=\"+id+\"&callback=?\", function(sessiondata) {\n  \t\tif (sessiondata.length>0) {\n\t\t\tfor (var i=0;i<sessiondata.length;i++){\n\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n\t\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n\t\t\t\t\t\t\"&sample_id=\"+sessiondata[i].id+\"&orderby=id&callback=?\", function(insectData) {\n\t\t\t\t\tif (insectData.length>0) {\n\t\t\t\t\t\tfor (var j=0;j<insectData.length;j++){\n\t\t\t\t\t\t\tvar insect=jQuery('<div class=\"ui-widget-content ui-corner-all collection-insect\" />').attr('occID', insectData[j].id).appendTo('#collection-insects');\n\t\t\t\t\t\t\tjQuery('<p class=\"insect-tag insect-unknown\" />').appendTo(insect);\n\t\t\t\t\t\t\tvar image = jQuery('<div class=\"insect-image\" />').appendTo(insect);\n\t\t\t\t\t\t\tjQuery('<p class=\"insect-determination\" />').appendTo(insect);\n\t\t\t\t\t\t\tvar displayButton = jQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>')\n\t\t\t\t\t\t\t\t.appendTo(insect).attr('value',insectData[j].id);\n\t\t\t\t\t\t\tdisplayButton.click(function(){\n\t\t\t\t\t\t\t\tloadInsect(jQuery(this).attr('value'));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tloadImage('occurrence_image', 'occurrence_id', insectData[j].id, image);\n\t\t\t\t\t\t\t// have to do this synchronously due to multiple targets\n\t\t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t    \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t    \t\t\t\"&occurrence_id=\" + insectData[j].id + \"&deleted=f&callback=?\", function(detData) {\n   \t\t\t\t\t\t\t\tif (detData.length>0) {\n\t\t\t\t\t    \t\t\tvar insect = jQuery('.collection-insect').filter('[occID='+detData[0].occurrence_id+']');\n\t\t\t\t\t    \t\t\tvar tag = insect.find('.insect-tag');\n\t\t\t\t\t    \t\t\tvar det = insect.find('.insect-determination');\n\t\t\t\t\t\t\t\t\tvar i = detData.length-1;\n\t\t\t\t\t\t\t\t\tvar string = '';\n\t\t\t\t\t\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\t\t\t\t\t\tstring = string + detData[i].taxon + ', ';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(detData[i].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\t\t\t\t\t\t\tstring = string + detData[i].taxon_text_description + ', ';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\t\t\t\t\t\t\tstring = string + detData[i].taxon_extra_info;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tjQuery('<div><p>" . lang::get('LANG_Last_ID') . ":</p><p><strong>'+string+'</strong></p></div>').addClass('insect-id').appendTo(det);\n\t\t\t\t\t\t\t\t\tif(detData[i].dubious == 'Y'){\n\t\t\t\t\t\t\t\t\t\ttag.removeClass('insect-unknown').addClass('insect-dubious');\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\ttag.removeClass('insect-unknown').addClass('insect-ok');\n\t\t\t\t\t\t\t\t\t}\n  \t\t\t\t\t\t\t\t}});  \t\t\t\t\t\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n  \t\t}\n\t});\n\tloadComments(id, '#fc-comment-list', 'sample_comment', 'sample_id', 'sample-comment-block', 'sample-comment-body');\n};\ntest = function(a1)\n{\n\tjQuery(this.target).empty();\n   \tjQuery('<span>'+a1.features[0].attributes.NOM+' ('+a1.features[0].attributes.INSEE_NEW+'), '+a1.features[0].attributes.DEPT_NOM+' ('+a1.features[0].attributes.DEPT_NUM+'), '+a1.features[0].attributes.REG_NOM+' ('+a1.features[0].attributes.REG_NUM+')</span>').appendTo(this.target);\n}\naddCollection = function(attributes, geom){\n\t// first the text, then the flower and environment picture, then the small insect pictures, then the afficher button\n\tvar collection=jQuery('<div class=\"ui-widget-content ui-corner-all filter-collection\" />').appendTo('#results-collections-results');\n\tvar details = jQuery('<div class=\"collection-details\" />').appendTo(collection); \n\tvar flower = jQuery('<div class=\"collection-image collection-flower\" />').attr('occID', attributes.flower_id).click(function(){\n\t\tloadFlower(jQuery(this).attr('occID'));\n\t});\n\tvar filter = new OpenLayers.Filter.Spatial({\n  \t\t\ttype: OpenLayers.Filter.Spatial.CONTAINS ,\n    \t\tproperty: 'the_geom',\n    \t\tvalue: geom\n  \t});\n\tflower.appendTo(collection);\n\tvar img = new Image();\n\t\$(img).load(function () {flower.append(this);})\n\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+attributes.flower_image_path)\n\t    .css('max-width', flower.width()).css('max-height', flower.height())\n\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\tvar location = jQuery('<div class=\"collection-image collection-environment\" />').appendTo(collection);\n\timg = new Image();\n\t\$(img).load(function () {location.append(this)})\n\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+attributes.location_image_path)\n\t    .css('max-width', location.width()).css('max-height', location.height())\n\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\tvar photoReel = jQuery('<div class=\"collection-photoreel\"></div>').appendTo(collection);\n\tvar displayButtonContainer = jQuery('<div class=\"collection-buttons\"></div>').appendTo(collection);\n\tvar displayButton = jQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>');\n\tdisplayButton.click(function(){\n\t\tloadCollection(jQuery(this).attr('value'));\n\t}).appendTo(displayButtonContainer).attr('value',attributes.collection_id);\n\tif(attributes.date_start == attributes.date_end){\n\t  jQuery('<p class=\"collection-date\">'+attributes.date_start.substring(0,10)+'</p>').appendTo(details);\n    } else {\n\t  jQuery('<p class=\"collection-date\">'+attributes.date_start+' - '+attributes.date_end+'</p>').appendTo(details);\n    }\n\tjQuery('<p class=\"collection-name\">'+attributes.location_name+'</p>').appendTo(details);\n\tvar locality = jQuery('<p  class=\"collection-locality\"></p>').appendTo(details);\n\tvar scope = {target: locality};\n\tinseeProtocol.read({filter: filter, callback: test, scope: scope, async: false});\n    \$.getJSON(\"" . $svcUrl . "/data/sample\" + \n    \t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&parent_id=\"+attributes.collection_id+\"&callback=?\", function(sessiondata) {\n\t\tfor (var i=0;i<sessiondata.length;i++){\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" +\n\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "&orderby=id\" +\n\t\t\t\t\t\"&sample_id=\"+sessiondata[i].id+\"&callback=?\", function(insectData) {\n\t\t    \tif (insectData.length>0) {\n \t\t\t\t\tfor (var j=0;j<insectData.length;j++){\n\t\t\t\t\t\tvar container = jQuery('<div/>').addClass('thumb').attr('occId', insectData[j].id.toString()).click(function () {loadInsect(jQuery(this).attr('occId'));});\n\t\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Unknown') . "</span>').addClass('thumb-text').appendTo(container);\n\t\t\t\t\t\tphotoReel.append(container);\n\t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_image\" +\n\t\t\t\t\t   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\t\t\t\"&occurrence_id=\" + insectData[j].id + \"&callback=?\", function(imageData) {\n\t\t\t\t\t\t\t  if (imageData.length>0) {\n\t\t\t\t\t\t      \tvar container = jQuery('.thumb').filter('[occId='+imageData[0].occurrence_id.toString()+']');\n\t\t\t\t\t\t\t    var img = new Image();\n\t\t\t\t\t\t\t\tjQuery(img).attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "thumb-'+imageData[0].path)\n\t\t\t    \t\t\t\t\t.attr('width', container.width()).attr('height', container.height()).addClass('thumb-image').appendTo(container);\n\t\t\t\t\t\t\t  }}); \n\t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/determination\" + \n\t\t\t\t\t    \t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" + \n\t\t\t\t\t    \t\t\"&occurrence_id=\" + insectData[j].id + \"&deleted=f&callback=?\", function(detData) {\n\t\t\t\t\t\t      if (detData.length>0) {\n\t\t\t\t\t\t        var container = jQuery('.thumb').filter('[occId='+detData[0].occurrence_id.toString()+']');\n\t\t\t\t\t\t        container.find('.thumb-text').remove();\n\t\t\t\t\t\t        if(detData[detData.length-1].dubious == 'Y'){\n\t\t\t\t\t\t\t\t\tjQuery('<span>" . lang::get('LANG_Dubious') . "</span>').addClass('thumb-text').appendTo(container);\n\t\t\t\t\t\t\t  \t}\n  \t\t\t\t\t\t\t  }});  \t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t}});\n\t\t}});\n};\naddInsect = function(attributes){\n\tvar container=jQuery('<div class=\"ui-widget-content ui-corner-all filter-insect\" />').appendTo('#results-insects-results');\n\tvar flag = jQuery('<div />').addClass('insect-ok').appendTo(container);\n\tvar insect = jQuery('<div class=\"insect-image\" />').attr('occID', attributes.insect_id).click(function(){\n\t\tloadInsect(jQuery(this).attr('occID'));\n\t});\n\tinsect.appendTo(container);\n\tvar img = new Image();\n\t\$(img).load(function () {insect.append(this);})\n\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "med-'+attributes.insect_image_path)\n\t\t.css('max-width', insect.width()).css('max-height', insect.width()*imageRatio)\n\t    .css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\t\$.getJSON(\"" . $svcUrl . "/data/determination\" +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&occurrence_id=\" + attributes.insect_id + \"&callback=?\", function(detData) {\n   \t\tif (detData.length>0) {\n\t\t\tvar i = detData.length-1;\n   \t\t\tvar string = '';\n\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\tstring = detData[i].taxon;\n\t\t\t}\n\t\t\tif(detData[i].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\tstring = (string == '' ? '' : string + ', ') + detData[i].taxon_text_description;\n\t\t\t}\n\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\tstring = (string == '' ? '' : string + ', ') + detData[i].taxon_extra_info;\n\t\t\t}\n\t\t\tjQuery('<p>'+string+'</p>').appendTo(container)\n\t\t\tif(detData[i].dubious == 'Y'){\n\t\t\t\tjQuery(flag).removeClass('insect-ok').addClass('insect-dubious');\n\t\t\t}\n\t\t} else {\n\t\t\tjQuery(flag).removeClass('insect-ok').addClass('insect-unknown');\n\t\t\tjQuery(\"<p>" . lang::get('LANG_No_Determinations') . "</p>\")\n\t\t\t\t\t.appendTo(container);\n\t\t}\n\t});\n\tvar displayButton = jQuery('<div class=\"ui-state-default ui-corner-all display-button\">" . lang::get('LANG_Display') . "</div>');\n\tdisplayButton.click(function(){\n\t\tloadInsect(jQuery(this).attr('value'));\n\t}).appendTo(container).attr('value',attributes.insect_id);\n};\n\n\nsetCollectionPage = function(pageNum){\n\tjQuery('#results-collections-results').empty();\n\tvar numPages = Math.ceil(searchResults.features.length/" . $args['collectionsPerPage'] . ");\n\tif(numPages > 1) {\n\t\tvar pageCtrl = jQuery('<div>').addClass('page-control').appendTo('#results-collections-results');\n\t\tvar pageCtrl2 = jQuery('<div>').addClass('page-control');\n\t\tvar first = true;\n\t\tfor (var j = (pageNum < 6  ? 1 : pageNum - 5); j <= numPages && j <= (pageNum + 5); j++){\n\t\t\tif (first != true){\n\t\t\t\tjQuery('<span>|</span>').appendTo(pageCtrl);\n\t\t\t\tjQuery('<span>|</span>').appendTo(pageCtrl2);\n  \t\t\t}\n  \t\t\tfirst = false;\n\t\t\tif( j != pageNum) {\n\t\t\t\tjQuery('<a>'+j+'</a>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a>'+j+'</a>').attr('value',j).click(function(){setCollectionPage(jQuery(this).attr('value'))}).appendTo(pageCtrl2);\n  \t\t\t} else {\n\t\t\t\tjQuery('<span>'+j+'</span>').appendTo(pageCtrl);\n\t\t\t\tjQuery('<span>'+j+'</span>').appendTo(pageCtrl2);\n  \t\t\t}\n\t    }\n\t}\n    for (var i = (pageNum-1)*" . $args['collectionsPerPage'] . "; i < searchResults.features.length && i < pageNum*" . $args['collectionsPerPage'] . "; i++){\n\t\taddCollection(searchResults.features[i].attributes,searchResults.features[i].geometry);\n\t}\n\tif(numPages > 1) {\n\t\tpageCtrl2.appendTo('#results-collections-results');\n\t}\n}\nsetInsectPage = function(pageNum){\n\tjQuery('#results-insects-results').empty();\n\tvar numPages = Math.ceil(searchResults.features.length/" . $args['insectsPerPage'] . ");\n\tif(numPages > 1) {\n\t\tvar pageCtrl = jQuery('<div>').addClass('page-control').appendTo('#results-insects-results');\n\t\tvar pageCtrl2 = jQuery('<div>').addClass('page-control');\n\t\tvar first = true;\n\t\tfor (var j = (pageNum < 6  ? 1 : pageNum - 5); j <= numPages && j <= (pageNum + 5); j++){\n\t\t\tif (first != true){\n\t\t\t\tjQuery('<span>|</span>').appendTo(pageCtrl);\n\t\t\t\tjQuery('<span>|</span>').appendTo(pageCtrl2);\n  \t\t\t}\n  \t\t\tfirst = false;\n\t\t\tif( j != pageNum) {\n\t\t\t\tjQuery('<a>'+j+'</a>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl);\n\t\t\t\tjQuery('<a>'+j+'</a>').attr('value',j).click(function(){setInsectPage(jQuery(this).attr('value'))}).appendTo(pageCtrl2);\n  \t\t\t} else {\n\t\t\t\tjQuery('<span>'+j+'</span>').appendTo(pageCtrl);\n\t\t\t\tjQuery('<span>'+j+'</span>').appendTo(pageCtrl2);\n  \t\t\t}\n\t    }\n\t}\n    for (var i = (pageNum-1)*" . $args['insectsPerPage'] . "; i < searchResults.features.length && i < pageNum*" . $args['insectsPerPage'] . "; i++){\n\t\taddInsect(searchResults.features[i].attributes);\n\t}\n\tif(numPages > 1) {\n\t\tpageCtrl2.appendTo('#results-insects-results');\n\t}\n}\n\n// searchLayer in map is used for georeferencing.\n// map editLayer is switched off.\nsearchLayer = null;\ninseeLayer = null;\npolygonLayer = new OpenLayers.Layer.Vector('Polygon Layer', {\n\tstyleMap: new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Red\",\n                    strokeColor: \"Red\",\n                    fillOpacity: 0,\n                    strokeWidth: 1\n                  })\n\t}),\n\tdisplayInLayerSwitcher: false\n});\npolygonLayer.events.register('featuresadded', {}, function(a1){\n\tpolygonLayer.map.searchLayer.destroyFeatures();\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroyFeatures();\n});          \nlocationLayer = new OpenLayers.Layer.Vector('Location Layer',\n\t{displayInLayerSwitcher: false});\ninseeProtocol = new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n              featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['NOM', 'INSEE_NEW', 'DEPT_NUM', 'DEPT_NOM', 'REG_NUM', 'REG_NOM']\n  \t\t\t});\n\n\njQuery('#search-insee-button').click(function(){\n\tif(inseeLayer != null)\n\t\tinseeLayer.destroy();\n\tpolygonLayer.map.searchLayer.destroyFeatures();\n\tpolygonLayer.destroyFeatures();\n\tvar filters = [];\n  \tvar place = jQuery('input[name=place\\:INSEE]').val();\n  \tif(place == '" . lang::get('LANG_INSEE') . "') return;\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_NEW',\n    \t\tvalue: place\n  \t\t}));\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO ,\n    \t\tproperty: 'INSEE_OLD',\n    \t\tvalue: place\n  \t\t}));\n\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tvar styleMap = new OpenLayers.StyleMap({\n                \"default\": new OpenLayers.Style({\n                    fillColor: \"Red\",\n                    strokeColor: \"Red\",\n                    fillOpacity: 0,\n                    strokeWidth: 1\n                  })\n\t});\n\tinseeLayer = new OpenLayers.Layer.Vector('INSEE Layer', {\n\t\t  styleMap: styleMap,\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url:  '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['INSEE_url']) . "',\n\t          featurePrefix: '" . $args['INSEE_prefix'] . "',\n              featureType: '" . $args['INSEE_type'] . "',\n              geometryName:'the_geom',\n              featureNS: '" . $args['INSEE_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0'                  \n      \t\t  ,propertyNames: ['the_geom']\n  \t\t\t})\n    });\n\tinseeLayer.events.register('featuresadded', {}, function(a1){\n\t\tvar div = jQuery('#map')[0];\n\t\tdiv.map.searchLayer.destroyFeatures();\n\t\tvar bounds=inseeLayer.getDataExtent();\n    \tvar dy = (bounds.top-bounds.bottom)/10;\n    \tvar dx = (bounds.right-bounds.left)/10;\n    \tbounds.top = bounds.top + dy;\n    \tbounds.bottom = bounds.bottom - dy;\n    \tbounds.right = bounds.right + dx;\n    \tbounds.left = bounds.left - dx;\n    \t// if showing a point, don't zoom in too far\n    \tif (dy===0 && dx===0) {\n    \t\tdiv.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\n    \t} else {\n    \t\tdiv.map.zoomToExtent(bounds);\n    \t}\n    });\n\tinseeLayer.events.register('loadend', {}, function(){\n\t\tif(inseeLayer.features.length == 0){\n\t\t\talert(\"" . lang::get('LANG_NO_INSEE') . "\");\n\t\t}\n    });\n    jQuery('#map')[0].map.addLayer(inseeLayer);\n\tstrategy.load({filter: new OpenLayers.Filter.Logical({\n\t\t\t      type: OpenLayers.Filter.Logical.OR,\n\t\t\t      filters: filters\n\t\t  \t  })});\n});\n\njQuery('#search-collections-button').click(function(){\n\tjQuery('#results-insects-header,#results-insects-results').addClass('filter-hide');\n\tjQuery('#results-collections-header,#results-collections-results').removeClass('filter-hide');\n\tjQuery('#results-collections-header').addClass('ui-state-active').removeClass('ui-state-default');\n\trunSearch(true);\n});\njQuery('#search-insects-button').click(function(){\n\tjQuery('#results-collections-header,#results-collections-results').addClass('filter-hide');\n\tjQuery('#results-insects-header,#results-insects-results').removeClass('filter-hide');\n\tjQuery('#results-insects-header').addClass('ui-state-active').removeClass('ui-state-default');\n\trunSearch(false);\n});\n\nrunSearch = function(forCollections){\n  \tvar ORgroup = [];\n\t\n  \tif(searchLayer != null)\n\t\tsearchLayer.destroy();\n\t\t\n\tvar use_insects = false;\n    jQuery('#results-collections-results,#results-insects-results').empty();\n\tjQuery('#focus-occurrence,#focus-collection').addClass('filter-hide');\n\tvar filters = [];\n\t// By default restrict selection to area displayed on map. When using the georeferencing system the map searchLayer\n\t// will contain a single point zoomed in appropriately.\n\tvar mapBounds = jQuery('#map')[0].map.getExtent();\n\tif (mapBounds != null){\n\t  filters.push(new OpenLayers.Filter.Spatial({\n    \ttype: OpenLayers.Filter.Spatial.BBOX,\n    \tproperty: 'geom',\n    \tvalue: mapBounds\n  \t  }));\n  \t}\n  \tif(inseeLayer != null){\n  \t\tif(inseeLayer.features.length > 0){\n  \t\t\t// should only be one entry in the inseeLayer\n\t\t\tfilters.push(new OpenLayers.Filter.Spatial({\n    \t\t\ttype: OpenLayers.Filter.Spatial.WITHIN,\n    \t\t\tproperty: 'geom',\n    \t\t\tvalue: inseeLayer.features[0].geometry\n\t\t  \t}));\n  \t\t}\n  \t}\n  \tif(polygonLayer != null){\n  \t\tif(polygonLayer.features.length > 0){\n  \t\t\tORgroup = [];\n  \t\t\tfor(i=0; i< polygonLayer.features.length; i++){\n\t\t\t\tORgroup.push(new OpenLayers.Filter.Spatial({\n    \t\t\t\ttype: OpenLayers.Filter.Spatial.WITHIN,\n\t    \t\t\tproperty: 'geom',\n    \t\t\t\tvalue: polygonLayer.features[i].geometry\n\t\t  \t\t}));\n  \t\t\t}\n\t\t  \tif(ORgroup.length > 1){\n\t\t\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\t\t\tfilters: ORgroup\n\t\t\t\t}));\n\t\t\t} else {\n  \t\t\t\tif(ORgroup.length == 1){\n\t\t\t \t\tfilters.push(ORgroup[0]);\n\t \t\t\t}\n\t\t  \t} \t\n  \t\t}\n  \t}\n  \t// Only deal with completed collections on our survey.\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\ttype: OpenLayers.Filter.Comparison.LIKE,\n    \tproperty: 'collection_attributes',\n    \tvalue: '*{|" . $args['complete_attr_id'] . "|,1}*'\n  \t}));\n  \tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\ttype: OpenLayers.Filter.Comparison.EQUAL_TO,\n    \tproperty: 'survey_id',\n    \tvalue: '" . $args['survey_id'] . "'\n  \t}));\n  \t\n  \tvar user = jQuery('input[name=username]').val();\n  \tif(user != ''){\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE,\n    \t\tproperty: 'collection_attributes',\n    \t\tvalue: '*{|" . $args['username_attr_id'] . "|,'+user+'}*'\n  \t\t}));\n  \t}\n  \t\n  \tvar start_date = jQuery('input[name=start_date]').val();\n  \tvar end_date = jQuery('input[name=end_date]').val();\n  \tif(start_date != '" . lang::get('click here') . "' && start_date != ''){\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.GREATER_THAN  ,\n    \t\tproperty: 'date_end',\n    \t\tvalue: start_date\n  \t\t}));\n  \t}\n  \tif(end_date != '" . lang::get('click here') . "' && end_date != ''){\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LESS_THAN  ,\n    \t\tproperty: 'date_start',\n    \t\tvalue: end_date\n  \t\t}));\n  \t}\n  \t\n  \tvar flower = jQuery('select[name=flower\\:taxa_taxon_list_id]').val();\n  \tif(flower != ''){\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'flower_taxon',\n    \t\tvalue: '*|'+flower+'|*'\n  \t\t}));\n  \t}\n \n  \tORgroup = [];\n  \tjQuery('#flower-filter-body').find('[name^=occAttr:" . $args['flower_type_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'flower_attributes',\n    \t\tvalue: '*{|" . $args['flower_type_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n \n  \tORgroup = [];\n  \tjQuery('#flower-filter-body').find('[name^=locAttr:" . $args['habitat_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'location_attributes',\n    \t\tvalue: '*{|" . $args['habitat_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n  \t\n  \tvar insect = jQuery('select[name=insect\\:taxa_taxon_list_id]').val();\n  \tif(insect != ''){\n  \t\tuse_insects = true;\n  \t\tfilters.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: forCollections ? 'insects' : 'insect_taxon',\n    \t\tvalue: '*|'+insect+'|*'\n  \t\t}));\n  \t}\n\n  \tORgroup = [];\n  \tjQuery('#insect-filter-body').find('[name^=smpAttr:" . $args['sky_state_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tuse_insects = true;\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'session_attributes',\n    \t\tvalue: '*{|" . $args['sky_state_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n\n  \tORgroup = [];\n  \tjQuery('#insect-filter-body').find('[name^=smpAttr:" . $args['temperature_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tuse_insects = true;\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'session_attributes',\n    \t\tvalue: '*{|" . $args['temperature_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n\n  \tORgroup = [];\n  \tjQuery('#insect-filter-body').find('[name^=smpAttr:" . $args['wind_attr_id'] . "]').filter('[checked]').each(function(index, elem){\n  \t\tuse_insects = true;\n  \t\tORgroup.push(new OpenLayers.Filter.Comparison({\n  \t\t\ttype: OpenLayers.Filter.Comparison.LIKE ,\n    \t\tproperty: 'session_attributes',\n    \t\tvalue: '*{|" . $args['wind_attr_id'] . "|,'+elem.value+'}*'\n  \t\t}));\n  \t});\n  \tif(ORgroup.length > 1){\n\t\tfilters.push(new OpenLayers.Filter.Logical({\n\t\t\ttype: OpenLayers.Filter.Logical.OR,\n\t\t\tfilters: ORgroup\n\t\t}));\n\t} else {\n  \t\tif(ORgroup.length == 1){\n\t \t\tfilters.push(ORgroup[0]);\n\t \t}\n  \t}\n\n\t// TODO need to do shade : this needs to be altered so that the attribute is a termlist\n  \t\n\tvar strategy = new OpenLayers.Strategy.Fixed({preload: false, autoActivate: false});\n\tsearchLayer = new OpenLayers.Layer.Vector('Search Layer', {\n          strategies: [strategy],\n          displayInLayerSwitcher: false,\n\t      protocol: new OpenLayers.Protocol.WFS({\n              url: '" . str_replace("{HOST}", $_SERVER['HTTP_HOST'], $args['search_url']) . "',\n              featurePrefix: '" . $args['search_prefix'] . "',\n              featureType: forCollections ? (use_insects ? 'poll_collection_insects' : 'poll_collections') : 'poll_insects',\n              geometryName:'geom',\n              featureNS: '" . $args['search_ns'] . "',\n              srsName: 'EPSG:900913',\n              version: '1.1.0',   \n              maxFeatures: " . $args['max_features'] . ",               \n//      \t\t  propertyNames: forCollections ? ['collection_id','date_start','date_end','geom','location_name','location_image_path','flower_image_path','flower_id','flower_taxon','collection_attributes','location_attributes','flower_attributes']\n              propertyNames: forCollections ? ['collection_id','date_start','date_end','geom','location_name','location_image_path','flower_image_path','flower_id','flower_taxon','collection_attributes','location_attributes','flower_attributes']\n      \t\t  \t\t\t\t\t\t\t: ['insect_id','collection_id','geom','insect_image_path']\n\t\t  })\n\t});\n\tif(forCollections) {\n\t\tsearchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tsearchResults = a1;\n\t\t\tif(searchResults.features.length >= " . $args['max_features'] . "){\n\t\t\t\talert(\"" . lang::get('LANG_Max_Features_Reached') . "\");\n\t\t\t}\n\t\t\tsetCollectionPage(1);\n\t\t});\n\t} else {\n\t\tsearchLayer.events.register('featuresadded', {}, function(a1){\n\t\t\tsearchResults = a1;\n\t\t\tif(searchResults.features.length >= " . $args['max_features'] . "){\n\t\t\t\talert(\"" . lang::get('LANG_Max_Features_Reached') . "\");\n\t\t\t}\n\t\t\tsetInsectPage(1);\n\t\t});\n\t}\n\tjQuery('#map')[0].map.addLayer(searchLayer);\n\tstrategy.load({filter: new OpenLayers.Filter.Logical({\n\t\t\t      type: OpenLayers.Filter.Logical.AND,\n\t\t\t      filters: filters\n\t\t  \t  })});\n};\n\nsearchResults = null;  \ncollection = '';\n\njQuery('form#fo-doubt-form').ajaxForm({ \n\tdataType:  'json', \n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id');\n\t\t\tjQuery('[name=occurrence_comment\\:comment]').val(\"" . lang::get('LANG_Doubt_Comment') . "\");\n\t\t\tjQuery('#fo-new-comment-button').click();\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('form#fo-new-insect-id-form').ajaxForm({ \n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fo-new-insect-id-form').valid()) { return false; }\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('[name=determination\\:taxa_taxon_list_id]').val('');\n\t\t\tjQuery('#fo-new-insect-id').removeClass('ui-accordion-content-active');\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('form#fo-new-flower-id-form').ajaxForm({ \n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fo-new-flower-id-form').valid()) { return false; }\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('[name=determination\\:taxa_taxon_list_id]').val('');\n\t\t\tjQuery('#fo-new-flower-id').removeClass('ui-accordion-content-active');\n\t\t\tloadDeterminations(jQuery('[name=determination\\:occurrence_id]').val(), '#fo-id-history', '#fo-current-id');\n\t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('#fo-new-comment-form').ajaxForm({ \n\t// dataType identifies the expected content type of the server response \n\tdataType:  'json', \n\t// success identifies the function to invoke when the server response \n\t// has been received \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fo-new-comment-form').valid()) { return false; }\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('[name=occurrence_comment\\:comment]').val('');\n\t\t\tjQuery('#fo-new-comment').removeClass('ui-accordion-content-active');\n\t\t\tloadComments(jQuery('[name=occurrence_comment\\:occurrence_id]').val(), '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body');\n  \t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\njQuery('#fc-new-comment-form').ajaxForm({ \n\tdataType:  'json', \n\tbeforeSubmit:   function(data, obj, options){\n\t\tif (!jQuery('form#fc-new-comment-form').valid()) { return false; }\n\t\treturn true;\n\t},\n\tsuccess:   function(data){\n\t\tif(data.error == undefined){\n\t\t\tjQuery('[name=sample_comment\\:comment]').val('');\n\t\t\tjQuery('#fc-new-comment').removeClass('ui-accordion-content-active');\n\t\t\tloadComments(jQuery('[name=sample_comment\\:sample_id]').val(), '#fc-comment-list', 'sample_comment', 'sample_id', 'sample-comment-block', 'sample-comment-body');\n  \t\t} else {\n\t\t\talert(data.error);\n\t\t}\n\t} \n});\n\nloadSampleAttributes = function(keyValue){\n\tjQuery('#fo-insect-start-time,#fo-insect-end-time,#fo-insect-sky,#fo-insect-temp,#fo-insect-wind,#fo-insect-shade').empty();\n\t\$.getJSON(\"" . $svcUrl . "/data/sample_attribute_value\"  +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&sample_id=\" + keyValue + \"&callback=?\", function(attrdata) {\n\t\tif (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id && (attrdata[i].iso == null || attrdata[i].iso == '' || attrdata[i].iso == '" . $language . "')){\n\t\t\t\t\tswitch(parseInt(attrdata[i].sample_attribute_id)){\n\t\t\t\t\t\tcase " . $args['start_time_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-start-time').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase " . $args['end_time_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-end-time').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['sky_state_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-sky').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['temperature_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-temp').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['wind_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-wind').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\tcase " . $args['shade_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('#fo-insect-shade').append(attrdata[i].value);\n\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n}\nloadOccurrenceAttributes = function(keyValue){\n\tjQuery('#focus-flower-type').empty();\n\t\$.getJSON(\"" . $svcUrl . "/data/occurrence_attribute_value\"  +\n\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&occurrence_id=\" + keyValue + \"&iso=" . $language . "&callback=?\", function(attrdata) {\n\t\tif (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].occurrence_attribute_id)){\n\t\t\t\t\t\tcase " . $args['flower_type_attr_id'] . ":\n\t\t\t\t\t\t\tjQuery('<span>'+attrdata[i].value+'</span>').appendTo('#focus-flower-type');\n\t\t\t\t\t\t\tbreak;\n  \t}}}}});\n}\nloadLocationAttributes = function(keyValue){\n\tjQuery('#focus-habitat').empty();\n\thabitat_string = '';\n\t\$.getJSON(\"" . $svcUrl . "/data/location_attribute_value\"  +\n\t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&location_id=\" + keyValue + \"&iso=" . $language . "&callback=?\", function(attrdata) {\n\t\tif (attrdata.length>0) {\n\t\t\tfor(i=0; i< attrdata.length; i++){\n\t\t\t\tif (attrdata[i].id){\n\t\t\t\t\tswitch(parseInt(attrdata[i].location_attribute_id)){\n\t\t\t\t\t\tcase " . $args['habitat_attr_id'] . ":\n\t\t\t\t\t\t\thabitat_string = (habitat_string == '' ? attrdata[i] : (habitat_string + ' | ' + attrdata[i]));\n\t\t\t\t\t\t\tbreak;\n\t\t\t}}}\n\t\t\tjQuery('<span>'+habitat_string+'</span>').appendTo('#focus-habitat');\n  }});\n}\nimageRatio = 3/4;\n\nloadImage = function(imageTable, key, keyValue, target){\n\tjQuery(target).empty();\n\t\$.getJSON(\"" . $svcUrl . "/data/\" + imageTable +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\", function(imageData) {\n\t\tif (imageData.length>0) {\n\t\t\tvar img = new Image();\n\t\t\tjQuery(img)\n        \t\t.load(function () {\n        \t\t\tjQuery(target).empty().append(this);\n\t\t\t    })\n\t\t\t    .attr('src', '" . data_entry_helper::$base_url . data_entry_helper::$indicia_upload_path . "'+imageData[0].path)\n\t\t\t\t.css('max-width', \$(target).width()).css('max-height', \$(target).width()*imageRatio)\n\t\t\t\t.css('vertical-align', 'middle').css('margin-left', 'auto').css('margin-right', 'auto').css('display', 'block');\n\t\t}\n\t});\n}\n\nloadDeterminations = function(keyValue, historyID, currentID){\n\tjQuery(historyID).empty().append('<strong>" . lang::get('LANG_History_Title') . "</strong>');\n\tjQuery(currentID).empty();\n\tjQuery('#fo-taxon').empty();\n\tjQuery('#fo-warning').addClass('insect-ok').removeClass('insect-dubious').removeClass('insect-unknown');\n\t\$.getJSON(\"" . $svcUrl . "/data/determination\" +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&occurrence_id=\" + keyValue + \"&callback=?\", function(detData) {\n   \t\tif (detData.length>0) {\n\t\t\tvar i = detData.length-1;\n   \t\t\tjQuery('#fo-doubt-form').find('[name=determination\\:id]').val(detData[i].id);\n   \t\t\tjQuery('#fo-doubt-form').find('[name=determination\\:occurrence_id]').val(detData[i].occurrence_id);\n   \t\t\tvar string = '';\n\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\tstring = detData[i].taxon;\n\t\t\t\tjQuery('#fo-taxon').append(detData[i].taxon);\n  \t\t\t}\n\t\t\tif(detData[i].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\tstring = (string == '' ? '' : string + ', ') + detData[i].taxon_text_description;\n\t\t\t}\n\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\tstring = (string == '' ? '' : string + ', ') + detData[i].taxon_text_description;\n\t\t\t}\n\t\t\tjQuery('<p><strong>'+string+ '</strong> " . lang::get('LANG_Comment_By') . "' + detData[i].person_name + ' ' + detData[i].updated_on + '</p>').appendTo(currentID)\n\t\t\tif(detData[i].dubious == 'Y'){\n\t\t\t\tjQuery(\"<p>" . lang::get('LANG_Doubt_Expressed') . "</p>\").appendTo(currentID)\n\t\t\t\tjQuery('#fo-warning').removeClass('insect-ok').addClass('insect-dubious');\n\t\t\t}\n\t\t\tfor(i=detData.length - 2; i >= 0; i--){ // deliberately miss last one, in reverse order\n\t\t\t\tvar string = detData[i].updated_on + ' : ';\n\t\t\t\tif(detData[i].taxon != '' && detData[i].taxon != null){\n\t\t\t\t\tstring = string + detData[i].taxon + ', ';\n\t\t\t\t}\n\t\t\t\tif(detData[i].taxon_text_description != '' && detData[i].taxon_text_description != null){\n\t\t\t\t\tstring = string + detData[i].taxon_text_description + ', ';\n\t\t\t\t}\n\t\t\t\tif(detData[i].taxon_extra_info != '' && detData[i].taxon_extra_info != null){\n\t\t\t\t\tstring = string + detData[i].taxon_text_description ;\n\t\t\t\t}\n\t\t\t\tjQuery('<p>'+string+ ' " . lang::get('LANG_Comment_By') . "' + detData[i].person_name+'</p>').appendTo(historyID)\n\t\t\t}\n\t\t} else {\n\t\t\tjQuery('#fo-doubt-button').hide();\n\t\t\tjQuery('#fo-warning').removeClass('insect-ok').addClass('insect-unknown');\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Determinations') . "</p>')\n\t\t\t\t\t.appendTo(historyID);\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Determinations') . "</p>')\n\t\t\t\t\t.appendTo(currentID);\n\t\t}\n\t});\n};\nloadComments = function(keyValue, block, table, key, blockClass, bodyClass){\n\tjQuery(block).empty();\n\t\$.getJSON(\"" . $svcUrl . "/data/\" + table +\n   \t\t\t\"?mode=json&view=list&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\", function(commentData) {\n   \t\tif (commentData.length>0) {\n   \t\t\tfor(i=commentData.length - 1; i >= 0; i--){\n\t   \t\t\tvar newCommentDetails = jQuery('<div class=\"'+blockClass+'\"/>')\n\t\t\t\t\t.appendTo(block);\n\t\t\t\tjQuery('<span>" . lang::get('LANG_Comment_By') . "' + commentData[i].person_name + ' ' + commentData[i].updated_on + '</span>')\n\t\t\t\t\t.appendTo(newCommentDetails);\n\t   \t\t\tvar newComment = jQuery('<div class=\"'+bodyClass+'\"/>')\n\t\t\t\t\t.appendTo(block);\n\t\t\t\tjQuery('<p>' + commentData[i].comment + '</p>')\n\t\t\t\t\t.appendTo(newComment);\n\t\t\t}\n\t\t} else {\n\t\t\tjQuery('<p>" . lang::get('LANG_No_Comments') . "</p>')\n\t\t\t\t\t.appendTo(block);\n\t\t}\n\t});\n};\n\nloadInsectAddnInfo = function(keyValue){\n\t// TODO convert buttons into thumbnails\n\tcollection = '';\n\tjQuery('#fo-prev-button,#fo-next-button').hide();\n\t\n\t// fetch occurrence details first to get the sample_id.\n\t// Get the sample to get the parent_id.\n\t// get all the samples (sessions) with the same parent_id;\n\t// fetch all the occurrences of the sessions.\n\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" + keyValue +\n   \t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&callback=?\", function(occData) {\n   \t\tif (occData.length > 0) {\n\t\t\t\$.getJSON(\"" . $svcUrl . "/data/sample/\" + occData[0].sample_id +\n   \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&callback=?\", function(smpData) {\n   \t\t\t\tif (smpData.length > 0) {\n   \t\t\t\t\tcollection = smpData[0].parent_id;\n\t\t\t\t\tjQuery('#fo-insect-date').empty().append(smpData[0].date_start);\n\t\t\t\t\tloadSampleAttributes(smpData[0].id);\n\t\t\t\t\tjQuery('#fo-collection-button').attr('smpID',smpData[0].parent_id).show();\n\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/sample/\" +\n   \t\t\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\t\t\"&parent_id=\" + smpData[0].parent_id + \"&callback=?\", function(smpList) {\n   \t\t\t\t\t\tif (smpList.length > 0) {\n   \t\t\t\t\t\t\tfor(j=0; j< smpList.length; j++){\n\t\t   \t\t\t\t\t\t\$.getJSON(\"" . $svcUrl . "/data/occurrence\" +\n   \t\t\t\t\t\t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\t\t\t\t\t\"&sample_id=\" + smpList[j].id + \"&orderby=id&callback=?\", function(occList) {\n\t   \t\t\t\t\t\t\t\tif(occList.length > 0){\n   \t\t\t\t\t\t\t\t\t\tfor(i=0; i< occList.length; i++){\n   \t\t\t\t\t\t\t\t\t\t\tif(parseInt(occList[i].id) == parseInt(keyValue)){\n   \t\t\t\t\t\t\t\t\t\t\t\tif(i>0){\n\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#fo-prev-button').attr('occID',occList[i-1].id).show();\n  \t\t\t\t\t\t\t\t\t\t\t\t}\n   \t\t\t\t\t\t\t\t\t\t\t\tif(i< occList.length-1){\n\t\t\t\t\t\t\t\t\t\t\t\t\tjQuery('#fo-next-button').attr('occID',occList[i+1].id).show();\n  \t\t\t\t\t\t\t\t\t\t\t\t}\n  \t\t\t\t\t\t\t\t\t\t\t}\n   \t\t\t\t\t\t\t\t\t\t}\n   \t\t\t\t\t\t\t\t\t}\n   \t\t\t\t\t\t\t\t});\n   \t\t\t\t\t\t\t}\n   \t\t\t\t\t\t}\n  \t\t\t\t\t});\n  \t\t\t\t}\n   \t\t   \t});\n   \t\t}\n   \t});\n}\nloadFlowerAddnInfo = function(keyValue){\n\t// fetch occurrence details first to get the collection id.\n\tloadOccurrenceAttributes(keyValue);\n\t\$.getJSON(\"" . $svcUrl . "/data/occurrence/\" + keyValue +\n   \t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&callback=?\", function(occData) {\n   \t\tif (occData.length > 0) {\n\t\t\tjQuery('#fo-collection-button').attr('smpID',occData[0].sample_id).show();\n   \t\t\t\$.getJSON(\"" . $svcUrl . "/data/sample/\" + occData[0].sample_id +\n   \t\t\t\t\t\"?mode=json&view=detail&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\t\t\"&callback=?\", function(collection) {\n   \t\t\t\tif (collection.length > 0) {\n\t\t\t\t\tloadLocationAttributes(collection.location_id);\n  \t\t\t\t}\n   \t\t   \t});\n   \t\t}\n   \t});\n}\n\nloadInsect = function(insectID){\n    jQuery('#focus-collection,#filter-spec,#filter-footer,#results-insects-header,#results-collections-header,#results-insects-header,#results-insects-results,#results-collections-results,#fo-flower-addn-info').addClass('filter-hide');\n    jQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n    jQuery('#focus-occurrence,#fo-addn-info-header,#fo-insect-addn-info').removeClass('filter-hide');\n\tjQuery('[name=determination\\:occurrence_id]').val(insectID);\n\tjQuery('[name=occurrence_comment\\:occurrence_id]').val(insectID);\n\tjQuery('#fo-new-comment,#fo-new-id').removeClass('ui-accordion-content-active');\n\tjQuery('#fo-new-insect-id-button').show();\n\tjQuery('#fo-new-flower-id-button').hide();\n\tjQuery('#fo-doubt-button')." . (user_access('IForm n' . $node->nid . ' insect expert') || user_access('IForm n' . $node->nid . ' flag dubious insect') ? "show()" : "hide()") . ";\n\tjQuery('#fo-new-comment-button')." . (user_access('IForm n' . $node->nid . ' insect expert') || user_access('IForm n' . $node->nid . ' create insect comment') ? "show()" : "hide()") . ";\n\tloadImage('occurrence_image', 'occurrence_id', insectID, '#fo-image');\n\tloadDeterminations(insectID, '#fo-id-history', '#fo-current-id');\n\tloadInsectAddnInfo(insectID);\n\tloadComments(insectID, '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body');\n}\nloadFlower = function(flowerID){\n\tjQuery('#fo-prev-button,#fo-next-button').hide();\n\tjQuery('#focus-collection,#filter-spec,#filter-footer,#results-insects-header,#results-collections-header,#results-insects-header,#results-insects-results,#results-collections-results,#fo-insect-addn-info').addClass('filter-hide');\n    jQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n\tjQuery('#focus-occurrence,#fo-addn-info-header,#fo-flower-addn-info').removeClass('filter-hide');\n\tjQuery('#fo-new-comment,#fo-new-id').removeClass('ui-accordion-content-active');\n\tjQuery('[name=determination\\:occurrence_id]').val(flowerID);\n\tjQuery('[name=occurrence_comment\\:occurrence_id]').val(flowerID);\n\tjQuery('#fo-new-flower-id-button').show();\n\tjQuery('#fo-new-insect-id-button').hide();\n\tjQuery('#fo-doubt-button')." . (user_access('IForm n' . $node->nid . ' flower expert') || user_access('IForm n' . $node->nid . ' flag dubious flower') ? "show()" : "hide()") . ";\n\tjQuery('#fo-new-comment-button')." . (user_access('IForm n' . $node->nid . ' flower expert') || user_access('IForm n' . $node->nid . ' create flower comment') ? "show()" : "hide()") . ";\n\tloadImage('occurrence_image', 'occurrence_id', flowerID, '#fo-image');\n\tloadDeterminations(flowerID, '#fo-id-history', '#fo-current-id');\n\tloadFlowerAddnInfo(flowerID);\n\tloadComments(flowerID, '#fo-comment-list', 'occurrence_comment', 'occurrence_id', 'occurrence-comment-block', 'occurrence-comment-body');\n}\n\njQuery('#fo-new-comment-button').click(function(){ \n\tjQuery('#fo-new-comment').toggleClass('ui-accordion-content-active');\n});\njQuery('#fc-new-comment-button').click(function(){ \n\tjQuery('#fc-new-comment').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-insect-id-button').click(function(){ \n\tjQuery('#fo-new-insect-id').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-new-flower-id-button').click(function(){ \n\tjQuery('#fo-new-flower-id').toggleClass('ui-accordion-content-active');\n});\njQuery('#fo-collection-button').click(function(){\n\tloadCollection(jQuery(this).attr('smpID'));\n});\njQuery('#fo-prev-button').click(function(){\n\tloadInsect(jQuery(this).attr('occID'));\n});\njQuery('#fo-next-button').click(function(){\n\tloadInsect(jQuery(this).attr('occID'));\n});\n  ";
        data_entry_helper::$onload_javascript .= "\n\tfunction addDrawnGeomToSelection (geometry) {\n    \t// Create the polygon as drawn\n    \tvar feature = new OpenLayers.Feature.Vector(geometry, {});\n    \tpolygonLayer.addFeatures([feature]);\n\t};\n    \n\tpolygonControl = new OpenLayers.Control.DrawFeature(polygonLayer, OpenLayers.Handler.Polygon, {drawFeature: addDrawnGeomToSelection});\n\tpolygonLayer.map.addControl(this.polygonControl);\n\tpolygonControl.activate();\n\tpolygonLayer.map.searchLayer.events.register('featuresadded', {}, function(a1){\n\t\tif(inseeLayer != null)\n\t\t\tinseeLayer.destroyFeatures();\n\t\tpolygonLayer.destroyFeatures();\n\t});          \n";
        switch ($mode) {
            case 'INSECT':
                data_entry_helper::$onload_javascript .= "loadInsect(" . $occID . ");\n\t\t\t";
                break;
            case 'FLOWER':
                data_entry_helper::$onload_javascript .= "loadFlower(" . $occID . ");\n\t\t\t";
                break;
            case 'COLLECTION':
                data_entry_helper::$onload_javascript .= "\n    \t\tjQuery('#focus-occurrence,#filter-spec,#filter-footer,#results-insects-header,#results-collections-header,#results-insects-results,#results-collections-results').addClass('filter-hide');\n    \t\tjQuery('#filter-header').removeClass('ui-state-active').addClass('ui-state-default').removeClass('ui-corner-top').addClass('ui-corner-all');\n    \t\tloadCollection(" . $smpID . ");\n    \t\t";
                break;
            default:
                data_entry_helper::$onload_javascript .= "\n    \t\tjQuery('#focus-occurrence,#focus-collection,#results-insects-header,#results-collections-header,#results-insects-results,#results-collections-results').addClass('filter-hide');\n    \t\t";
                if ($userID != '') {
                    $thisuser = user_load($userID);
                    data_entry_helper::$onload_javascript .= "\n    \t\t\tjQuery('[name=username]').val('" . $thisuser->name . "');\n    \t\t\tjQuery('#search-collections-button').click();\n    \t\t\t";
                }
                break;
        }
        return $r;
    }
    ?>
  <input type="hidden" name="milestone:id" value="<?php 
    echo html::initial_value($values, 'milestone:id');
    ?>
" />
<?php 
    echo $metadata;
}
echo data_entry_helper::hidden_text(array('fieldname' => 'milestone:id', 'default' => html::initial_value($values, 'milestone:id')));
echo data_entry_helper::hidden_text(array('fieldname' => 'website_id', 'default' => html::initial_value($values, 'milestone:website_id')));
echo data_entry_helper::text_input(array('label' => 'Title', 'fieldname' => 'milestone:title', 'class' => 'control-width-4', 'default' => html::initial_value($values, 'milestone:title')));
echo data_entry_helper::select(array('label' => 'Count what?', 'fieldname' => 'milestone:entity', 'lookupValues' => array('T' => 'Species or taxa', 'O' => 'Records', 'M' => 'Media/photos'), 'default' => html::initial_value($values, 'milestone:entity'), 'helpText' => 'Are you targetting a total count of species, records or media/photos for this milestone?'));
echo data_entry_helper::text_input(array('label' => 'Count', 'fieldname' => 'milestone:count', 'class' => 'control-width-2', 'default' => html::initial_value($values, 'milestone:count'), 'helpText' => 'What is the target number that must be reached to hit the milestone?'));
echo data_entry_helper::text_input(array('label' => 'Group ID', 'fieldname' => 'milestone:group_id', 'class' => 'control-width-2', 'default' => html::initial_value($values, 'milestone:group_id'), 'helpText' => 'Optional ID of the recording group associated with the milestone, only users that are members of this group will receive the milestone award.'));
echo data_entry_helper::textarea(array('label' => 'Success message', 'fieldname' => 'milestone:success_message', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'milestone:success_message'), 'helpText' => 'This message will be sent to the user on reaching the milestone as a notification.'));
echo data_entry_helper::text_input(array('label' => 'Awarded by', 'fieldname' => 'milestone:awarded_by', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'milestone:awarded_by'), 'helpText' => 'Which organisation is awarding the milestone? This will appear in the from field for the notification sent to the recorder.'));
//The filter title is actually generated using the milestone title we enter. There are issues with using the built-in validator to detect duplicate titles because the filter supermodel is validated
//first. The filter requires a unique title/sharing/created_by_id option that isn't included in the model, the issue is only
//detected once the system tries to add the filter to the database, this will fail with a general error without even getting as far as doing the milestone model's
//title duplciate detection.
//So to fix this, collect the existing filters from the database so we can compare the titles with the one we create and then
//do the validation manually.
$readAuth = data_entry_helper::get_read_auth(0 - $_SESSION['auth_user']->id, kohana::config('indicia.private_key'));
$existingFilterData = data_entry_helper::get_population_data(array('table' => 'filter', 'extraParams' => $readAuth, 'nocache' => true));
//When we save a milestone when we need to automatically set the filter title as there isn't a separate field
//to fill this in.
//Also hide the "who" filter as we don't need this for milestones as they can apply to all users
//Also manually do the unique milestone/filter title validation (see note above)
data_entry_helper::$javascript .= "\nvar existingFilterData=" . json_encode($existingFilterData) . ";  \n\$('#pane-filter_who').hide();\n\$('#milestones-form').submit(function() {\n  \$('#filter-title-val').val('" . 'Filter for milestone' . " ' + \$('#milestone\\\\:title').val());\n  for (var i = 0; i<existingFilterData.length;i++) {\n    //Note we must allow a duplicate title in the situaton where the duplicate title is for the already existing item\n    if (existingFilterData[i]['title']==\$('#filter-title-val').val() && existingFilterData[i]['id']!=\$('#filter\\\\:id').val()) {\n      alert('The filter title is generated from the milestone title you have entered and would cause a duplicate filter title, please choose a different title');\n      return false;\n    }\n  }\n  \$('#filter-def-val').val(JSON.stringify(indiciaData.filter.def));\n});\n";
$readAuth = data_entry_helper::get_read_auth(0 - $_SESSION['auth_user']->id, kohana::config('indicia.private_key'));
$filterPanelHTML = '<h3>Specify the filter used to define which records count</h3>';
 /**
  * Returns a control to insert onto a parameters form.
  * @param string $key The unique identifier of this control.
  * @param array $info Configuration options for the parameter as defined in the report, including the 
  * description, display (label), default and datatype.
  * @param array $options Control options array
  * @param array $tools Any tools to be embedded in the map toolbar are returned in this 
  * parameter rather than as the return result of the function.
  * @return string The HTML for the form parameter.
  */
 private static function get_params_form_control($key, $info, $options, &$tools)
 {
     $r = '';
     $fieldPrefix = isset($options['fieldNamePrefix']) ? $options['fieldNamePrefix'] . '-' : '';
     $ctrlOptions = array('label' => lang::get($info['display']), 'helpText' => $options['helpText'] ? $info['description'] : '', 'fieldname' => $fieldPrefix . $key, 'nocache' => isset($options['nocache']) && $options['nocache']);
     // If this parameter is in the URL or post data, put it in the control instead of the original default
     if (isset($options['defaults'][$key])) {
         $ctrlOptions['default'] = $options['defaults'][$key];
     } elseif (isset($info['default'])) {
         $ctrlOptions['default'] = $info['default'];
     }
     if ($info['datatype'] == 'idlist') {
         // idlists are not for human input so use a hidden.
         $r .= "<input type=\"hidden\" name=\"{$fieldPrefix}{$key}\" value=\"" . self::get_preset_param($options, $key) . "\" class=\"" . $fieldPrefix . "idlist-param\" />\n";
     } elseif (isset($options['extraParams']) && array_key_exists($key, $options['extraParams'])) {
         $r .= "<input type=\"hidden\" name=\"{$fieldPrefix}{$key}\" value=\"" . self::get_preset_param($options, $key) . "\" />\n";
     } elseif ($info['datatype'] == 'lookup' && isset($info['population_call'])) {
         // population call is colon separated, of the form direct|report:table|view|report:idField:captionField:params(key=value,key=value,...)
         $popOpts = explode(':', $info['population_call']);
         $extras = array();
         // if there are any extra parameters on the report lookup call, apply them
         if (count($popOpts) >= 5) {
             // because any extra params might contain colons, any colons from item 5 onwards are considered part of the extra params. So we
             // have to take the remaining items and re-implode them, then split them by commas instead. E.g. population call could be set to
             // direct:term:id:term:term=a:b - in this case option 5 (term=a:b) is not to be split by colons.
             $extraItems = explode(',', implode(':', array_slice($popOpts, 4)));
             foreach ($extraItems as $extraItem) {
                 $extraItem = explode('=', $extraItem);
                 $extras[$extraItem[0]] = $extraItem[1];
             }
         }
         // allow local page configuration to apply extra restrictions on the return values: e.g. only return some location_types from the termlist
         if (isset($options['param_lookup_extras']) && isset($options['param_lookup_extras'][$key])) {
             foreach ($options['param_lookup_extras'][$key] as $param => $value) {
                 // direct table access can handle 'in' statements, reports can't.
                 $extras[$param] = $popOpts[0] == 'direct' ? $value : (is_array($value) ? implode(',', $value) : $value);
             }
             // $extras[$param] = $value;
         }
         $ctrlOptions = array_merge($ctrlOptions, array('valueField' => $popOpts[2], 'captionField' => $popOpts[3], 'blankText' => '<please select>', 'extraParams' => $options['readAuth'] + $extras));
         if ($popOpts[0] == 'direct') {
             $ctrlOptions['table'] = $popOpts[1];
         } else {
             $ctrlOptions['report'] = $popOpts[1];
         }
         if (isset($info['linked_to']) && isset($info['linked_filter_field'])) {
             $ctrlOptions['filterIncludesNulls'] = false;
             //exclude null entries from filter field by default
             if (isset($options['extraParams']) && array_key_exists($info['linked_to'], $options['extraParams'])) {
                 // if the control this is linked to is hidden because it has a preset value, just use that value as a filter on the
                 // population call for this control
                 $ctrlOptions = array_merge($ctrlOptions, array('extraParams' => array_merge($ctrlOptions['extraParams'], array('query' => json_encode(array('in' => array($info['linked_filter_field'] => array($options['extraParams'][$info['linked_to']], null))))))));
             } else {
                 // otherwise link the 2 controls
                 $ctrlOptions = array_merge($ctrlOptions, array('parentControlId' => $fieldPrefix . $info['linked_to'], 'filterField' => $info['linked_filter_field'], 'parentControlLabel' => $options['form'][$info['linked_to']]['display']));
             }
         }
         //If user has set option, then make any lookup parameter an autocomplete, note that autocomplete controls also have a "selectMode"
         //which is why there is a further option provided if you want to use that mode.
         if (!empty($options['forceLookupParamAutocomplete']) && $options['forceLookupParamAutocomplete'] == true) {
             if (!empty($options['forceLookupParamAutocompleteSelectMode']) && $options['forceLookupParamAutocompleteSelectMode'] == true) {
                 $ctrlOptions['selectMode'] = true;
             }
             $r .= data_entry_helper::autocomplete($ctrlOptions);
         } else {
             $r .= data_entry_helper::select($ctrlOptions);
         }
     } elseif ($info['datatype'] == 'lookup' && isset($info['lookup_values'])) {
         // Convert the lookup values into an associative array
         $lookups = explode(',', $info['lookup_values']);
         $lookupsAssoc = array();
         foreach ($lookups as $lookup) {
             $lookup = explode(':', $lookup);
             $lookupsAssoc[$lookup[0]] = $lookup[1];
         }
         $ctrlOptions = array_merge($ctrlOptions, array('blankText' => '<' . lang::get('please select') . '>', 'lookupValues' => $lookupsAssoc));
         //If user has set option, then make any lookup parameter an autocomplete, note that autocomplete controls also have a "selectMode"
         //which is why there is a further option provided if you want to use that mode.
         if (!empty($options['forceLookupParamAutocomplete']) && $options['forceLookupParamAutocomplete'] == true) {
             if (!empty($options['forceLookupParamAutocompleteSelectMode']) && $options['forceLookupParamAutocompleteSelectMode'] == true) {
                 $ctrlOptions['selectMode'] = true;
             }
             $r .= data_entry_helper::autocomplete($ctrlOptions);
         } else {
             $r .= data_entry_helper::select($ctrlOptions);
         }
     } elseif ($info['datatype'] == 'date') {
         $r .= data_entry_helper::date_picker($ctrlOptions);
     } elseif ($info['datatype'] == 'geometry') {
         $tools = array('Polygon', 'Line', 'Point');
     } elseif ($info['datatype'] == 'polygon') {
         $tools = array('Polygon');
     } elseif ($info['datatype'] == 'line') {
         $tools = array('Line');
     } elseif ($info['datatype'] == 'point') {
         $tools = array('Point');
     } else {
         if (method_exists('data_entry_helper', $info['datatype'])) {
             $ctrl = $info['datatype'];
             $r .= data_entry_helper::$ctrl($ctrlOptions);
         } else {
             $r .= data_entry_helper::text_input($ctrlOptions);
         }
     }
     return $r;
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  * @todo: Implement this method 
  */
 public static function get_form($args, $node, $response = null)
 {
     global $indicia_templates, $user;
     data_entry_helper::enable_validation('entry_form');
     $url = !empty($_SERVER['HTTPS']) ? "https://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] : "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
     $r = data_entry_helper::loading_block_start();
     $r .= "<form method=\"post\" id=\"entry_form\" action=\"{$url}\">\n";
     $readAuth = data_entry_helper::get_read_auth($args['website_id'], $args['password']);
     $r .= "<div id=\"controls\">\n";
     if ($args['interface'] != 'one_page') {
         $r .= "<ul>\n";
         if ($user->uid == 0) {
             $r .= '  <li><a href="#about_you"><span>' . lang::get('about you') . "</span></a></li>\n";
         }
         $r .= '  <li><a href="#species"><span>' . lang::get('what did you see') . "</span></a></li>\n";
         $r .= '  <li><a href="#place"><span>' . lang::get('where was it') . "</span></a></li>\n";
         $r .= '  <li><a href="#other"><span>' . lang::get('other information') . "</span></a></li>\n";
         $r .= "</ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface']));
     }
     if ($user->uid == 0) {
         $r .= "<fieldset id=\"about_you\">\n";
         if ($args['interface'] == 'one_page') {
             $r .= '<legend>' . lang::get('about you') . '</legend>';
         }
         $r .= data_entry_helper::text_input(array('label' => lang::get('first name'), 'fieldname' => 'smpAttr:' . $args['first_name_attr_id'], 'class' => 'control-width-4', 'validation' => array('required')));
         $r .= data_entry_helper::text_input(array('label' => lang::get('surname'), 'fieldname' => 'smpAttr:' . $args['surname_attr_id'], 'class' => 'control-width-4', 'validation' => array('required')));
         $r .= data_entry_helper::text_input(array('label' => lang::get('phone number'), 'fieldname' => 'smpAttr:' . $args['phone_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('email'), 'fieldname' => 'smpAttr:' . $args['email_attr_id'], 'class' => 'control-width-4 optional', 'validation' => array('email')));
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'first'));
         }
         $r .= "</fieldset>\n";
     }
     // Species tab
     $r .= "<fieldset id=\"species\">\n";
     if ($args['interface'] == 'one_page') {
         $r .= '<legend>' . lang::get('what did you see') . '</legend>';
     }
     $species_list_args = array('label' => lang::get('Species'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'listId' => $args['species_list_id'], 'columns' => 1, 'parentField' => 'parent_id', 'checkboxCol' => false, 'occAttrs' => array($args['abundance_attr_id']), 'extraParams' => $readAuth + array('view' => 'detail', 'orderby' => 'taxonomic_sort_order'), 'survey_id' => $args['survey_id'], 'header' => false, 'view' => 'detail', 'PHPtaxonLabel' => true);
     // Build a nice template to show a picture of each species, with fancybox.
     data_entry_helper::add_resource('fancybox');
     data_entry_helper::$javascript .= "jQuery('a.fancybox').fancybox();\n";
     $indicia_templates['taxon_label'] = 'return \'<div class="taxon-cell">' . '<a href="' . data_entry_helper::$base_url . 'upload/{image_path}" class="fancybox" >' . '<img alt="{taxon}" src="' . data_entry_helper::$base_url . 'upload/med-{image_path}" width="250"/></a>' . '<div>{taxon}</div></div>' . '<div class="taxon-desc"><ul><li>\'.str_replace("\\n", "</li><li>","{description_in_list}").\'</li></ul>' . '<a href="http://www.marine-life.org.uk/northeastcetaceans/?q=\'.
     strtolower(str_replace(array(" ", "\\\'"), array("-", ""), "{taxon}")).
     \'" target="_blank" class="ui-state-default ui-corner-all indicia-button">' . lang::get('More Info') . '...</a></div>\';';
     // Template the taxon label cell
     $indicia_templates['taxon_label_cell'] = "\n<td class='scTaxonCell'>{content}</td>";
     // Also template the attribute controls to show the label in place.
     $indicia_templates['attribute_cell'] = "\n<td class='scOccAttrCell'><label>{label}:</label><br/>{content}</td>";
     $r .= data_entry_helper::species_checklist($species_list_args);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->uid == 0 ? 'middle' : 'first'));
     }
     $r .= "</fieldset>";
     // --Place tab--
     $r .= "<fieldset id=\"place\">\n";
     if ($args['interface'] == 'one_page') {
         $r .= '<legend>' . lang::get('where was it') . '</legend>';
     }
     $r .= data_entry_helper::radio_group(array('label' => 'Where were you when you made the sighting?', 'fieldname' => 'smpAttr:' . $args['platform_attr_id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $readAuth + array('termlist_id' => $args['platform_termlist_id']), 'sep' => '<br />', 'labelClass' => 'auto', 'class' => 'inline sighting-platform', 'validation' => array('required')));
     $r .= '<div id="place_wrapper" class="hidden">';
     // Some instructions only visible when entering data from a boat
     $r .= '<p class="boat_mode page-notice ui-state-highlight ui-corner-all">' . lang::get('Instructions for when on boat') . '</p>';
     // Some instructions only visible when entering data from the shore
     $r .= '<p class="shore_mode page-notice ui-state-highlight ui-corner-all">' . lang::get('Instructions for clicking on map') . '</p>';
     $r .= '<div class="boat_mode">';
     // Add help examples to the lat and long boxes
     $indicia_templates['sref_textbox_latlong'] = '<label for="{idLat}">{labelLat}:</label>' . '<input type="text" id="{idLat}" name="{fieldnameLat}" {class} {disabled} value="{default}" /> <p class="helpText">e.g. 55:12.345N</p>' . '<label for="{idLong}">{labelLong}:</label>' . '<input type="text" id="{idLong}" name="{fieldnameLong}" {class} {disabled} value="{default}" /> <p class="helpText">e.g. 0:45.678W</p>' . '<input type="hidden" id="imp-geom" name="{table}:geom" value="{defaultGeom}" />' . '<input type="text" id="{id}" name="{fieldname}" style="display:none" value="{default}" />';
     $r .= data_entry_helper::sref_and_system(array('systems' => array(4326 => lang::get('Latitude, Longitude')), 'splitLatLong' => true, 'helpText' => lang::get('Instructions for latlong')));
     $r .= '</div>';
     // Initially, we hide the map. Only show it when the user selects the sighting was from the shore,
     // as a click on the map for boat recordings will not be accurate.
     $r .= '<div class="shore_mode">';
     $options = iform_map_get_map_options($args, $readAuth);
     $olOptions = iform_map_get_ol_options($args);
     $options['maxZoom'] = 9;
     // Switch to degrees and decimal minutes for lat long.
     $options['latLongFormat'] = 'DM';
     $r .= data_entry_helper::map_panel($options, $olOptions);
     // Now, add some JavaScript to show or hide the map. Show it for when the sighting was from the shore.
     // Hide it for boat based sightings as we want a GPS coordinate in this case. The JavaScript looks for the
     // checked radio button to see the value
     data_entry_helper::$javascript .= 'jQuery(".sighting-platform input").click(
   function() {
     var platformId = jQuery("input[name=smpAttr\\\\:' . $args['platform_attr_id'] . ']:checked").val();
     if (platformId == ' . $args['platform_mapped_term_id'] . ') {
       jQuery("#place_wrapper").removeClass("hidden");
       jQuery(".shore_mode").removeClass("hidden");
       jQuery(".boat_mode").addClass("hidden");
     } else {          
       jQuery("#place_wrapper").removeClass("hidden");
       jQuery(".shore_mode").addClass("hidden");
       jQuery(".boat_mode").removeClass("hidden");
     }
   }
 );' . "\n";
     // Force existing setting of the radio buttons to reload when showign page after validation failure
     data_entry_helper::$onload_javascript .= '
 jQuery("input[name=smpAttr\\\\:' . $args['platform_attr_id'] . ']:checked").trigger("click");
 ';
     $r .= '</div></div>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls'));
     }
     $r .= '</fieldset>';
     // --Other information tab--
     $r .= "<fieldset id=\"other\">\n";
     // Get authorisation tokens to update and read from the Warehouse.
     $r .= data_entry_helper::get_auth($args['website_id'], $args['password']);
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"occurrence:record_status\" value=\"C\" />\n";
     if ($args['interface'] == 'one_page') {
         $r .= '<legend>' . lang::get('other information') . '</legend>';
     }
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Sighting Date'), 'fieldname' => 'sample:date'));
     $indicia_templates['timeFormat'] = '<label>hh:mm</label><br/>';
     $r .= data_entry_helper::text_input(array('label' => lang::get('Sighting Time'), 'fieldname' => 'smpAttr:' . $args['sample_time_attr_id'], 'class' => 'control-width-1', 'suffixTemplate' => 'timeFormat'));
     $r .= data_entry_helper::textarea(array('label' => lang::get('Any other information'), 'fieldname' => 'sample:comment', 'class' => 'control-width-6', 'helpText' => lang::get('Instructions for any other info')));
     $r .= '<div class="footer">' . data_entry_helper::checkbox(array('label' => lang::get('happy for contact'), 'labelClass' => 'auto', 'fieldname' => 'smpAttr:' . $args['contact_attr_id'])) . '</div>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'last'));
     } else {
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     }
     $r .= "</fieldset></div>";
     $r .= "</form>";
     $r .= data_entry_helper::loading_block_end();
     return $r;
 }
 protected static function get_control_emailaddress($auth, $args, $tabalias, $options)
 {
     return data_entry_helper::text_input(array_merge(array('label' => lang::get('LANG_Email_Address'), 'fieldname' => 'person:email_address', 'class' => 'control-width-5'), $options));
 }
<legend>Verification rule details</legend>
<?php 
data_entry_helper::link_default_stylesheet();
data_entry_helper::enable_validation('entry-form');
if (isset($values['verification_rule:id'])) {
    ?>
  <input type="hidden" name="verification_rule:id" value="<?php 
    echo html::initial_value($values, 'verification_rule:id');
    ?>
" />
<?php 
}
echo data_entry_helper::text_input(array('label' => 'Title', 'fieldname' => 'verification_rule:title', 'class' => 'control-width-4', 'validation' => array('required'), 'default' => html::initial_value($values, 'verification_rule:title')));
echo data_entry_helper::textarea(array('label' => 'Description', 'fieldname' => 'verification_rule:description', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'verification_rule:description')));
echo data_entry_helper::text_input(array('label' => 'Test Type', 'fieldname' => 'verification_rule:test_type', 'class' => 'control-width-4', 'validation' => array('required'), 'default' => html::initial_value($values, 'verification_rule:test_type')));
echo data_entry_helper::text_input(array('label' => 'Source URL', 'fieldname' => 'verification_rule:source_url', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'verification_rule:source_url'), 'helpText' => 'When this verification rule file was imported, this identifies the name of the file ' . 'it was imported from'));
echo data_entry_helper::text_input(array('label' => 'Source Filename', 'fieldname' => 'verification_rule:source_filename', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'verification_rule:source_filename')));
echo data_entry_helper::text_input(array('label' => 'Error Message', 'fieldname' => 'verification_rule:error_message', 'class' => 'control-width-6', 'validation' => array('required'), 'default' => html::initial_value($values, 'verification_rule:error_message')));
echo data_entry_helper::checkbox(array('label' => 'Reverse Rule', 'fieldname' => 'verification_rule:reverse_rule', 'default' => html::initial_value($values, 'verification_rule:reverse_rule'), 'helpText' => 'Tick this box to reverse the rule logic - i.e. items that pass the test are flagged as failures.'));
echo data_entry_helper::textarea(array('label' => 'Metadata', 'fieldname' => 'metaFields:metadata', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'metaFields:metadata'), 'helpText' => 'Additional settings from the header of the verification rule file, in parameter=value format with ' . 'one parameter per line'));
echo data_entry_helper::textarea(array('label' => 'Other Data', 'fieldname' => 'metaFields:data', 'class' => 'control-width-6', 'default' => html::initial_value($values, 'metaFields:data'), 'helpText' => 'Additional settings from the data part of the verification rule file, with blocks of data items ' . 'started by a header name in square brackets, followed by parameters in parameter=value format with ' . 'one parameter per line'));
echo $metadata;
echo html::form_buttons(html::initial_value($values, 'verification_rule:id') != null, false, false);
data_entry_helper::link_default_stylesheet();
data_entry_helper::$dumped_resources[] = 'jquery';
data_entry_helper::$dumped_resources[] = 'jquery_ui';
data_entry_helper::$dumped_resources[] = 'fancybox';
echo data_entry_helper::dump_javascript();
?>
</fieldset>
</form>
 /**
  * Return the generated form output.
  * @return Form HTML.
  */
 public static function get_form($args)
 {
     global $user;
     $logged_in = $user->uid > 0;
     // Get authorisation tokens to update and read from the Warehouse.
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     $readAuth = $auth['read'];
     // enable image viewing with FancyBox - only required if the file box is enabled
     //data_entry_helper::$javascript .= "jQuery(\"a.fancybox\").fancybox();\n";
     $r = "\n<form method=\"post\" id=\"entry_form\">\n";
     if (isset($_GET['taxa_taxon_list_id']) || isset($_GET['taxon_external_key'])) {
         if (isset($_GET['taxa_taxon_list_id'])) {
             $filter = array('id' => $_GET['taxa_taxon_list_id']);
         } else {
             $filter = array('external_key' => $_GET['taxon_external_key']);
         }
         $species = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + $filter + array('taxon_list_id' => $args['list_id'], 'view' => 'detail', 'preferred' => 't')));
         // we need only one result, but there could be more than one picture, therefore multiple rows
         $uniqueMeaning = false;
         if (count($species) == 1) {
             $uniqueMeaning = $species[0]['taxon_meaning_id'];
         }
         if (count($species) > 1) {
             $uniqueMeaning = $species[0]['taxon_meaning_id'];
             foreach ($species as $item) {
                 if ($item['taxon_meaning_id'] != $uniqueMeaning) {
                     $uniqueMeaning = false;
                 }
             }
         }
         if ($uniqueMeaning) {
             // now we have the meaning_id, we need to fetch the actual species in the chosen common name
             $speciesCommon = data_entry_helper::get_population_data(array('table' => 'taxa_taxon_list', 'extraParams' => $readAuth + array('taxon_meaning_id' => $uniqueMeaning, 'language_iso' => iform_lang_iso_639_2($user->lang), 'view' => 'detail')));
             $r .= '<div class="ui-widget ui-widget-content ui-corner-all page-notice ui-helper-clearfix">';
             $nameString = ($species[0]['language_iso'] == 'lat' ? '<em>' : '') . $species[0]['taxon'] . ($species[0]['language_iso'] == 'lat' ? '</em>' : '');
             if (count($speciesCommon) >= 1) {
                 // use a common name if we have one
                 $nameString = $speciesCommon[0]['taxon'] . ' (' . $nameString . ')';
             }
             if (!empty($species[0]['description_in_list'])) {
                 $r .= '<div class="page-notice">' . lang::get('you are recording a', $nameString) . '</div>';
             }
             $taxa_taxon_list_id = $species[0]['id'];
             $images_path = data_entry_helper::$base_url . (isset(data_entry_helper::$indicia_upload_path) ? data_entry_helper::$indicia_upload_path : 'upload/');
             foreach ($species as $item) {
                 if (!empty($item['image_path'])) {
                     $r .= '<a class="fancybox left" href="' . $images_path . $item['image_path'] . '" style="margin: 0 1em 1em;">';
                     $r .= '<img width="100" src="' . $images_path . 'thumb-' . $item['image_path'] . '" />';
                     $r .= '</a>';
                 }
             }
             if (!empty($species[0]['description_in_list'])) {
                 $r .= '<p>' . $species[0]['description_in_list'] . "</p>";
             } else {
                 $r .= '<p>' . lang::get('you are recording a', $nameString) . '</p>';
             }
             $r .= "</div>\n";
         } else {
             $r .= "<p>The species not be identified uniquely from the URL parameters.</p>\n";
         }
     }
     // request automatic JS validation
     data_entry_helper::enable_validation('entry_form');
     $r .= "<div id=\"controls\">\n";
     if ($args['interface'] != 'one_page') {
         $r .= "<ul>\n";
         if (!$logged_in) {
             $r .= '  <li><a href="#about_you"><span>' . lang::get('about you') . "</span></a></li>\n";
         }
         if (!isset($taxa_taxon_list_id)) {
             $r .= '  <li><a href="#species"><span>' . lang::get('what did you see') . "</span></a></li>\n";
         }
         $r .= '  <li><a href="#place"><span>' . lang::get('where was it') . "</span></a></li>\n";
         $r .= '  <li><a href="#other"><span>' . lang::get('other information') . "</span></a></li>\n";
         $r .= "</ul>\n";
         data_entry_helper::enable_tabs(array('divId' => 'controls', 'style' => $args['interface']));
     }
     if ($user->uid == 0) {
         $r .= "<fieldset id=\"about_you\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('about you tab instructions') . "</p>";
         $r .= data_entry_helper::text_input(array('label' => lang::get('first name'), 'fieldname' => 'smpAttr:' . $args['first_name_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('surname'), 'fieldname' => 'smpAttr:' . $args['surname_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('email'), 'fieldname' => 'smpAttr:' . $args['email_attr_id'], 'class' => 'control-width-4'));
         $r .= data_entry_helper::text_input(array('label' => lang::get('phone number'), 'fieldname' => 'smpAttr:' . $args['phone_attr_id'], 'class' => 'control-width-4'));
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'first'));
         }
         $r .= "</fieldset>\n";
     }
     // the species tab is ommitted if the page is called with a taxon in the querystring parameters
     if (isset($taxa_taxon_list_id)) {
         $r .= "<input type=\"hidden\" name=\"occurrence:taxa_taxon_list_id\" value=\"{$taxa_taxon_list_id}\"/>\n";
     } else {
         $r .= "<fieldset id=\"species\">\n";
         $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('species tab instructions') . "</p>";
         $extraParams = $readAuth + array('taxon_list_id' => $args['list_id']);
         if ($args['preferred']) {
             $extraParams += array('preferred' => 't');
         }
         if ($args['restrict_species_to_users_lang']) {
             $extraParams += array('language_iso' => iform_lang_iso_639_2($user->lang));
         }
         $species_list_args = array('label' => lang::get('occurrence:taxa_taxon_list_id'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'view' => 'detail', 'parentField' => 'parent_id', 'extraParams' => $extraParams);
         if ($args['species_ctrl'] == 'tree_browser') {
             // change the node template to include images
             global $indicia_templates;
             $indicia_templates['tree_browser_node'] = '<div>' . '<img src="' . data_entry_helper::$base_url . '/upload/thumb-{image_path}" alt="Image of {caption}" width="80" /></div>' . '<span>{caption}</span>';
         }
         // Dynamically generate the species selection control required.
         $r .= call_user_func(array('data_entry_helper', $args['species_ctrl']), $species_list_args);
         if ($args['interface'] == 'wizard') {
             $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 ? 'first' : 'middle'));
         }
         $r .= "</fieldset>\n";
     }
     $r .= "<fieldset id=\"place\">\n";
     // Output all our hidden data here, because this tab is always present
     $r .= $auth['write'];
     if ($logged_in) {
         // If logged in, output some hidden data about the user
         $r .= iform_user_get_hidden_inputs($args);
     }
     // if the species being recorded is a fixed species defined in the URL, then output a hidden
     if (isset($taxa_taxon_list_id)) {
         $r .= "<input type=\"hidden\" name=\"occurrence:taxa_taxon_list_id'\" value=\"" . $taxa_taxon_list_id . "\" />\n";
     }
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"record_status\" value=\"" . $args['record_status'] . "\" />\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('place tab instructions') . "</p>";
     // Build the array of spatial reference systems into a format Indicia can use.
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::georeference_lookup(iform_map_get_georef_options($args, $auth['read']));
     $r .= data_entry_helper::sref_and_system(array('label' => lang::get('sample:entered_sref'), 'systems' => $systems));
     // retrieve options for the IndiciaMapPanel, and optionally options for OpenLayers.
     $options = iform_map_get_map_options($args, $readAuth);
     $options['tabDiv'] = 'place';
     $olOptions = iform_map_get_ol_options($args);
     $options['scroll_wheel_zoom'] = false;
     $r .= data_entry_helper::map_panel($options, $olOptions);
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => $user->id == 0 && isset($taxa_taxon_list_id) ? 'first' : 'middle'));
     }
     $r .= "</fieldset>\n";
     $r .= "<fieldset id=\"other\">\n";
     $r .= '<p class="page-notice ui-state-highlight ui-corner-all">' . lang::get('other tab instructions') . "</p>";
     $r .= data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date'));
     $r .= data_entry_helper::file_box(array('caption' => 'Upload your photos', 'readAuth' => $readAuth, 'resizeWidth' => 1024, 'resizeHeight' => 768, 'table' => 'occurrence_image', 'tabDiv' => 'other', 'runtimes' => array('html5', 'html4')));
     // Dynamically create a control for the abundance, unless overridden for this species
     if (isset($species) && count($species) > 0 && trim($args['abundance_overrides']) !== '') {
         $overrides = explode("\n", $args['abundance_overrides']);
         foreach ($overrides as $override) {
             $tokens = explode(':', $override);
             if ($tokens[0] == $species[0]['taxon']) {
                 // remove the default abundance attribute behaviour
                 $args['abundance_attr_id'] = '';
                 if (trim($tokens[1]) !== '') {
                     $attrIds = explode(',', $tokens[1]);
                     $attributes = data_entry_helper::getAttributes(array('id' => null, 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => "occAttr", 'extraParams' => $readAuth + array('query' => urlencode(json_encode(array('in' => array('id', $attrIds))))), 'survey_id' => $args['survey_id']));
                     foreach ($attributes as $attribute) {
                         $r .= data_entry_helper::outputAttribute($attribute, array('language' => iform_lang_iso_639_2($user->lang), 'booleanCtrl' => 'checkbox'));
                     }
                 }
             }
         }
     }
     if (!empty($args['abundance_attr_id'])) {
         $abundance_args = array('label' => lang::get('abundance'), 'fieldname' => 'occAttr:' . $args['abundance_attr_id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'extraParams' => $readAuth + array('termlist_id' => $args['abundance_termlist_id']), 'size' => 6, 'sep' => '<br/>');
         $r .= call_user_func(array('data_entry_helper', $args['abundance_ctrl']), $abundance_args);
     }
     $r .= data_entry_helper::textarea(array('label' => lang::get('sample:comment'), 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= '<div class="footer">' . data_entry_helper::checkbox(array('label' => lang::get('happy for contact'), 'labelClass' => 'auto', 'fieldname' => 'smpAttr:' . $args['contact_attr_id'])) . '</div>';
     if ($args['interface'] == 'wizard') {
         $r .= data_entry_helper::wizard_buttons(array('divId' => 'controls', 'page' => 'last'));
     } else {
         $r .= "<input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"Save\" />\n";
     }
     $r .= "</fieldset>\n";
     $r .= "</div>\n";
     $r .= "</form>";
     return $r;
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     $form = '<form action="#" method="POST" id="entry_form">';
     if ($_POST) {
         $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
         self::subscribe($args, $auth);
     } else {
         // don't bother with write auth for initial form load, as read auth is cached and faster
         $auth = array('read' => data_entry_helper::get_read_auth($args['website_id'], $args['password']));
     }
     if (!empty($_GET['id'])) {
         data_entry_helper::load_existing_record($auth['read'], 'species_alert', $_GET['id']);
         // enforce permissions
         if (data_entry_helper::$entity_to_load['species_alert:user_id'] != hostsite_get_user_field('indicia_user_id')) {
             return lang::get('You cannot modify a species alert subscription created by someone else');
         }
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:id', 'default' => $_GET['id']));
     }
     // if not logged in, then ask for details to register against
     global $user;
     if (!hostsite_get_user_field('id') || !isset($user) || empty($user->mail) || !hostsite_get_user_field('last_name')) {
         $form .= "<fieldset><legend>" . lang::get('Your details') . ":</legend>\n";
         $default = empty($_POST['first_name']) ? hostsite_get_user_field('first_name', '') : $_POST['first_name'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('First name'), 'fieldname' => 'first_name', 'validation' => array('required'), 'default' => $default, 'class' => 'control-width-4'));
         $default = empty($_POST['surname']) ? hostsite_get_user_field('last_name', '') : $_POST['surname'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('Last name'), 'fieldname' => 'surname', 'validation' => array('required'), 'default' => $default, 'class' => 'control-width-4'));
         $default = empty($_POST['email']) ? empty($user->mail) ? '' : $user->mail : $_POST['email'];
         $form .= data_entry_helper::text_input(array('label' => lang::get('Email'), 'fieldname' => 'email', 'validation' => array('required', 'email'), 'default' => $default, 'class' => 'control-width-4'));
         $form .= "</fieldset>\n";
     } else {
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'first_name', 'default' => hostsite_get_user_field('first_name')));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'surname', 'default' => hostsite_get_user_field('last_name')));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'email', 'default' => $user->mail));
         $form .= data_entry_helper::hidden_text(array('fieldname' => 'user_id', 'default' => hostsite_get_user_field('indicia_user_id')));
     }
     $form .= "<fieldset><legend>" . lang::get('Alert criteria') . ":</legend>\n";
     // Output the species selection control
     // Default after saving with a validation failure can be pulled direct from the post, but
     // when reloading we don't need a default taxa taxon list ID since we already know the meaning
     // ID or external key.
     $default = empty($_POST['taxa_taxon_list_id']) ? '' : $_POST['taxa_taxon_list_id'];
     if (empty($_POST['taxa_taxon_list_id:taxon'])) {
         $defaultCaption = empty(data_entry_helper::$entity_to_load['species_alert:preferred_taxon']) ? '' : data_entry_helper::$entity_to_load['species_alert:preferred_taxon'];
     } else {
         $defaultCaption = $_POST['taxa_taxon_list_id:taxon'];
     }
     $form .= data_entry_helper::species_autocomplete(array('label' => lang::get('Alert species'), 'helpText' => lang::get('Select the species you are interested in receiving alerts in ' . 'relation to if you want to receive alerts on a single species.'), 'fieldname' => 'taxa_taxon_list_id', 'cacheLookup' => true, 'extraParams' => $auth['read'] + array('taxon_list_id' => $args['list_id']), 'class' => 'control-width-4', 'default' => $default, 'defaultCaption' => $defaultCaption));
     if (empty($default)) {
         // Unless we've searched for the species name then posted (and failed), then the
         // default will be empty. We might therefore be reloading existing data which has
         // a meaning ID or external key.
         if (!empty(data_entry_helper::$entity_to_load['species_alert:external_key'])) {
             $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:external_key', 'default' => data_entry_helper::$entity_to_load['species_alert:external_key']));
         } elseif (!empty(data_entry_helper::$entity_to_load['species_alert:taxon_meaning_id'])) {
             $form .= data_entry_helper::hidden_text(array('fieldname' => 'species_alert:taxon_meaning_id', 'default' => data_entry_helper::$entity_to_load['species_alert:taxon_meaning_id']));
         }
     }
     if (!empty($args['full_lists'])) {
         $form .= data_entry_helper::select(array('label' => lang::get('Select full species lists'), 'helpText' => lang::get('If you want to restrict the alerts to records of any ' . 'species within a species list, then select the list here.'), 'fieldname' => 'species_alert:taxon_list_id', 'blankText' => lang::get('<Select a species list>'), 'table' => 'taxon_list', 'valueField' => 'id', 'captionField' => 'title', 'extraParams' => $auth['read'] + array('id' => $args['full_lists'], 'orderby' => 'title'), 'class' => 'control-width-4'));
     }
     $form .= data_entry_helper::location_select(array('label' => lang::get('Select location'), 'helpText' => lang::get('If you want to restrict the alerts to records within a certain boundary, select it here.'), 'fieldname' => 'species_alert:location_id', 'id' => 'imp-location', 'blankText' => lang::get('<Select boundary>'), 'extraParams' => $auth['read'] + array('location_type_id' => $args['location_type_id'], 'orderby' => 'name'), 'class' => 'control-width-4'));
     $form .= data_entry_helper::checkbox(array('label' => lang::get('Alert on initial entry'), 'helpText' => lang::get('Tick this box if you want to receive a notification when the record is first input into the system.'), 'fieldname' => 'species_alert:alert_on_entry'));
     $form .= data_entry_helper::checkbox(array('label' => lang::get('Alert on verification as correct'), 'helpText' => lang::get('Tick this box if you want to receive a notification when the record has been verified as correct.'), 'fieldname' => 'species_alert:alert_on_verify'));
     $form .= "</fieldset>\n";
     $form .= '<input type="Submit" value="Subscribe" />';
     $form .= '</form>';
     data_entry_helper::enable_validation('entry_form');
     iform_load_helpers(array('map_helper'));
     $mapOptions = iform_map_get_map_options($args, $auth['read']);
     $map = map_helper::map_panel($mapOptions);
     global $indicia_templates;
     return str_replace(array('{col-1}', '{col-2}'), array($form, $map), $indicia_templates['two-col-50']);
 }
 private static function get_control_identifier($auth, $args, $tabalias, $options)
 {
     $fieldPrefix = !empty($options['fieldprefix']) ? $options['fieldprefix'] : '';
     $r = '';
     $r .= '<h3 id="' . $fieldPrefix . 'header" class="idn:accordion:header"><a href="#">' . $options['identifierName'] . '</a></h2>';
     $r .= '<div id="' . $fieldPrefix . 'panel" class="idn:accordion:panel">';
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:identifier_type_id" value="' . $options['identifierTypeId'] . '" />' . "\n";
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:coded_value" id="' . $fieldPrefix . 'identifier:coded_value" class="identifier_coded_value" value="" />' . "\n";
     $val = isset(data_entry_helper::$entity_to_load[$fieldPrefix . 'identifier:id']) ? data_entry_helper::$entity_to_load[$fieldPrefix . 'identifier:id'] : '0';
     $r .= '<input type="hidden" name="' . $fieldPrefix . 'identifier:id" id="' . $fieldPrefix . 'identifier:id" class="identifier_id" value="' . $val . '" />' . "\n";
     if (isset(data_entry_helper::$entity_to_load[$fieldPrefix . 'identifiers_subject_observation:id'])) {
         $r .= '<input type="hidden" id="' . $fieldPrefix . 'identifiers_subject_observation:id" name="' . $fieldPrefix . 'identifiers_subject_observation:id" ' . 'value="' . data_entry_helper::$entity_to_load[$fieldPrefix . 'identifiers_subject_observation:id'] . '" />' . "\n";
     }
     // checkbox - (now hidden by CSS, probably should refactor to hidden input?)
     $r .= data_entry_helper::checkbox(array_merge(array('label' => '', 'fieldname' => $fieldPrefix . 'identifier:checkbox', 'class' => 'identifier_checkbox identifierRequired noDuplicateIdentifiers'), $options));
     // loop through the requested attributes and output an appropriate control
     $classes = $options['class'];
     foreach ($options['attrList'] as $attribute) {
         // find the definition of this attribute
         $found = false;
         if ($attribute['attrType'] === 'idn') {
             foreach ($options['idnAttributeTypes'] as $attrType) {
                 if ($attrType['id'] === $attribute['typeId']) {
                     $found = true;
                     break;
                 }
             }
         } else {
             if ($attribute['attrType'] === 'iso') {
                 foreach ($options['isoAttributeTypes'] as $attrType) {
                     if ($attrType['id'] === $attribute['typeId']) {
                         $found = true;
                         break;
                     }
                 }
             }
         }
         if (!$found) {
             throw new exception(lang::get('Unknown ' . $attribute['attrType'] . ' attribute type id [' . $attribute['typeId'] . '] specified for ' . $options['identifierName'] . ' in Identifier Attributes array.'));
         }
         // setup any locking
         if (!empty($attribute['lockable']) && $attribute['lockable'] === true) {
             $options['lockable'] = $options['identifiers_lockable'];
         }
         // setup any data filters
         if ($attribute['attrType'] === 'idn' && $options['baseColourId'] == $attribute['typeId']) {
             if (!empty($args['base_colours'])) {
                 // filter the colours available
                 $query = array('in' => array('id', $args['base_colours']));
             }
             $attr_name = 'base-colour';
         } elseif ($attribute['attrType'] === 'idn' && $options['textColourId'] == $attribute['typeId']) {
             if (!empty($args['text_colours'])) {
                 // filter the colours available
                 $query = array('in' => array('id', $args['text_colours']));
             }
             $attr_name = 'text-colour';
         } elseif ($attribute['attrType'] === 'idn' && $options['positionId'] == $attribute['typeId']) {
             $attr_name = 'position';
             if (count($args['position']) > 0) {
                 // filter the identifier position available
                 $query = array('in' => array('id', $args['position']));
             }
         } elseif ($attribute['attrType'] === 'idn' && $options['sequenceId'] == $attribute['typeId']) {
             $attr_name = 'sequence';
             $options['maxlength'] = $options['seq_maxlength'] ? $options['seq_maxlength'] : '';
             if ($options['seq_format_class']) {
                 $options['class'] = empty($options['class']) ? $options['seq_format_class'] : (strstr($options['class'], $options['seq_format_class']) ? $options['class'] : $options['class'] . ' ' . $options['seq_format_class']);
             }
         } elseif ($attribute['attrType'] === 'iso' && $options['conditionsId'] == $attribute['typeId']) {
             // filter the identifier conditions available
             if ($options['identifierTypeId'] == $args['neck_collar_type'] && !empty($args['neck_collar_conditions'])) {
                 $query = array('in' => array('id', $args['neck_collar_conditions']));
             } elseif ($options['identifierTypeId'] == $args['enscribed_colour_ring_type'] && !empty($args['coloured_ring_conditions'])) {
                 $query = array('in' => array('id', $args['coloured_ring_conditions']));
             } elseif ($options['identifierTypeId'] == $args['metal_ring_type'] && !empty($args['metal_ring_conditions'])) {
                 $query = array('in' => array('id', $args['metal_ring_conditions']));
             }
             $attr_name = 'conditions';
         }
         // add classes as identifiers
         $options['class'] = empty($options['class']) ? $options['classprefix'] . $attr_name : (strstr($options['class'], $options['classprefix'] . $attr_name) ? $options['class'] : $options['class'] . ' ' . $options['classprefix'] . $attr_name);
         $options['class'] = $options['class'] . ' idn-' . $attr_name;
         if ($attribute['attrType'] === 'idn' && ($options['baseColourId'] == $attribute['typeId'] || $options['textColourId'] == $attribute['typeId'])) {
             $options['class'] = strstr($options['class'], 'select_colour') ? $options['class'] : $options['class'] . ' select_colour';
             $options['class'] = strstr($options['class'], 'textAndBaseMustDiffer') ? $options['class'] : $options['class'] . ' textAndBaseMustDiffer';
         }
         if ($attribute['attrType'] === 'idn' && $options['sequenceId'] == $attribute['typeId']) {
             $options['class'] = strstr($options['class'], 'identifier_sequence') ? $options['class'] : $options['class'] . ' identifier_sequence';
         }
         if (!empty($attribute['hidden']) && $attribute['hidden'] === true) {
             $dataType = 'H';
             // hidden
             if (!empty($attribute['hiddenValue'])) {
                 $dataDefault = $attribute['hiddenValue'];
             } else {
                 $dataDefault = '';
             }
         } else {
             $dataType = $attrType['data_type'];
         }
         // output an appropriate control for the attribute data type
         switch ($dataType) {
             case 'D':
             case 'V':
                 $r .= data_entry_helper::date_picker(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
                 break;
             case 'L':
                 $filter = array('termlist_id' => $attrType['termlist_id']);
                 if (!empty($query)) {
                     $filter += array('query' => json_encode($query));
                 }
                 $extraParams = array_merge($filter, $auth['read']);
                 if ($attribute['attrType'] === 'iso' && $options['conditionsId'] == $attribute['typeId']) {
                     $fieldname = $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'];
                     $default = array();
                     // if this attribute exists on DB, we need to write a hidden with id appended to fieldname and set defaults for checkboxes
                     if (is_array(data_entry_helper::$entity_to_load)) {
                         $stored_keys = preg_grep('/^' . $fieldname . ':[0-9]+$/', array_keys(data_entry_helper::$entity_to_load));
                         foreach ($stored_keys as $stored_key) {
                             $r .= '<input type="hidden" name="' . $stored_key . '" value="" />';
                             $default[] = array('fieldname' => $stored_key, 'default' => data_entry_helper::$entity_to_load[$stored_key]);
                             unset(data_entry_helper::$entity_to_load[$stored_key]);
                         }
                     }
                     $r .= data_entry_helper::checkbox_group(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldname, 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'default' => $default, 'extraParams' => $extraParams), $options));
                 } else {
                     $r .= data_entry_helper::select(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'], 'table' => 'termlists_term', 'captionField' => 'term', 'valueField' => 'id', 'blankText' => '<Please select>', 'extraParams' => $extraParams), $options));
                 }
                 break;
             case 'B':
                 $r .= data_entry_helper::checkbox(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
                 break;
             case 'H':
                 // Any multi-value attributes shown as hidden will be single-valued
                 // so transform the array to a scalar
                 $fieldname = $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id'];
                 if (!empty(data_entry_helper::$entity_to_load[$fieldname]) && is_array(data_entry_helper::$entity_to_load[$fieldname])) {
                     data_entry_helper::$entity_to_load[$fieldname] = data_entry_helper::$entity_to_load[$fieldname][0];
                 }
                 $r .= data_entry_helper::hidden_text(array_merge(array('fieldname' => $fieldname, 'default' => $dataDefault), $options));
                 break;
             default:
                 $r .= data_entry_helper::text_input(array_merge(array('label' => lang::get($attrType['caption']), 'fieldname' => $fieldPrefix . $attribute['attrType'] . 'Attr:' . $attrType['id']), $options));
         }
         $options['class'] = $classes;
         if (isset($options['maxlength'])) {
             unset($options['maxlength']);
         }
         if (isset($options['lockable'])) {
             unset($options['lockable']);
         }
     }
     $r .= '</div>';
     return $r;
 }
echo data_entry_helper::hidden_text(array('fieldname' => 'location_medium:id', 'default' => $id));
echo data_entry_helper::hidden_text(array('fieldname' => 'location_medium:location_id', 'default' => html::initial_value($values, 'location_medium:location_id')));
?>
<legend>Media file details</legend>
<?php 
$mediaTypeId = html::initial_value($values, 'location_medium:media_type_id');
$mediaType = $mediaTypeId ? $other_data['media_type_terms'][$mediaTypeId] : 'Image:Local';
if ($mediaType === 'Image:Local') {
    echo '<label>Image:</label>';
    echo html::sized_image(html::initial_value($values, 'occurrence_medium:path')) . '</br>';
    echo data_entry_helper::hidden_text(array('fieldname' => 'location_medium:path', 'default' => html::initial_value($values, 'location_medium:path')));
    echo data_entry_helper::image_upload(array('label' => 'Upload image file', 'fieldname' => 'image_upload', 'default' => html::initial_value($values, 'location_medium:path')));
} else {
    echo data_entry_helper::text_input(array('label' => 'Path or URL', 'fieldname' => 'location_medium:path', 'default' => html::initial_value($values, 'location_medium:path'), 'class' => 'control-width-5'));
}
echo data_entry_helper::text_input(array('label' => 'Caption', 'fieldname' => 'location_medium:caption', 'default' => html::initial_value($values, 'location_medium:caption'), 'class' => 'control-width-5'));
if ($mediaTypeId && $mediaType !== 'Image:Local') {
    echo data_entry_helper::select(array('label' => 'Media type', 'fieldname' => 'location_medium:media_type_id', 'default' => $mediaTypeId, 'lookupValues' => $other_data['media_type_terms'], 'blankText' => '<Please select>', 'class' => 'control-width-5'));
}
?>

</fieldset>
<?php 
echo html::form_buttons($id != null, false, false);
data_entry_helper::$dumped_resources[] = 'jquery';
data_entry_helper::$dumped_resources[] = 'jquery_ui';
data_entry_helper::$dumped_resources[] = 'fancybox';
data_entry_helper::enable_validation('location-medium-edit');
data_entry_helper::link_default_stylesheet();
echo data_entry_helper::dump_javascript();
?>
 protected static function get_control_habitatblocks($auth, $args, $tabAlias, $options)
 {
     // build a template for the data entry controls for each habitat
     $template = '<legend title="' . lang::get('Each habitat is numbered. Make sure the description and quantitative data is ' . 'entered in the correct columns and that you number your sketch or plan in the same way. Each written description ' . 'should tally with the information entered on the columns and diagrams on the next page.') . '">Habitat habitatIdx</legend>';
     $template .= data_entry_helper::textarea(array('fieldname' => 'sample:comment:habitatIdx', 'label' => lang::get('DESCRIPTION (physical + community'), 'tooltip' => lang::get('This should be a brief \\\'sketch in words\\\' to describe the main characteristics ' . 'of each habitat and the dominant plant or animal communities. An example would be: "Gently shelving ' . 'seabed consisting of large boulders up to 1m x 1m with patches of coarse sand collecting between them. Kelp ' . 'forest on boulders with pink encrusting algae and red seaweeds beneath".')));
     $biotopeCode = self::$habitatAttrsByCaption['biotope code'];
     $seabedType = self::$habitatAttrsByCaption['seabed type'];
     $seabedTypeOther = self::$habitatAttrsByCaption['other seabed type'];
     $communities = self::$habitatAttrsByCaption['communities'];
     $animalTurf = self::$habitatAttrsByCaption['animal turf'];
     $animalBed = self::$habitatAttrsByCaption['animal bed'];
     $sedimentTypes = self::$habitatAttrsByCaption['sediment types'];
     if (user_access('biotope codes')) {
         $template .= data_entry_helper::text_input(array('fieldname' => "smpAttr:{$biotopeCode['attributeId']}::habitatIdx", 'label' => lang::get('Biotope code')));
     }
     $template .= data_entry_helper::checkbox_group(array('fieldname' => "smpAttr:{$seabedType['attributeId']}::habitatIdx", 'label' => lang::get('Seabed type'), 'table' => 'termlists_term', 'valueField' => 'id', 'captionField' => 'term', 'extraParams' => $auth['read'] + array('termlist_id' => $seabedType['termlist_id'], 'view' => 'cache'), 'afterControl' => data_entry_helper::text_input(array('label' => lang::get('other'), 'labelClass' => 'auto', 'fieldname' => "smpAttr:{$seabedTypeOther['attributeId']}::habitatIdx")), 'labelClass' => 'auto', 'tooltip' => lang::get('Each habitat should only contain a limited number of physical types. Rock and boulders or ' . 'cobble and pebbles are fine but avoid identifying habitats containing very different physical characteristics, ' . 'for instance rock and sand or wreckage and mud.')));
     $template .= data_entry_helper::checkbox_group(array('fieldname' => "smpAttr:{$communities['attributeId']}::habitatIdx", 'label' => lang::get('Communities'), 'table' => 'termlists_term', 'valueField' => 'id', 'captionField' => 'term', 'extraParams' => $auth['read'] + array('label' => lang::get('other'), 'termlist_id' => $communities['termlist_id'], 'view' => 'cache', 'orderby' => 'sort_order'), 'labelClass' => 'auto', 'tooltip' => lang::get('Each habitat described should rarely have more than one dominant community. For instance ' . 'if the main cover is kelp forest with pink encrusting algae and anemones on the rocks beneath only tick the ' . 'kelp forest box because this dominates.')));
     $template .= '<div style="display: inline-block;">';
     $template .= data_entry_helper::text_input(array('label' => lang::get('animal turf'), 'fieldname' => "smpAttr:{$animalTurf['attributeId']}::habitatIdx", 'labelClass' => 'auto', 'tooltip' => lang::get('Write the main component in the box. This may, for example, be hydroids, jewel anemones or ' . 'bryozoans but will not be mobile animals.')));
     $template .= '</div>&nbsp; <div style="display: inline-block;">';
     $template .= data_entry_helper::text_input(array('label' => lang::get('animal bed'), 'fieldname' => "smpAttr:{$animalBed['attributeId']}::habitatIdx", 'labelClass' => 'auto', 'tooltip' => lang::get('Animal beds are where large numbers of a particular animal changes the composition of the ' . 'seabed. Examples are the brittlestar beds, mussel beds and gravel sea cucumber beds.')));
     $template .= '</div>';
     $template .= data_entry_helper::checkbox_group(array('fieldname' => "smpAttr:{$sedimentTypes['attributeId']}::habitatIdx", 'table' => 'termlists_term', 'valueField' => 'id', 'captionField' => 'term', 'extraParams' => $auth['read'] + array('label' => lang::get('other'), 'termlist_id' => $sedimentTypes['termlist_id'], 'view' => 'cache')));
     // create the control output
     // add the template, wrapped in a hidden div. JS will be used to clone it as many times as is required.
     $r = "<div style=\"display: none;\"><fieldset id=\"habitat-block-template\">\n{$template}\n</fieldset></div>\n";
     $r .= '<input type="hidden" id="habitat-count" name="habitat-count" />';
     $r .= "<div id=\"habitat-blocks\"></div>\n";
     return $r;
 }
 private static function get_site_tab($auth, $args, $settings)
 {
     $r = '<div id="site-details" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: 54%">';
     $r .= '<fieldset><legend>' . lang::get('Site Details') . '</legend>';
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $typeTerms = array();
     if (!empty($args['main_type_term_1'])) {
         $typeTerms[] = $args['main_type_term_1'];
     }
     if (!empty($args['main_type_term_2'])) {
         $typeTerms[] = $args['main_type_term_2'];
     }
     if (!empty($args['main_type_term_3'])) {
         $typeTerms[] = $args['main_type_term_3'];
     }
     $typeTermIDs = helper_base::get_termlist_terms($auth, 'indicia:location_types', $typeTerms);
     $lookUpValues = array('' => '<' . lang::get('please select') . '>');
     foreach ($typeTermIDs as $termDetails) {
         $lookUpValues[$termDetails['id']] = $termDetails['term'];
     }
     // if location is predefined, can not change unless a 'managerPermission'
     $canEditType = !$settings['locationId'] || isset($args['managerPermission']) && $args['managerPermission'] != '' && function_exists('user_access') && user_access($args['managerPermission']);
     if ($canEditType) {
         $r .= data_entry_helper::select(array('label' => lang::get('Site Type'), 'id' => 'location_type_id', 'fieldname' => 'location:location_type_id', 'lookupValues' => $lookUpValues));
         data_entry_helper::$javascript .= "\$('#location_type_id').change(function(){\r\n  switch(\$(this).val()){\n";
         for ($i = 1; $i < 4; $i++) {
             if (!empty($args['main_type_term_' . $i])) {
                 $type = helper_base::get_termlist_terms($auth, 'indicia:location_types', array($args['main_type_term_' . $i]));
                 data_entry_helper::$javascript .= "    case \"" . $type[0]['id'] . "\":\n";
                 if (!isset($args['can_change_section_number_' . $i]) || !$args['can_change_section_number_' . $i]) {
                     if ($settings['locationId']) {
                         // not saved yet, so no sections yet created, hence no need to worry about existing value. make number attribute readonly. set value. min value will be 1.
                         data_entry_helper::$javascript .= "      var minValue = \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').attr('min');\r\n      if(minValue > " . $args['section_number_' . $i] . ") { // existing value is greater than one we want to set\r\n        alert('You are reducing the number of sections below that already existing. Please use the Remove Section button on the Your Route tab to reduce the number of sections to " . $args['section_number_' . $i] . " before changing the Site type');\r\n        return false;\r\n      }\r\n      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').val(" . $args['section_number_' . $i] . ").attr('readonly','readonly').css('color','graytext');\n";
                     } else {
                         // not saved yet, so no sections yet created, hence no need to worry about existing value. make number attribute readonly. set value. min value will be 1.
                         data_entry_helper::$javascript .= "      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').val(" . $args['section_number_' . $i] . ").attr('readonly','readonly').css('color','graytext');\n";
                     }
                 } else {
                     // user modifiable number of sections. value of attribute is left alone: don't have to worry att his point whether existing data.
                     data_entry_helper::$javascript .= "      \$('[name=" . str_replace(':', '\\\\:', $settings['numSectionsAttr']) . "]').removeAttr('readonly').css('color','');\n";
                 }
                 data_entry_helper::$javascript .= "      break;\n";
             }
         }
         data_entry_helper::$javascript .= "    default: break;\r\n  };\r\n  return true;\r\n});\n";
     }
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" id="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Site Name'), 'class' => 'control-width-4 required', 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if (!$settings['canEditBody']) {
         $r .= '<p>' . lang::get('This site cannot be edited because there are walks recorded on it. Please contact the site administrator if you think there are details which need changing.') . '</p>';
     } else {
         if (count($settings['walks']) > 0) {
             // can edit it
             $r .= '<p>' . lang::get('This site has walks recorded on it. Please do not change the site details without considering the impact on the existing data.') . '</p>';
         }
     }
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     if (isset(data_entry_helper::$entity_to_load['location:centroid_sref_system']) && in_array(data_entry_helper::$entity_to_load['location:centroid_sref_system'], array('osgb', 'osie'))) {
         data_entry_helper::$entity_to_load['location:centroid_sref_system'] = strtoupper(data_entry_helper::$entity_to_load['location:centroid_sref_system']);
     }
     $r .= data_entry_helper::sref_and_system(array('fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Grid Ref.', 'systems' => $systems, 'class' => 'required', 'helpText' => lang::get('Click on the map to set the central grid reference.'), 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if ($settings['locationId'] && data_entry_helper::$entity_to_load['location:code'] != '' && data_entry_helper::$entity_to_load['location:code'] != null) {
         $r .= data_entry_helper::text_input(array('fieldname' => 'location:code', 'label' => lang::get('Site Code'), 'class' => 'control-width-4', 'disabled' => ' readonly="readonly" '));
     } else {
         $r .= "<p>" . lang::get('The Site Code will be allocated by the Administrator.') . "</p>";
     }
     // setup the map options
     $options = iform_map_get_map_options($args, $auth['read']);
     // find the form blocks that need to go below the map.
     $bottom = '';
     $bottomBlocks = explode("\n", isset($args['bottom_blocks']) ? $args['bottom_blocks'] : '');
     foreach ($bottomBlocks as $block) {
         $bottom .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read'], 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '), $block);
     }
     // other blocks to go at the top, next to the map
     if (isset($args['site_help']) && $args['site_help'] != '') {
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . t($args['site_help']) . '</p>';
     }
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']));
     $r .= '</fieldset>';
     $r .= "</div>";
     // left
     $r .= '<div class="right" style="width: 44%">';
     if (!$settings['locationId']) {
         $help = t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box on the left.');
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
         $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']));
     }
     if (isset($args['maxPrecision']) && $args['maxPrecision'] != '') {
         $options['clickedSrefPrecisionMax'] = $args['maxPrecision'];
     }
     if (isset($args['minPrecision']) && $args['minPrecision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['minPrecision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     $options['clickForSpatialRef'] = $settings['canEditBody'];
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= '</div></div>';
     // right
     if (!empty($bottom)) {
         $r .= $bottom;
     }
     if ($args['branch_assignment_permission'] != '') {
         if ($settings['canAllocBranch'] || $settings['locationId']) {
             $r .= self::get_branch_assignment_control($auth['read'], $settings['branchCmsUserAttr'], $args, $settings);
         }
     }
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $r .= self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
         } else {
             if (!$settings['locationId']) {
                 // for a new record, we need to link the current user to the location if they are not admin.
                 global $user;
                 $r .= '<input type="hidden" name="locAttr:' . self::$cmsUserAttrId . '" value="' . $user->uid . '">';
             }
         }
     }
     if ($settings['canEditBody']) {
         $r .= '<button type="submit" class="indicia-button right">' . lang::get('Save') . '</button>';
     }
     if ($settings['canEditBody'] && $settings['locationId']) {
         $r .= '<button type="button" class="indicia-button right" id="delete-transect">' . lang::get('Delete') . '</button>';
     }
     $r .= '</form>';
     $r .= '</div>';
     // site-details
     // This must go after the map panel, so it has created its toolbar
     data_entry_helper::$onload_javascript .= "\$('#current-section').change(selectSection);\n";
     if ($settings['canEditBody'] && $settings['locationId']) {
         $walkIDs = array();
         foreach ($settings['walks'] as $walk) {
             $walkIDs[] = $walk['id'];
         }
         $sectionIDs = array();
         foreach ($settings['sections'] as $code => $section) {
             $sectionIDs[] = $section['id'];
         }
         data_entry_helper::$javascript .= "\r\ndeleteSurvey = function(){\r\n  if(confirm(\"" . (count($settings['walks']) > 0 ? count($settings['walks']) . ' ' . lang::get('walks will also be deleted when you delete this location.') . ' ' : '') . lang::get('Are you sure you wish to delete this location?') . "\")){\r\n    deleteWalks([" . implode(',', $walkIDs) . "]);\r\n    deleteSections([" . implode(',', $sectionIDs) . "]);\r\n    \$('#delete-transect').html('Deleting Site');\r\n    deleteLocation(" . $settings['locationId'] . ");\r\n    \$('#delete-transect').html('Done');\r\n    window.location='" . url($args['sites_list_path']) . "';\r\n  };\r\n};\r\n\$('#delete-transect').click(deleteSurvey);\r\n";
     }
     return $r;
 }
Beispiel #22
0
 public static function get_sample_form($args, $node, $response)
 {
     global $user;
     iform_load_helpers(array('map_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // either looking at existing, creating a new one, or an error occurred: no successful posts...
     // first check some conditions are met
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Timed Count'));
     if (count($sampleMethods) == 0) {
         return 'The sample method "Timed Count" must be defined in the termlist in order to use this form.';
     }
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     if ($sampleId && !isset(data_entry_helper::$validation_errors)) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
     }
     $r = '<form method="post" id="sample">' . $auth['write'];
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get location details.
     $r .= '<input type="hidden" name="read_nonce" value="' . $auth['read']['nonce'] . '"/>';
     $r .= '<input type="hidden" name="read_auth_token" value="' . $auth['read']['auth_token'] . '"/>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
     }
     // pass a param that sets the next page to display
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\"/>\n<input type=\"hidden\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\"/>\n<input type=\"hidden\" name=\"page\" value=\"site\"/>";
     $attributes = data_entry_helper::getAttributes(array('id' => $sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
     $r .= get_user_profile_hidden_inputs($attributes, $args, '', $auth['read']) . data_entry_helper::text_input(array('label' => lang::get('Site Name'), 'fieldname' => 'sample:location_name', 'validation' => array('required')));
     $help = lang::get('The Year field is read-only, and is calculated automatically from the date(s) of the Counts.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     if ($sampleId == null) {
         if (isset($_GET['date'])) {
             data_entry_helper::$entity_to_load['C1:sample:date'] = $_GET['date'];
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date of first count'), 'fieldname' => 'C1:sample:date', 'validation' => array('required', 'date')));
         data_entry_helper::$javascript .= "jQuery('#C1\\\\:sample\\\\:date').change(function(){\n  jQuery('#sample\\\\:date').val(jQuery(this).val() == '' ? '' : jQuery(this).datepicker('getDate').getFullYear());\n});\nif(jQuery('#C1\\\\:sample\\\\:date').val() != '') jQuery('#sample\\\\:date').val(jQuery('#C1\\\\:sample\\\\:date').datepicker('getDate').getFullYear());\n";
     }
     if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
         // Date has 4 digit year first (ISO style) - only interested in Year.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('Y');
     }
     unset(data_entry_helper::$default_validation_rules['sample:date']);
     $r .= data_entry_helper::text_input(array('label' => lang::get('Year'), 'fieldname' => 'sample:date', 'readonly' => ' readonly="readonly" '));
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $r .= get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions);
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $help = lang::get('Now draw the flight area for the timed count on the map below. The Grid Reference is filled in automatically when the site is drawn.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     $options = iform_map_get_map_options($args, $auth['read']);
     $options['allowPolygonRecording'] = true;
     $options['clickForSpatialRef'] = false;
     if (isset($args['precision']) && $args['precision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['precision'];
         $options['clickedSrefPrecisionMax'] = $args['precision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     if (!in_array('drawPolygon', $options['standardControls'])) {
         $options['standardControls'][] = 'drawPolygon';
     }
     if (!in_array('modifyFeature', $options['standardControls'])) {
         $options['standardControls'][] = 'modifyFeature';
     }
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= "<label for=\"imp-sref\">" . lang::get('Grid Reference') . ":</label> <input type=\"text\" id=\"imp-sref\" name=\"sample:entered_sref\" value=\"" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "\" readonly=\"readonly\" class=\"required\" />";
     $r .= "<input type=\"hidden\" id=\"imp-geom\" name=\"sample:geom\" value=\"" . data_entry_helper::$entity_to_load['sample:geom'] . "\" />";
     if (count($systems) == 1) {
         // Hidden field for the system
         $keys = array_keys($systems);
         $r .= "<input type=\"hidden\" id=\"imp-sref-system\" name=\"sample:entered_sref_system\" value=\"" . $keys[0] . "\" />\n";
     } else {
         $r .= self::sref_system_select(array('fieldname' => 'sample:entered_sref_system'));
     }
     $r .= '<br />' . data_entry_helper::georeference_lookup(iform_map_get_georef_options($args, $auth['read']));
     $r .= data_entry_helper::map_panel($options, $olOptions);
     // switch off the sref functionality.
     data_entry_helper::$javascript .= "mapInitialisationHooks.push(function(div){\n  \$('#imp-sref').unbind('change');\n  // Programatic activation does not rippleout, so deactivate Nav first, which is actibve by default.\n  for(var i=0; i<div.map.controls.length; i++)\n    if(div.map.controls[i].CLASS_NAME == \"OpenLayers.Control.Navigation\")\n      div.map.controls[i].deactivate();\n  activeCtrl = false;\n  for(var i=0; i<div.map.controls.length; i++){\n    if(div.map.controls[i].CLASS_NAME == \"" . (isset(data_entry_helper::$entity_to_load['sample:id']) ? "OpenLayers.Control.ModifyFeature" : "OpenLayers.Control.DrawFeature") . "\"){\n      div.map.controls[i].activate();\n      activeCtrl = div.map.controls[i];\n      break;\n    }}\n" . (isset(data_entry_helper::$entity_to_load['sample:id']) ? "  if(activeCtrl && div.map.editLayer.features.length>0) activeCtrl.selectFeature(div.map.editLayer.features[0]);\n" : "") . "});\n";
     $r .= data_entry_helper::textarea(array('label' => 'Comment', 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= '<input type="submit" value="' . lang::get('Next') . '" />';
     $r .= '<a href="' . $args['summary_page'] . '"><button type="button" class="ui-state-default ui-corner-all" />' . lang::get('Cancel') . '</button></a>';
     // allow deletes if sample id is present: i.e. existing sample.
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<button id="delete-button" type="button" class="ui-state-default ui-corner-all" />' . lang::get('Delete') . '</button>';
         // note we only require bare minimum in order to flag a sample as deleted.
         $r .= '</form><form method="post" id="delete-form" style="display: none;">';
         $r .= $auth['write'];
         $r .= '<input type="hidden" name="page" value="delete"/>';
         $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
         $r .= '<input type="hidden" name="sample:deleted" value="t"/>';
         data_entry_helper::$javascript .= "jQuery('#delete-button').click(function(){\n  if(confirm(\"" . lang::get('Are you sure you want to delete this timed count?') . "\"))\n    jQuery('#delete-form').submit();\n});\n";
     }
     $r .= '</form>';
     data_entry_helper::enable_validation('sample');
     return $r;
 }
 private static function get_site_tab($auth, $args, $settings)
 {
     $r = '<div id="site-details" class="ui-helper-clearfix">';
     $r .= '<form method="post" id="input-form">';
     $r .= $auth['write'];
     $r .= '<div id="cols" class="ui-helper-clearfix"><div class="left" style="width: 54%">';
     $r .= '<fieldset><legend>' . lang::get('Transect Details') . '</legend>';
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"survey_id\" value=\"" . $args['survey_id'] . "\" />\n";
     $r .= "<input type=\"hidden\" name=\"location:location_type_id\" value=\"" . $settings['locationTypes'][0]['id'] . "\" />\n";
     if ($settings['locationId']) {
         $r .= '<input type="hidden" name="location:id" id="location:id" value="' . $settings['locationId'] . "\" />\n";
     }
     $r .= data_entry_helper::text_input(array('fieldname' => 'location:name', 'label' => lang::get('Transect Name'), 'class' => 'control-width-4 required', 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if (!$settings['canEditBody']) {
         $r .= '<p>' . lang::get('This site cannot be edited because there are walks recorded on it. Please contact the site administrator if you think there are details which need changing.') . '</p>';
     } else {
         if (count($settings['walks']) > 0) {
             // can edit it
             $r .= '<p>' . lang::get('This site has walks recorded on it. Please do not change the site details without considering the impact on the existing data.') . '</p>';
         }
     }
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= data_entry_helper::sref_and_system(array('fieldname' => 'location:centroid_sref', 'geomFieldname' => 'location:centroid_geom', 'label' => 'Grid Ref.', 'systems' => $systems, 'class' => 'required', 'helpText' => lang::get('Click on the map to set the central grid reference.'), 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '));
     if ($settings['locationId'] && data_entry_helper::$entity_to_load['location:code'] != '' && data_entry_helper::$entity_to_load['location:code'] != null) {
         $r .= data_entry_helper::text_input(array('fieldname' => 'location:code', 'label' => lang::get('Site Code'), 'class' => 'control-width-4', 'disabled' => ' readonly="readonly" '));
     } else {
         $r .= "<p>" . lang::get('The Site Code will be allocated by the Administrator.') . "</p>";
     }
     // setup the map options
     $options = iform_map_get_map_options($args, $auth['read']);
     // find the form blocks that need to go below the map.
     $bottom = '';
     $bottomBlocks = explode("\n", isset($args['bottom_blocks']) ? $args['bottom_blocks'] : '');
     foreach ($bottomBlocks as $block) {
         $bottom .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read'], 'disabled' => $settings['canEditBody'] ? '' : ' disabled="disabled" '), $block);
     }
     // other blocks to go at the top, next to the map
     if (isset($args['site_help']) && $args['site_help'] != '') {
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . t($args['site_help']) . '</p>';
     }
     $r .= get_attribute_html($settings['attributes'], $args, array('extraParams' => $auth['read']));
     $r .= '</fieldset>';
     $r .= "</div>";
     // left
     $r .= '<div class="right" style="width: 44%">';
     if (!$settings['locationId']) {
         $help = t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box on the left.');
         $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
         $r .= data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']));
     }
     if (isset($args['maxPrecision']) && $args['maxPrecision'] != '') {
         $options['clickedSrefPrecisionMax'] = $args['maxPrecision'];
     }
     if (isset($args['minPrecision']) && $args['minPrecision'] != '') {
         $options['clickedSrefPrecisionMin'] = $args['minPrecision'];
     }
     $olOptions = iform_map_get_ol_options($args);
     $options['clickForSpatialRef'] = $settings['canEditBody'];
     $r .= map_helper::map_panel($options, $olOptions);
     $r .= '</div></div>';
     // right
     if (!empty($bottom)) {
         $r .= $bottom;
     }
     if ($args['branch_assignment_permission'] != '') {
         if ($settings['canAllocBranch'] || $settings['locationId']) {
             $r .= self::get_branch_assignment_control($auth['read'], $settings['branchCmsUserAttr'], $args, $settings);
         }
     }
     if ($args['allow_user_assignment']) {
         if ($settings['canAllocUser']) {
             $r .= self::get_user_assignment_control($auth['read'], $settings['cmsUserAttr'], $args);
         } else {
             if (!$settings['locationId']) {
                 // for a new record, we need to link the current user to the location if they are not admin.
                 global $user;
                 $r .= '<input type="hidden" name="locAttr:' . self::$cmsUserAttrId . '" value="' . $user->uid . '">';
             }
         }
     }
     if ($settings['canEditBody']) {
         $r .= '<button type="submit" class="indicia-button right">' . lang::get('Save') . '</button>';
     }
     if ($settings['canEditBody'] && $settings['locationId']) {
         $r .= '<button type="button" class="indicia-button right" id="delete-transect">' . lang::get('Delete') . '</button>';
     }
     $r .= '</form>';
     $r .= '</div>';
     // site-details
     // This must go after the map panel, so it has created its toolbar
     data_entry_helper::$onload_javascript .= "\$('#current-section').change(selectSection);\n";
     if ($settings['canEditBody'] && $settings['locationId']) {
         $walkIDs = array();
         foreach ($settings['walks'] as $walk) {
             $walkIDs[] = $walk['id'];
         }
         $sectionIDs = array();
         foreach ($settings['sections'] as $code => $section) {
             $sectionIDs[] = $section['id'];
         }
         data_entry_helper::$javascript .= "\r\ndeleteSurvey = function(){\r\n  if(confirm(\"" . (count($settings['walks']) > 0 ? count($settings['walks']) . ' ' . lang::get('walks will also be deleted when you delete this location.') . ' ' : '') . lang::get('Are you sure you wish to delete this location?') . "\")){\r\n    deleteWalks([" . implode(',', $walkIDs) . "]);\r\n    deleteSections([" . implode(',', $sectionIDs) . "]);\r\n    \$('#delete-transect').html('Deleting Transect');\r\n    deleteLocation(" . $settings['locationId'] . ");\r\n    \$('#delete-transect').html('Done');\r\n    window.location='" . url($args['sites_list_path']) . "';\r\n  };\r\n};\r\n\$('#delete-transect').click(deleteSurvey);\r\n";
     }
     return $r;
 }
 public static function get_sample_form($args, $node, $response)
 {
     global $user;
     iform_load_helpers(array('map_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     // either looking at existing, creating a new one, or an error occurred: no successful posts...
     // first check some conditions are met
     $sampleMethods = helper_base::get_termlist_terms($auth, 'indicia:sample_methods', array('Timed Count'));
     if (count($sampleMethods) == 0) {
         return 'The sample method "Timed Count" must be defined in the termlist in order to use this form.';
     }
     $sampleId = isset($_GET['sample_id']) ? $_GET['sample_id'] : null;
     if ($sampleId && !isset(data_entry_helper::$validation_errors)) {
         data_entry_helper::load_existing_record($auth['read'], 'sample', $sampleId);
     }
     $isAdmin = isset($args['manager_permission']) && user_access($args['manager_permission']);
     // The following is butchered from mnhnl.
     data_entry_helper::$javascript .= "\r\n// the default edit layer is used for this sample\r\nvar editLayer = null;\r\n\r\nconvertGeom = function(geom, projection){\r\n  if (projection.projcode!='EPSG:900913' && projection.projcode!='EPSG:3857') {\r\n    var cloned = geom.clone();\r\n    return cloned.transform(new OpenLayers.Projection('EPSG:900913'), projection);\r\n  }\r\n  return geom;\r\n}\r\nreverseConvertGeom = function(geom, projection){\r\n  if (projection.projcode!='EPSG:900913' && projection.projcode!='EPSG:3857') {\r\n    var cloned = geom.clone();\r\n    return cloned.transform(projection, new OpenLayers.Projection('EPSG:900913'));\r\n  }\r\n  return geom;\r\n}\r\n\r\ngetwkt = function(geometry, incFront, incBrackets){\r\n  var retVal;\r\n  \t  retVal = '';\r\n  \t  switch(geometry.CLASS_NAME){\r\n  \t  case \"OpenLayers.Geometry.Point\":\r\n  \t  return((incFront!=false ? 'POINT' : '')+(incBrackets!=false ? '(' : '')+geometry.x+' '+geometry.y+(incBrackets!=false ? ')' : ''));\r\n  \t  break;\r\n  \t  case \"OpenLayers.Geometry.MultiPoint\":\r\n      retVal = 'MULTIPOINT(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\r\n      retVal += ')';\r\n      break;\r\n    case \"OpenLayers.Geometry.LineString\":\r\n      retVal = (incFront!=false ? 'LINESTRING' : '')+'(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, false);\r\n      retVal += ')';\r\n      break;\r\n    case \"OpenLayers.Geometry.MultiLineString\":\r\n      retVal = 'MULTILINESTRING(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\r\n      retVal += ')';\r\n      break;\r\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\r\n      retVal = (incFront!=false ? 'POLYGON' : '')+'((';\r\n      for(var i=0; i< geometry.components[0].components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[0].components[i], false, false);\r\n      retVal += '))';\r\n      break;\r\n    case \"OpenLayers.Geometry.MultiPolygon\":\r\n      retVal = 'MULTIPOLYGON(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], false, true);\r\n      retVal += ')';\r\n      break;\r\n    case \"OpenLayers.Geometry.Collection\":\r\n      retVal = 'GEOMETRYCOLLECTION(';\r\n      for(var i=0; i< geometry.components.length; i++)\r\n        retVal += (i!=0 ? ',':'')+getwkt(geometry.components[i], true, true);\r\n      retVal += ')';\r\n      break;\r\n  }\r\n  return retVal;\r\n}\r\nsetSref = function(geometry){\r\n  var centre = getCentroid(geometry);\r\n  centre = reverseConvertGeom(centre, editLayer.map.projection); // convert to indicia internal projection\r\n  var system = \$('#imp-sref-system').val();\t\t\t\t\r\n  jQuery.getJSON('" . data_entry_helper::$base_url . "/index.php/services/spatial/wkt_to_sref?wkt=POINT(' + centre.x + '  ' + centre.y + ')&system=' + system + '&precision=" . (isset($args['precision']) && $args['precision'] != '' ? $args['precision'] : '8') . "&callback=?',\r\n      function(data){\r\n        if(typeof data.error != 'undefined')\r\n          alert(data.error);\r\n        else\r\n          \$('#imp-sref').val(data.sref);\r\n       });\r\n};\r\nhook_setGeomFields = [];\r\nsetGeomFields = function(){\r\n  var geomstack = [];\r\n  var completeGeom;\r\n  for(var i=0; i<editLayer.features.length; i++)\r\n    if(editLayer.features[i].attributes.highlighted == true)\r\n      geomstack.push(editLayer.features[i].geometry.clone()); // needs to be a clone as we don't want to transform the original geoms.\r\n  if(geomstack.length == 0){\r\n    jQuery('#imp-geom').val('');\r\n    jQuery('#imp-sref').val('');\r\n    return;\r\n  } else if (geomstack.length == 1)\r\n    completeGeom = geomstack[0];\r\n  else\r\n    completeGeom = new OpenLayers.Geometry.Collection(geomstack);\r\n  // the geometry is in the map projection: if this doesn't match indicia's internal one, then must convert.\r\n  if (editLayer.map.projection.projcode!='EPSG:900913' && editLayer.map.projection.projcode!='EPSG:3857') \r\n    completeGeom.transform(editLayer.map.projection,  new OpenLayers.Projection('EPSG:900913'));\r\n  jQuery('#imp-geom').val(getwkt(completeGeom, true, true));\r\n  setSref(getCentroid(completeGeom));\r\n  if(hook_setGeomFields.length > 0)\r\n    for(i=0; i< hook_setGeomFields.length; i++)\r\n  \t  (hook_setGeomFields[i])(completeGeom);\r\n}\r\nremoveDrawnGeom = function(){\r\n  var highlighted=gethighlight();\r\n  if(highlighted.length > 0) {\r\n    unhighlightAll();\r\n  }\r\n  for(var i=editLayer.features.length-1; i>=0; i--)\r\n    editLayer.destroyFeatures([editLayer.features[i]]);\r\n}\r\nreplaceGeom = function(feature, layer, modControl, geom, highlight, setFields){\r\n  if(modControl.feature)\r\n    modControl.unselectFeature(modControl.feature);\r\n  var newfeature = new OpenLayers.Feature.Vector(geom, {});\r\n  newfeature.attributes = feature.attributes;\r\n  layer.destroyFeatures([feature]);\r\n  layer.addFeatures([newfeature]);\r\n  modControl.selectFeature(newfeature);\r\n  selectFeature.highlight(newfeature);\r\n  newfeature.attributes.highlighted=true;\r\n  if(setFields) setGeomFields();\r\n}\r\naddAndSelectNewGeom = function(layer, modControl, geom, highlight){\r\n  var feature = new OpenLayers.Feature.Vector(geom, {highlighted: false, ours: true});\r\n  layer.addFeatures([feature]);\r\n  modControl.selectFeature(feature);\r\n  feature.attributes.highlighted=true;\r\n  selectFeature.highlight(feature);\r\n  setGeomFields();\r\n  return feature;\r\n}\r\naddToExistingFeatureSet = function(existingFeatures, layer, modControl, geom, highlight){\r\n  var feature = new OpenLayers.Feature.Vector(geom, {});\r\n  feature.attributes = existingFeatures[0].attributes;\r\n  layer.addFeatures([feature]);\r\n  modControl.selectFeature(feature);\r\n  selectFeature.highlight(feature);\r\n  feature.attributes.highlighted=true;\r\n  setGeomFields();\r\n}\r\nunhighlightAll = function(){\r\n  if(modAreaFeature.feature) modAreaFeature.unselectFeature(modAreaFeature.feature);\r\n  var highlighted = gethighlight();\r\n  for(var i=0; i<highlighted.length; i++) {\r\n    highlighted[i].attributes.highlighted = false;\r\n    selectFeature.unhighlight(highlighted[i]);\r\n  }\r\n}\r\ngethighlight = function(){\r\n  var features=[];\r\n  for(var i=0; i<editLayer.features.length; i++){\r\n    if(editLayer.features[i].attributes.highlighted==true){\r\n      features.push(editLayer.features[i]);\r\n    }}\r\n  return features;\r\n}\r\n\r\naddDrawnPolygonToSelection = function(geometry) {\r\n  var points = geometry.components[0].getVertices();\r\n  if(points.length < 3){\r\n    alert(\"" . lang::get('LANG_TooFewPoints') . "\");\r\n    return false;\r\n  }\r\n  var highlightedFeatures = gethighlight();\r\n  if(highlightedFeatures.length == 0){\r\n    // No currently selected feature. Create a new one.\r\n    feature = addAndSelectNewGeom(editLayer, modAreaFeature, geometry, true);\r\n  \treturn true;\r\n  }\r\n  var selectedFeature = false;\r\n  for(var i=0; i<highlightedFeatures.length; i++){\r\n    if(highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.Polygon\" ||\r\n        highlightedFeatures[i].geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") {\r\n      selectedFeature = highlightedFeatures[i];\r\n  \t        \t\tbreak;\r\n    }}\r\n  // a site is already selected so the Drawn/Specified state stays unaltered\r\n  if(!selectedFeature) {\r\n      addToExistingFeatureSet(highlightedFeatures, editLayer, modAreaFeature, geometry, true);\r\n      return true;\r\n  }\r\n  if(selectedFeature.geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") {\r\n    if(modAreaFeature.feature)\r\n\t    modAreaFeature.unselectFeature(selectedFeature);\r\n    selectedFeature.geometry.addComponents([geometry]);\r\n    modAreaFeature.selectFeature(selectedFeature);\r\n    selectFeature.highlight(selectedFeature);\r\n    selectedFeature.attributes.highlighted = true;\r\n    setGeomFields();\r\n  } else { // is OpenLayers.Geometry.Polygon\r\n    var CompoundGeom = new OpenLayers.Geometry.MultiPolygon([selectedFeature.geometry, geometry]);\r\n    replaceGeom(selectedFeature, editLayer, modAreaFeature, CompoundGeom, true, true);\r\n  }\r\n  return true;\r\n}\r\nonFeatureModified = function(evt) {\r\n  var feature = evt.feature;\r\n  switch(feature.geometry.CLASS_NAME){\r\n    case \"OpenLayers.Geometry.Polygon\": // only do outer ring\r\n      points = feature.geometry.components[0].getVertices();\r\n      if(points.length < 3){\r\n        alert(\"" . lang::get('There are now too few vertices to make a polygon: it will now be completely removed.') . "\");\r\n        modAreaFeature.unselectFeature(feature);\r\n        editLayer.destroyFeatures([feature]);\r\n      }\r\n      break;\r\n    case \"OpenLayers.Geometry.MultiPolygon\":\r\n  \t  for(i=feature.geometry.components.length-1; i>=0; i--) {\r\n        points = feature.geometry.components[i].components[0].getVertices();\r\n        if(points.length < 3){\r\n          alert(\"" . lang::get('There are now too few vertices to make a polygon: it will now be completely removed.') . "\");\r\n  \t      var selectedFeature = modAreaFeature.feature;\r\n          modAreaFeature.unselectFeature(selectedFeature);\r\n          selectFeature.unhighlight(selectedFeature);\r\n          editLayer.removeFeatures([selectedFeature]);\r\n          selectedFeature.geometry.removeComponents([feature.geometry.components[i]]);\r\n  \t      editLayer.addFeatures([selectedFeature]);\r\n          modAreaFeature.selectFeature(selectedFeature);\r\n          selectFeature.highlight(selectedFeature);\r\n          selectedFeature.attributes.highlighted = true;\r\n        }\r\n      }\r\n      if(feature.geometry.components.length == 0){\r\n        modAreaFeature.unselectFeature(feature);\r\n        editLayer.destroyFeatures([feature]);\r\n      }\r\n      break;\r\n  }\r\n  setGeomFields();\r\n}\r\n/********************************/\r\n/* Define Map Control callbacks */\r\n/********************************/\r\nUndoSketchPoint = function(layer){\r\n  for(var i = editControl.controls.length-1; i>=0; i--)\r\n    if(editControl.controls[i].CLASS_NAME == \"OpenLayers.Control.DrawFeature\" && editControl.controls[i].active)\r\n      editControl.controls[i].undo();\r\n};\r\nRemoveNewSite = function(){\r\n  highlighted = gethighlight();\r\n  removeDrawnGeom(highlighted[0].attributes.SiteNum);\r\n  setGeomFields();\r\n};\r\nZoomToFeature = function(feature){\r\n  var div = jQuery('#map')[0];\r\n  var bounds=feature.geometry.bounds.clone();\r\n  // extend the boundary to include a buffer, so the map does not zoom too tight.\r\n  var dy = (bounds.top-bounds.bottom) * div.settings.maxZoomBuffer;\r\n  var dx = (bounds.right-bounds.left) * div.settings.maxZoomBuffer;\r\n  bounds.top = bounds.top + dy;\r\n  bounds.bottom = bounds.bottom - dy;\r\n  bounds.right = bounds.right + dx;\r\n  bounds.left = bounds.left - dx;\r\n  if (div.map.getZoomForExtent(bounds) > div.settings.maxZoom) {\r\n    // if showing something small, don't zoom in too far\r\n    div.map.setCenter(bounds.getCenterLonLat(), div.settings.maxZoom);\r\n  } else {\r\n    // Set the default view to show something triple the size of the grid square\r\n    // Assume this is within the map extent\r\n    div.map.zoomToExtent(bounds);\r\n  }\r\n};\r\n/***********************************/\r\n/* Define Controls for use on Map. */\r\n/***********************************/\r\npolygonDrawActivate = function(){\r\n  selectFeature.deactivate();\r\n  modAreaFeature.activate();\r\n  highlighted = gethighlight();\r\n  if(highlighted.length == 0)\r\n    return true;\r\n  for(var i=0; i<editLayer.features.length; i++)\r\n      if(editLayer.features[i].attributes.highlighted == true)\r\n        modAreaFeature.selectFeature(editLayer.features[i]);\r\n  return true;\r\n};\r\n\t\t         \t\t \t\t\r\nmodAreaFeature = null;\r\nselectFeature = null;\r\npolygonDraw = null;\r\neditControl = null;\r\n\r\nmapInitialisationHooks.push(function(mapdiv) {\r\n\t\$('#imp-sref').unbind('change');\r\n\teditLayer=mapdiv.map.editLayer;\r\n    var nav=new OpenLayers.Control.Navigation({displayClass: \"olControlNavigation\", \"title\":mapdiv.settings.hintNavigation+((!mapdiv.settings.scroll_wheel_zoom || mapdiv.settings.scroll_wheel_zoom===\"false\")?'': mapdiv.settings.hintScrollWheel)});\t\r\n\teditControl = new OpenLayers.Control.Panel({allowDepress: false, 'displayClass':'olControlEditingToolbar'});\r\n\tmapdiv.map.addControl(editControl);\r\n" . ($isAdmin || $sampleId == null ? "  \tmodAreaFeature = new OpenLayers.Control.ModifyFeature(editLayer,{standalone: true});\r\n\tselectFeature = new OpenLayers.Control.SelectFeature([editLayer],{standalone: true});\r\n\tpolygonDraw = new OpenLayers.Control.DrawFeature(editLayer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon', drawFeature: addDrawnPolygonToSelection, title: '" . lang::get('Select this tool to draw a polygon, clicking on the map to place the vertices of the shape, and double clicking on the final vertex to finish. You may drag and drop vertices (circles) to move them, and draw more than one polygon, i.e. input a discontinuous site.') . "'});\r\n\tpolygonDraw.events.on({'activate': polygonDrawActivate});\r\n\teditControl.addControls([polygonDraw\r\n\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlClearLayer\", trigger: RemoveNewSite, title: '" . lang::get('Press this button to completely remove the currently drawn site.') . "'})\r\n    \t\t\t\t\t ,nav\t\r\n\t\t\t\t         ,new OpenLayers.Control.Button({displayClass: \"olControlUndo\", trigger: UndoSketchPoint, title: '" . lang::get('If you have not completed a polygon, press this button to clear the last vertex. If you have completed a polygon but wish to remove a vertex, place the mouse over the vertex and press the Delete button: this only works for the corner vertices, not the dummy ones half way down each side.') . "'})\r\n    ]);\r\n\tmapdiv.map.addControl(modAreaFeature);\r\n\tmodAreaFeature.deactivate();\r\n\tfor(var i=0; i<mapdiv.map.controls.length; i++)\r\n      mapdiv.map.controls[i].deactivate();\r\n\teditControl.activate();\r\n\tnav.activate();\r\n\t// any existing features come from the existing sites geometry: convert to ours\r\n    // will have been zoomed as well.\r\n\tfor(var i=0; i<editLayer.features.length; i++) {\r\n\t  editLayer.features[i].attributes.highlighted = true;\r\n\t  editLayer.features[i].attributes.type = 'ours';\r\n\t  editLayer.features[i].attributes.ours = true;\r\n\t  selectFeature.highlight(editLayer.features[i]);\r\n\t}\t\t\t\t         \t\t\r\n\teditLayer.events.on({\r\n\t\t'featuremodified': onFeatureModified\r\n\t});\r\n" : "\teditControl.addControls([nav]);\r\n\tfor(var i=0; i<mapdiv.map.controls.length; i++)\r\n      mapdiv.map.controls[i].deactivate();\r\n\teditControl.activate();\r\n\tnav.activate();\r\n") . "\tmapdiv.map.events.triggerEvent('zoomend');\r\n});\r\n";
     $r = '<form method="post" id="sample">' . $auth['write'];
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get location details.
     $r .= '<input type="hidden" name="read_nonce" value="' . $auth['read']['nonce'] . '"/>';
     $r .= '<input type="hidden" name="read_auth_token" value="' . $auth['read']['auth_token'] . '"/>';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
     }
     // pass a param that sets the next page to display
     $r .= "<input type=\"hidden\" name=\"website_id\" value=\"" . $args['website_id'] . "\"/>\r\n<input type=\"hidden\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\"/>\r\n<input type=\"hidden\" name=\"page\" value=\"site\"/>";
     $attributes = data_entry_helper::getAttributes(array('id' => $sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $sampleMethods[0]['id']));
     $r .= get_user_profile_hidden_inputs($attributes, $args, isset(data_entry_helper::$entity_to_load['sample:id']), $auth['read']) . data_entry_helper::text_input(array('label' => lang::get('Site Name'), 'fieldname' => 'sample:location_name', 'validation' => array('required')));
     $help = lang::get('The Year field is read-only, and is calculated automatically from the date(s) of the Counts.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     if ($sampleId == null) {
         if (isset($_GET['date'])) {
             data_entry_helper::$entity_to_load['C1:sample:date'] = $_GET['date'];
         }
         $r .= data_entry_helper::date_picker(array('label' => lang::get('Date of first count'), 'fieldname' => 'C1:sample:date', 'validation' => array('required', 'date')));
         data_entry_helper::$javascript .= "jQuery('#C1\\\\:sample\\\\:date').change(function(){\r\n  jQuery('#sample\\\\:date').val(jQuery(this).val() == '' ? '' : jQuery(this).datepicker('getDate').getFullYear());\r\n});\r\nif(jQuery('#C1\\\\:sample\\\\:date').val() != '') jQuery('#sample\\\\:date').val(jQuery('#C1\\\\:sample\\\\:date').datepicker('getDate').getFullYear());\n";
     }
     if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
         // Date has 4 digit year first (ISO style) - only interested in Year.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('Y');
     }
     unset(data_entry_helper::$default_validation_rules['sample:date']);
     $r .= data_entry_helper::text_input(array('label' => lang::get('Year'), 'fieldname' => 'sample:date', 'readonly' => ' readonly="readonly" '));
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $r .= get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions);
     foreach ($blockOptions as $attr => $block) {
         foreach ($block as $item => $value) {
             switch ($item) {
                 case 'suffix':
                     data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr) . "').after(' <label style=\"width:auto\">" . $value . "</label>');\n";
                     break;
                 case 'setArea':
                     $parts = explode(',', $value);
                     // 0=factor,1=number decimal places
                     data_entry_helper::$javascript .= "\$('#" . str_replace(':', '\\\\:', $attr) . "').attr('readonly','readonly');\nhook_setGeomFields.push(function(geom){\n\$('#" . str_replace(':', '\\\\:', $attr) . "').val(\n(geom.getArea()/" . $parts[0] . ").toFixed(" . $parts[1] . "));\n});\n";
                     break;
             }
         }
     }
     $r .= '<input type="hidden" name="sample:sample_method_id" value="' . $sampleMethods[0]['id'] . '" />';
     $help = lang::get('Now draw the flight area for the timed count on the map below. The Grid Reference is filled in automatically when the site is drawn.');
     $r .= '<p class="ui-state-highlight page-notice ui-corner-all">' . $help . '</p>';
     $options = iform_map_get_map_options($args, $auth['read']);
     $options['clickForSpatialRef'] = false;
     $olOptions = iform_map_get_ol_options($args);
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get($system);
     }
     $r .= "<label for=\"imp-sref\">" . lang::get('Grid Reference') . ":</label> <input type=\"text\" id=\"imp-sref\" name=\"sample:entered_sref\" value=\"" . data_entry_helper::$entity_to_load['sample:entered_sref'] . "\" readonly=\"readonly\" class=\"required\" />";
     $r .= "<input type=\"hidden\" id=\"imp-geom\" name=\"sample:geom\" value=\"" . data_entry_helper::$entity_to_load['sample:geom'] . "\" />";
     if (count($systems) == 1) {
         // Hidden field for the system
         $keys = array_keys($systems);
         $r .= "<input type=\"hidden\" id=\"imp-sref-system\" name=\"sample:entered_sref_system\" value=\"" . $keys[0] . "\" />\n";
     } else {
         $r .= self::sref_system_select(array('fieldname' => 'sample:entered_sref_system'));
     }
     $r .= '<br />' . data_entry_helper::georeference_lookup(iform_map_get_georef_options($args, $auth['read']));
     $r .= data_entry_helper::map_panel($options, $olOptions);
     $r .= data_entry_helper::textarea(array('label' => 'Comment', 'fieldname' => 'sample:comment', 'class' => 'wide'));
     $r .= '<input type="submit" value="' . lang::get('Next') . '" />';
     $r .= '<a href="' . $args['summary_page'] . '"><button type="button" class="ui-state-default ui-corner-all" />' . lang::get('Cancel') . '</button></a>';
     // allow deletes if sample id is present: i.e. existing sample.
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= '<button id="delete-button" type="button" class="ui-state-default ui-corner-all" />' . lang::get('Delete') . '</button>';
         // note we only require bare minimum in order to flag a sample as deleted.
         $r .= '</form><form method="post" id="delete-form" style="display: none;">';
         $r .= $auth['write'];
         $r .= '<input type="hidden" name="page" value="delete"/>';
         $r .= '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>';
         $r .= '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>';
         $r .= '<input type="hidden" name="sample:deleted" value="t"/>';
         data_entry_helper::$javascript .= "jQuery('#delete-button').click(function(){\r\n  if(confirm(\"" . lang::get('Are you sure you want to delete this timed count?') . "\"))\r\n    jQuery('#delete-form').submit();\r\n});\n";
     }
     $r .= '</form>';
     data_entry_helper::enable_validation('sample');
     return $r;
 }
?>

<form action="" method="post">
<?php 
require_once DOCROOT . 'client_helpers/data_entry_helper.php';
if (isset($_POST['from']) && !preg_match('/^[0-2][0-9]:[0-5][0-9](:[0-5][0-9])?$/', $_POST['from'])) {
    echo '<p>The start time you entered was not recognised.</p>';
    unset($_POST['from']);
}
if (isset($_POST['to']) && !preg_match('/^[0-2][0-9]:[0-5][0-9](:[0-5][0-9])?$/', $_POST['to'])) {
    echo '<p>The end time you entered was not recognised.</p>';
    unset($_POST['to']);
}
echo data_entry_helper::select(array('label' => 'Select the log date', 'lookupValues' => $files, 'fieldname' => 'file', 'labelClass' => 'auto', 'suffixTemplate' => 'nosuffix', 'default' => isset($_POST['file']) ? $_POST['file'] : null));
echo data_entry_helper::text_input(array('label' => 'between', 'labelClass' => 'auto', 'fieldname' => 'from', 'suffixTemplate' => 'nosuffix', 'default' => isset($_POST['from']) ? $_POST['from'] : '00:00:00'));
echo data_entry_helper::text_input(array('label' => 'and', 'labelClass' => 'auto', 'fieldname' => 'to', 'suffixTemplate' => 'nosuffix', 'default' => isset($_POST['to']) ? $_POST['to'] : '24:00:00'));
echo data_entry_helper::select(array('label' => 'level', 'labelClass' => 'auto', 'fieldname' => 'level', 'suffixTemplate' => 'nosuffix', 'default' => isset($_POST['level']) ? $_POST['level'] : 'debug', 'lookupValues' => array('4' => 'All messages', '3' => 'Errors, warnings and notices', '2' => 'Errors and warnings', '1' => 'Errors only')));
?>
<input type="submit" value="Go" />
</form>
<?php 
if (isset($_POST['file'])) {
    // A file has been selected, so output the filtered log content.
    $filename = DOCROOT . 'application/logs/' . $_POST['file'];
    if (file_exists($filename)) {
        $file = fopen($filename, 'r');
        if ($file === FALSE) {
            echo '<p class="page-notice">The log file could not be opened.</p>';
        } else {
            echo '<br/><h2>Showing log file for ' . str_replace('.log.php', '', $_POST['file']) . '</h2>';
            $time = '00:00:00';
   /**
    * Return the generated form output.
    * @return Form HTML.
    */
   public static function get_form($args, $node, $response = null)
   {
       global $user;
       global $custom_terms;
       $logged_in = $user->uid > 0;
       $r = '';
       // Get authorisation tokens to update and read from the Warehouse.
       $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
       $readAuth = $auth['read'];
       $svcUrl = data_entry_helper::$base_url . '/index.php/services';
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.form.js', 'module');
       data_entry_helper::link_default_stylesheet();
       data_entry_helper::add_resource('jquery_ui');
       $language = iform_lang_iso_639_2($args['language']);
       if ($args['language'] != 'en') {
           data_entry_helper::add_resource('jquery_ui_' . $args['language']);
       }
       // If not logged in: Display an information message.
       // This form should only be called in POST mode when setting the location allocation.
       //  All other posting is now done via AJAX.
       // When invoked by GET there are the following modes:
       // No additional arguments: mode 0.
       // Additional argument - new : mode 1.
       // Additional argument - sample_id=<id> : mode 2.
       // Additional argument - occurrence_id=<id> : mode 3.
       // Additional arguments - merge_sample_id1=<id>&merge_sample_id2=<id> : mode 2.1
       $mode = 0;
       // default mode : output survey selector
       // mode 1: output the main Data Entry page: occurrence list or add/edit occurrence tabs hidden. "Survey" tab active
       // mode 2: output the main Data Entry page, display existing sample. Active tab determined by iform params. No occurence details filled in.
       // mode 2.1: sample 2 has all its occurrences merged into sample 1. sample 2 is then flagged as deleted. sample 1 is then viewed as in normal mode 2.
       // mode 3: output the main Data Entry page, display existing occurrence. "Edit Occurrence" tab active. Occurence details filled in.
       $surveyReadOnly = false;
       // On top of this, things can be flagged as readonly. RO mode 2+4 means no Add Occurrence tab.
       if (!$logged_in) {
           return lang::get('LANG_not_logged_in');
       }
       $parentSample = array();
       $parentLoadID = null;
       $childSample = array();
       $childLoadID = null;
       $thisOccID = -1;
       // IDs have to be >0, so this is outside the valid range
       // Load up attribute details
       $sample_walk_direction_id = self::getAttrID($auth, $args, 'sample', self::ATTR_WALK);
       $sample_reliability_id = self::getAttrID($auth, $args, 'sample', self::ATTR_RELIABILITY);
       $sample_visit_number_id = self::getAttrID($auth, $args, 'sample', self::ATTR_VISIT);
       $sample_wind_id = self::getAttrID($auth, $args, 'sample', self::ATTR_WIND);
       $sample_precipitation_id = self::getAttrID($auth, $args, 'sample', self::ATTR_RAIN);
       $sample_temperature_id = self::getAttrID($auth, $args, 'sample', self::ATTR_TEMP);
       $sample_cloud_id = self::getAttrID($auth, $args, 'sample', self::ATTR_CLOUD);
       $sample_start_time_id = self::getAttrID($auth, $args, 'sample', self::ATTR_START_TIME);
       $sample_end_time_id = self::getAttrID($auth, $args, 'sample', self::ATTR_END_TIME);
       $sample_closure_id = self::getAttrID($auth, $args, 'sample', self::ATTR_CLOSED);
       $uid_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_UID);
       $email_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_EMAIL);
       $username_attr_id = self::getAttrID($auth, $args, 'sample', self::ATTR_USERNAME);
       $occurrence_confidence_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_CONFIDENCE);
       $occurrence_count_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_COUNT);
       $occurrence_approximation_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_APPROXIMATION);
       $occurrence_territorial_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_TERRITORIAL);
       $occurrence_atlas_code_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_ATLAS_CODE);
       $occurrence_overflying_id = self::getAttrID($auth, $args, 'occurrence', self::ATTR_OVERFLYING);
       if (!$sample_closure_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_CLOSED . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$uid_attr_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_UID . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$email_attr_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_EMAIL . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$username_attr_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_USERNAME . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$sample_walk_direction_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_WALK . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$sample_visit_number_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_VISIT . '" sample attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$occurrence_count_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_COUNT . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$occurrence_territorial_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_TERRITORIAL . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if (!$occurrence_atlas_code_id) {
           return '<p>This form must be used with a survey which has the "' . self::ATTR_ATLAS_CODE . '" occurrence attribute allocated to it. Survey_id = ' . $args['survey_id'];
       }
       if ($_POST) {
           if (!array_key_exists('website_id', $_POST)) {
               // non Indicia POST, in this case must be the location allocations. add check to ensure we don't corrept the data by accident
               if (iform_loctools_checkaccess($node, 'admin') && array_key_exists('mnhnlbtw', $_POST)) {
                   iform_loctools_deletelocations($node);
                   foreach ($_POST as $key => $value) {
                       $parts = explode(':', $key);
                       if ($parts[0] == 'location' && $value) {
                           iform_loctools_insertlocation($node, $value, $parts[1]);
                       }
                   }
               }
           }
       } else {
           if (array_key_exists('merge_sample_id1', $_GET) && array_key_exists('merge_sample_id2', $_GET) && user_access($args['edit_permission'])) {
               $mode = 2;
               // first check can access the 2 samples given
               $parentLoadID = $_GET['merge_sample_id1'];
               $url = $svcUrl . '/data/sample/' . $parentLoadID . "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entity = json_decode(curl_exec($session), true);
               if (count($entity) == 0 || $entity[0]["parent_id"]) {
                   return '<p>' . lang::get('LANG_No_Access_To_Sample') . ' ' . $parentLoadID . '</p>';
               }
               // The check for id2 is slightly different: there is the possiblity that someone will F5/refresh their browser, after the transfer and delete have taken place.
               // In this case we carry on, but do not do the transfer and delete.
               $url = $svcUrl . '/data/sample/' . $_GET['merge_sample_id2'] . "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entity = json_decode(curl_exec($session), true);
               if (count($entity) > 0 && !$entity[0]["parent_id"]) {
                   // now get child samples and point to new parent.
                   $url = $svcUrl . '/data/sample?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . '&parent_id=' . $_GET['merge_sample_id2'];
                   $session = curl_init($url);
                   curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
                   $entities = json_decode(curl_exec($session), true);
                   if (count($entities) > 0) {
                       foreach ($entities as $entity) {
                           $Model = data_entry_helper::wrap(array('id' => $entity['id'], 'parent_id' => $_GET['merge_sample_id1']), 'sample');
                           $request = data_entry_helper::$base_url . "/index.php/services/data/save";
                           $postargs = 'submission=' . json_encode($Model) . '&auth_token=' . $auth['write_tokens']['auth_token'] . '&nonce=' . $auth['write_tokens']['nonce'] . '&persist_auth=true';
                           $postresponse = data_entry_helper::http_post($request, $postargs, false);
                           // the response array will always feature an output, which is the actual response or error message. if it is not json format, assume error text, and json encode that.
                           $response = $postresponse['output'];
                           if (!json_decode($response, true)) {
                               return "<p>" . lang::get('LANG_Error_When_Moving_Sample') . ": id " . $entity['id'] . " : " . $response;
                           }
                       }
                   }
                   // finally delete the no longer used sample
                   $Model = data_entry_helper::wrap(array('id' => $_GET['merge_sample_id2'], 'deleted' => 'true'), 'sample');
                   $request = data_entry_helper::$base_url . "/index.php/services/data/save";
                   $postargs = 'submission=' . json_encode($Model) . '&auth_token=' . $auth['write_tokens']['auth_token'] . '&nonce=' . $auth['write_tokens']['nonce'] . '&persist_auth=true';
                   $postresponse = data_entry_helper::http_post($request, $postargs, false);
                   // the response array will always feature an output, which is the actual response or error message. if it is not json format, assume error text, and json encode that.
                   $response = $postresponse['output'];
                   if (!json_decode($response, true)) {
                       return "<p>" . lang::get('LANG_Error_When_Deleting_Sample') . ": id " . $entity['id'] . " : " . $response;
                   }
               }
           } else {
               if (array_key_exists('sample_id', $_GET)) {
                   $mode = 2;
                   $parentLoadID = $_GET['sample_id'];
               } else {
                   if (array_key_exists('occurrence_id', $_GET)) {
                       $mode = 3;
                       $childLoadID = $_GET['occurrence_id'];
                       $thisOccID = $childLoadID;
                   } else {
                       if (array_key_exists('new', $_GET)) {
                           $mode = 1;
                       }
                   }
               }
           }
           // else default to mode 0
       }
       // define language strings so they can be used for validation translation.
       data_entry_helper::$javascript .= "var translations = [\n";
       foreach ($custom_terms as $key => $value) {
           if (substr($key, 0, 4) != "LANG") {
               data_entry_helper::$javascript .= "  {key: \"" . $key . "\", translated: \"" . $value . "\"},\n";
           }
       }
       data_entry_helper::$javascript .= "];\n";
       // define layers for all maps.
       // each argument is a comma separated list eg:
       // "Name:Lux Outline,URL:http://localhost/geoserver/wms,LAYERS:indicia:nation2,SRS:EPSG:2169,FORMAT:image/png,minScale:0,maxScale:1000000,units:m";
       $optionsArray_Location = array();
       $options = explode(',', $args['locationLayer']);
       foreach ($options as $option) {
           $parts = explode(':', $option);
           $optionName = $parts[0];
           unset($parts[0]);
           $optionsArray_Location[$optionName] = implode(':', $parts);
       }
       // Work out list of locations this user can see.
       $locations = iform_loctools_listlocations($node);
       if ($locations != 'all') {
           data_entry_helper::$javascript .= "var locationList = [" . implode(',', $locations) . "];\n";
       }
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/hasharray.js', 'module');
       drupal_add_js(drupal_get_path('module', 'iform') . '/media/js/jquery.datagrid.js', 'module');
       if (method_exists(get_called_class(), 'getHeaderHTML')) {
           $r .= call_user_func(array(get_called_class(), 'getHeaderHTML'), $args);
       }
       // Work out list of locations this user can see.
       // $locations = iform_loctools_listlocations($node);
       ///////////////////////////////////////////////////////////////////
       // default mode 0 : display a page with tabs for survey selector,
       // locations allocator and reports (last two require permissions)
       ///////////////////////////////////////////////////////////////////
       if ($mode == 0) {
           // If the user has permissions, add tabs so can choose to see
           // locations allocator
           $tabs = array('#surveyList' => lang::get('LANG_Surveys'));
           if (iform_loctools_checkaccess($node, 'admin')) {
               $tabs['#setLocations'] = lang::get('LANG_Allocate_Locations');
           }
           if (iform_loctools_checkaccess($node, 'superuser')) {
               $tabs['#downloads'] = lang::get('LANG_Download');
           }
           if (count($tabs) > 1) {
               $r .= "<div id=\"controls\">" . data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => '#surveyList')) . "<div id=\"temp\"></div>";
               $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
           }
           if ($locations == 'all') {
               $useloclist = 'NO';
               $loclist = '-1';
           } else {
               // an empty list will cause an sql error, lids must be > 0, so push a -1 to prevent the error.
               if (empty($locations)) {
                   $locations[] = -1;
               }
               $useloclist = 'YES';
               $loclist = implode(',', $locations);
           }
           // Create the Survey list datagrid for this user.
           drupal_add_js("jQuery(document).ready(function(){\n  \$('div#smp_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_samples', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['location_name', 'date', 'num_visit', 'num_occurrences', 'num_taxa'],\n    reportColumnTitles: {location_name : '" . lang::get('LANG_Transect') . "', date : '" . lang::get('LANG_Date') . "', num_visit : '" . lang::get('LANG_Visit_No') . "', num_occurrences : '" . lang::get('LANG_Num_Occurrences') . "', num_taxa : '" . lang::get('LANG_Num_Species') . "'},\n    actionColumns: {" . lang::get('LANG_Show') . " : \"" . url('node/' . $node->nid, array('query' => 'sample_id=£id£')) . "\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "', visit_attr_id : '" . $sample_visit_number_id . "', closed_attr_id : '" . $sample_closure_id . "', use_location_list : '" . $useloclist . "', locations : '" . $loclist . "'},\n    itemsPerPage : 12,\n    condCss : {field : 'closed', value : '0', css: 'mnhnl-btw-highlight'},\n    cssOdd : ''\n  });\n});\n      ", 'inline');
           data_entry_helper::$javascript .= "\n// Create Layers.\nvar locationListLayer;\nmapInitialisationHooks.push(function (div) {\n      \"use strict\";";
           if ($locations == 'all' || $loclist != '-1') {
               data_entry_helper::$javascript .= "\n  var WMSoptions = {SERVICE: 'WMS', VERSION: '1.1.0', STYLES: '',\n        SRS: div.map.projection.proj.srsCode, /* Now takes it from map */\n        FORMAT: '" . $optionsArray_Location['FORMAT'] . "',\n        TRANSPARENT: 'true', ";
               if ($locations != 'all') {
                   // when given a restricted feature list we have to use the feature id to filter in order to not go over 2000 char limit on the URL
                   // Can only generate the feature id if we access a table directly, not through a view. Go direct to the locations table.
                   // don't need to worry about parent_id in this case as we know exactly which features we want.
                   // need to use btw_transects view for unrestricted so we can filter by parent_id=NULL.
                   $locFeatures = array();
                   foreach ($locations as $location) {
                       $locFeatures[] = "locations." . $location;
                   }
                   data_entry_helper::$javascript .= "\n        LAYERS: 'indicia:locations',\n        FEATUREID: '" . implode(',', $locFeatures) . "'";
               } else {
                   data_entry_helper::$javascript .= " LAYERS: '" . $optionsArray_Location['LAYERS'] . "', CQL_FILTER: 'website_id=" . $args['website_id'] . "'";
               }
               data_entry_helper::$javascript .= "\n  };\n  locationListLayer = new OpenLayers.Layer.WMS('" . $optionsArray_Location['Name'] . "',\n        '" . (function_exists(iform_proxy_url) ? iform_proxy_url($optionsArray_Location['URL']) : $optionsArray_Location['URL']) . "',\n        WMSoptions, {\n        minScale: " . $optionsArray_Location['minScale'] . ",\n        maxScale: " . $optionsArray_Location['maxScale'] . ",\n        units: '" . $optionsArray_Location['units'] . "',\n        isBaseLayer: false,\n        singleTile: true\n  });\n  div.map.addLayer(locationListLayer);\n});\n";
           }
           $r .= '
 <div id="surveyList" class="mnhnl-btw-datapanel"><div id="smp_grid"></div>
   <form><input type="button" value="' . lang::get('LANG_Add_Survey') . '" onclick="window.location.href=\'' . url('node/' . $node->nid, array('query' => 'new')) . '\'"></form></div>';
           // Add the locations allocator if user has admin rights.
           if (iform_loctools_checkaccess($node, 'admin')) {
               $r .= '
 <div id="setLocations" class="mnhnl-btw-datapanel">
   <form method="post">
     <input type="hidden" id="mnhnlbtw" name="mnhnlbtw" value="mnhnlbtw" />';
               $url = $svcUrl . '/data/location?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&parent_id=NULL&orderby=name&columns=id,name,parent_id";
               $session = curl_init($url);
               curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
               $entities = json_decode(curl_exec($session), true);
               $userlist = iform_loctools_listusers($node);
               if (!empty($entities)) {
                   foreach ($entities as $entity) {
                       if (!$entity["parent_id"]) {
                           // only assign parent locations.
                           $r .= "\n<label for=\"location:" . $entity["id"] . "\">" . $entity["name"] . ":</label><select id=\"location:" . $entity["id"] . "\" name=\"location:" . $entity["id"] . "\"><option value=\"\" >&lt;" . lang::get('LANG_Not_Allocated') . "&gt;</option>";
                           $defaultuserid = iform_loctools_getuser($node, $entity["id"]);
                           foreach ($userlist as $uid => $a_user) {
                               $r .= "<option value=\"" . $uid . "\" " . ($uid == $defaultuserid ? 'selected="selected" ' : '') . ">" . $a_user->name . "</option>";
                           }
                           $r .= "</select>";
                       }
                   }
               }
               $r .= "\n      <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('Save Location Allocations') . "\" />\n    </form>\n  </div>";
           }
           // Add the downloader if user has manager (superuser) rights.
           if (iform_loctools_checkaccess($node, 'superuser')) {
               $r .= '
 <div id="downloads" class="mnhnl-btw-datapanel">
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_transect_direction_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Direction_Report') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "direction_attr_id":' . $sample_walk_direction_id . ', "closed_attr_id":' . $sample_closure_id . '}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Direction_Report_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_verified_data_report.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Verified_Data_Report') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . '}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Verified_Data_Report_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Initial_Download') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "INITIAL", "quality": "!R", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Initial_Download_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Confirm_Download') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "CONFIRM", "quality": "V", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Confirm_Download_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Final_Download') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "FINAL", "quality": "V", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Final_Download_Button') . '">
   </form>
   <form method="post" action="' . data_entry_helper::$base_url . '/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_download_report_2.xml&reportSource=local&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth['nonce'] . '&mode=csv">
     <p>' . lang::get('LANG_Complete_Final_Download') . '</p>
     <input type="hidden" name="params" value=\'{"survey_id":' . $args['survey_id'] . ', "closed_attr_id":' . $sample_closure_id . ', "download": "OFF", "quality": "NA", "occattrs": "' . $occurrence_confidence_id . ',' . $occurrence_count_id . ',' . $occurrence_approximation_id . ',' . $occurrence_territorial_id . ',' . $occurrence_atlas_code_id . ',' . $occurrence_overflying_id . '", "smpattrs" : "' . $sample_walk_direction_id . ',' . $sample_reliability_id . ',' . $sample_visit_number_id . ',' . $sample_wind_id . ',' . $sample_precipitation_id . ',' . $sample_temperature_id . ',' . $sample_cloud_id . ',' . $sample_start_time_id . ',' . $sample_end_time_id . ',' . $sample_closure_id . ',' . $uid_attr_id . ',' . $email_attr_id . ',' . $username_attr_id . '"}\' />
     <input type="submit" class="ui-state-default ui-corner-all" value="' . lang::get('LANG_Complete_Final_Download_Button') . '">
   </form>
 </div>';
           }
           // Create Map
           $options = iform_map_get_map_options($args, $readAuth);
           $olOptions = iform_map_get_ol_options($args);
           //      if($locations == 'all' || $loclist != '-1')
           //        $options['layers'] = array('locationListLayer');
           $options['searchLayer'] = 'false';
           $options['editLayer'] = 'false';
           $options['initialFeatureWkt'] = null;
           $options['proxy'] = '';
           $options['scroll_wheel_zoom'] = false;
           $options['width'] = 'auto';
           // TBD remove from arglist
           $r .= "<div class=\"mnhnl-btw-mappanel\">\n" . data_entry_helper::map_panel($options, $olOptions) . "</div>\n";
           data_entry_helper::$javascript .= "\n\$('#controls').bind('tabsshow', function(event, ui) {\n  var y = \$('.mnhnl-btw-datapanel:visible').outerHeight(true) + \$('.mnhnl-btw-datapanel:visible').position().top;\n  if(y < \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top){\n    y = \$('.mnhnl-btw-mappanel').outerHeight(true)+ \$('.mnhnl-btw-mappanel').position().top;\n  }\n  \$('#controls').height(y - \$('#controls').position().top);\n});\n";
           if (count($tabs) > 1) {
               // close tabs div if present
               $r .= "</div>";
           }
           if (method_exists(get_called_class(), 'getTrailerHTML')) {
               $r .= call_user_func(array(get_called_class(), 'getTrailerHTML'), $args);
           }
           return $r;
       }
       ///////////////////////////////////////////////////////////////////
       // At this point there are 3 modes:
       // Adding a new survey
       // editing/showing an existing survey
       // editing/showing an existing occurrence
       // First load the occurrence (and its position sample) if provided
       // Then load the parent sample if provided, or derived from occurrence.
       // $occReadOnly is set if the occurrence has been downloaded. Not even an admin user can modify it in this case.
       data_entry_helper::$javascript .= "\n// Create Layers.\nvar locationLayer, occListLayer, control;\nmapInitialisationHooks.push(function (div) {\n  \"use strict\";\n  // Create vector layers: one to display the location onto, and another for the occurrence list\n  // the default edit layer is used for the occurrences themselves\n  var locStyleMap = new OpenLayers.StyleMap({\n      'default': new OpenLayers.Style({\n        fillColor: 'Green',\n        strokeColor: 'Black',\n        fillOpacity: 0.2,\n        strokeWidth: 1\n  })});\n  locationLayer = new OpenLayers.Layer.Vector('" . lang::get("LANG_Location_Layer") . "', {styleMap: locStyleMap});\n  var occStyleMap = new OpenLayers.StyleMap({\n      'default': new OpenLayers.Style({\n        pointRadius: 3,\n        fillColor: 'Red',\n        fillOpacity: 0.3,\n        strokeColor: 'Red',\n        strokeWidth: 1\n  })});\n  occListLayer = new OpenLayers.Layer.Vector(\"" . lang::get("LANG_Occurrence_List_Layer") . "\", {styleMap: occStyleMap});\n  div.map.addLayer(locationLayer);\n  div.map.addLayer(occListLayer);\n  var control = new OpenLayers.Control.SelectFeature(occListLayer);\n  occListLayer.map.addControl(control);\n  function onPopupClose(evt) {\n    // 'this' is the popup.\n    control.unselect(this.feature);\n  }\n  function onFeatureSelect(evt) {\n    feature = evt.feature;\n    popup = new OpenLayers.Popup.FramedCloud(\"featurePopup\",\n               feature.geometry.getBounds().getCenterLonLat(),\n                             new OpenLayers.Size(100,100),\n                             feature.attributes.taxon + \" (\" + feature.attributes.count + \")\",\n                             null, true, onPopupClose);\n    feature.popup = popup;\n    popup.feature = feature;\n    feature.layer.map.addPopup(popup);\n  }\n  function onFeatureUnselect(evt) {\n    feature = evt.feature;\n    if (feature.popup) {\n        popup.feature = null;\n        feature.layer.map.removePopup(feature.popup);\n        feature.popup.destroy();\n        feature.popup = null;\n    }\n  }\n  occListLayer.events.on({\n    'featureselected': onFeatureSelect,\n    'featureunselected': onFeatureUnselect\n  });\n  control.activate();\n});\n";
       $occReadOnly = false;
       $childSample = array();
       if ($childLoadID) {
           // load the occurrence and its associated sample (which holds the position)
           $url = $svcUrl . '/data/occurrence/' . $childLoadID;
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           if (count($entity) == 0) {
               return '<p>' . lang::get('LANG_No_Access_To_Occurrence') . '</p>';
           }
           foreach ($entity[0] as $key => $value) {
               $childSample['occurrence:' . $key] = $value;
           }
           if ($entity[0]['downloaded_flag'] == 'F') {
               // Final download complete, now readonly
               $occReadOnly = true;
           }
           $url = $svcUrl . '/data/sample/' . $childSample['occurrence:sample_id'];
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           if (count($entity) == 0) {
               return '<p>' . lang::get('LANG_No_Access_To_Occurrence') . '</p>';
           }
           foreach ($entity[0] as $key => $value) {
               $childSample['sample:' . $key] = $value;
           }
           $childSample['sample:geom'] = '';
           // value received from db is not WKT, which is assumed by all the code.
           $childSample['taxon'] = $childSample['occurrence:taxon'];
           $parentLoadID = $childSample['sample:parent_id'];
       }
       $parentSample = array();
       if ($parentLoadID) {
           // load the container master sample
           $url = $svcUrl . '/data/sample/' . $parentLoadID;
           $url .= "?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           if (count($entity) == 0) {
               return '<p>' . lang::get('LANG_No_Access_To_Sample') . '</p>';
           }
           foreach ($entity[0] as $key => $value) {
               $parentSample['sample:' . $key] = $value;
           }
           if (is_array($locations) && !in_array($entity[0]["location_id"], $locations)) {
               return '<p>' . lang::get('LANG_No_Access_To_Location') . '</p>';
           }
           if ($entity[0]["parent_id"]) {
               return '<p>' . lang::get('LANG_No_Access_To_Sample') . '</p>';
           }
           $parentSample['sample:date'] = $parentSample['sample:date_start'];
           // bit of a bodge
           $childSample['sample:date'] = $parentSample['sample:date'];
           // enforce a match between child and parent sample dates
           // default values for attributes from DB are picked up automatically.
       }
       data_entry_helper::$entity_to_load = $parentSample;
       $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['sample:id'], 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $readAuth));
       $closedFieldName = $attributes[$sample_closure_id]['fieldname'];
       $closedFieldValue = data_entry_helper::check_default_value($closedFieldName, array_key_exists('default', $attributes[$sample_closure_id]) ? $attributes[$sample_closure_id]['default'] : '0');
       // default is not closed
       if ($closedFieldValue == '') {
           $closedFieldValue = '0';
       }
       if ($closedFieldValue == '1' && !user_access($args['edit_permission'])) {
           // sample has been closed, no admin perms. Everything now set to read only.
           $surveyReadOnly = true;
           $disabledText = "disabled=\"disabled\"";
           $defAttrOptions = array('extraParams' => $readAuth, 'disabled' => $disabledText);
       } else {
           // sample editable. Admin users can modify closed samples.
           $disabledText = "";
           $defAttrOptions = array('extraParams' => $readAuth);
       }
       // with the AJAX code, we deal with the validation semi manually: Form name is meant be invalid as we only want code included.
       data_entry_helper::enable_validation(null);
       $r .= "<div id=\"controls\">\n";
       $activeTab = 'survey';
       // mode 1 = new Sample, display sample.
       if ($mode == 2) {
           // have specified a sample ID
           if ($args["on_edit_survey_nav"] == "survey") {
               $activeTab = 'survey';
           } else {
               if ($surveyReadOnly || $args["on_edit_survey_nav"] == "list") {
                   $activeTab = 'occurrenceList';
               } else {
                   $activeTab = 'occurrence';
               }
           }
           if ($surveyReadOnly) {
               data_entry_helper::$javascript .= "jQuery('#occ-form').hide();";
           }
       } else {
           if ($mode == 3) {
               // have specified an occurrence ID
               $activeTab = 'occurrence';
           }
       }
       // Set Up form tabs.
       $r .= data_entry_helper::enable_tabs(array('divId' => 'controls', 'active' => $activeTab));
       $r .= "<div id=\"temp\"></div>";
       $r .= data_entry_helper::tab_header(array('tabs' => array('#survey' => lang::get('LANG_Survey'), '#occurrence' => lang::get($surveyReadOnly || $occReadOnly ? 'LANG_Show_Occurrence' : (isset($childSample['sample:id']) ? 'LANG_Edit_Occurrence' : 'LANG_Add_Occurrence')), '#occurrenceList' => lang::get('LANG_Occurrence_List'))));
       // Set up main Survey Form.
       $r .= "<div id=\"survey\" class=\"mnhnl-btw-datapanel\">\n  <p id=\"read-only-survey\"><strong>" . lang::get('LANG_Read_Only_Survey') . "</strong></p>";
       if (user_access($args['edit_permission']) && array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
           // check for other surveys of same date/transect: only if admin user.
           $url = $svcUrl . '/data/sample?mode=json&view=detail&auth_token=' . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&date_start=" . $parentSample['sample:date_start'] . "&location_id=" . $parentSample['sample:location_id'];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entity = json_decode(curl_exec($session), true);
           if (count($entity) > 1) {
               // ignore ourselves!
               $r .= "<div id=\"mergeSurveys\"><p><strong>" . lang::get('LANG_Found_Mergable_Surveys') . "</strong></p>";
               foreach ($entity as $survey) {
                   if ($survey['id'] != $parentSample['sample:id']) {
                       $r .= "<form action=\"" . url('node/' . $node->nid, array()) . "\" method=\"get\"><input type=\"submit\" value=\"" . lang::get('LANG_Merge_With_ID') . " " . $survey['id'] . "\"><input type=\"hidden\" name=\"merge_sample_id1\" value=\"" . $parentSample['sample:id'] . "\" /><input type=\"hidden\" name=\"merge_sample_id2\" value=\"" . $survey['id'] . "\" /></form>";
                   }
               }
               $r .= "</div>";
           }
       }
       $r .= "<form id=\"SurveyForm\" action=\"" . iform_ajaxproxy_url($node, 'sample') . "\" method=\"post\">\n    <input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />";
       if (array_key_exists('sample:id', data_entry_helper::$entity_to_load)) {
           $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n";
       } else {
           $r .= "<input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"\" disabled=\"disabled\" />\n";
           // GvB 19/Nov/2012 : change to user detail defaults
           // logic is now much simpler, and they are only included/created if the sample is new.
           $fieldName = $attributes[$uid_attr_id]['fieldname'];
           $fieldValue = data_entry_helper::check_default_value($fieldName, $user->uid);
           $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n";
           $fieldName = $attributes[$email_attr_id]['fieldname'];
           $fieldValue = data_entry_helper::check_default_value($fieldName, $user->mail);
           $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n";
           $fieldName = $attributes[$username_attr_id]['fieldname'];
           $fieldValue = data_entry_helper::check_default_value($fieldName, $user->name);
           $r .= "<input type=\"hidden\" name=\"" . $fieldName . "\" value=\"" . $fieldValue . "\" />\n";
       }
       $defAttrOptions['validation'] = array('required');
       if ($locations == 'all') {
           $locOptions = array_merge(array('label' => lang::get('LANG_Transect')), $defAttrOptions);
           $locOptions['extraParams'] = array_merge(array('parent_id' => 'NULL', 'view' => 'detail', 'orderby' => 'name'), $locOptions['extraParams']);
           $r .= data_entry_helper::location_select($locOptions);
       } else {
           // can't use location select due to location filtering.
           $r .= "<label for=\"imp-location\">" . lang::get('LANG_Transect') . ":</label>\n<select id=\"imp-location\" name=\"sample:location_id\" " . $disabled_text . " class=\" \"  >";
           $url = $svcUrl . '/data/location?mode=json&view=detail&parent_id=NULL&orderby=name&auth_token=' . $readAuth['auth_token'] . '&nonce=' . $readAuth["nonce"];
           $session = curl_init($url);
           curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
           $entities = json_decode(curl_exec($session), true);
           if (!empty($entities)) {
               foreach ($entities as $entity) {
                   if (in_array($entity["id"], $locations)) {
                       if ($entity["id"] == data_entry_helper::$entity_to_load['sample:location_id']) {
                           $selected = 'selected="selected"';
                       } else {
                           $selected = '';
                       }
                       $r .= "<option value=\"" . $entity["id"] . "\" " . $selected . ">" . $entity["name"] . "</option>";
                   }
               }
           }
           $r .= "</select><span class=\"deh-required\">*</span><br />";
       }
       $languageFilteredAttrOptions = $defAttrOptions + array('language' => iform_lang_iso_639_2($args['language']));
       $r .= data_entry_helper::outputAttribute($attributes[$sample_walk_direction_id], $languageFilteredAttrOptions) . ($sample_reliability_id ? data_entry_helper::outputAttribute($attributes[$sample_reliability_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_RELIABILITY . "' not assigned to this survey</span>") . data_entry_helper::outputAttribute($attributes[$sample_visit_number_id], array_merge($languageFilteredAttrOptions, array('default' => 1, 'noBlankText' => true)));
       if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
           // Date has 4 digit year first (ISO style) - convert date to expected output format
           $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
           data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
       }
       if ($args['language'] != 'en') {
           data_entry_helper::add_resource('jquery_ui_' . $args['language']);
       }
       // this will autoload the jquery_ui resource. The date_picker does not have access to the args.
       if ($surveyReadOnly) {
           $r .= data_entry_helper::text_input(array_merge($defAttrOptions, array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'disabled' => $disabledText)));
       } else {
           $r .= data_entry_helper::date_picker(array('label' => lang::get('LANG_Date'), 'fieldname' => 'sample:date', 'class' => 'vague-date-picker'));
       }
       $r .= ($sample_wind_id ? data_entry_helper::outputAttribute($attributes[$sample_wind_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_WIND . "' not assigned to this survey</span>") . ($sample_precipitation_id ? data_entry_helper::outputAttribute($attributes[$sample_precipitation_id], $languageFilteredAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_RAIN . "' not assigned to this survey</span>") . ($sample_temperature_id ? data_entry_helper::outputAttribute($attributes[$sample_temperature_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> &deg;C</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_TEMP . "' not assigned to this survey</span>") . ($sample_cloud_id ? data_entry_helper::outputAttribute($attributes[$sample_cloud_id], $defAttrOptions) : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_CLOUD . "' not assigned to this survey</span>") . ($sample_start_time_id ? data_entry_helper::outputAttribute($attributes[$sample_start_time_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> hh:mm</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_START_TIME . "' not assigned to this survey</span>") . ($sample_end_time_id ? data_entry_helper::outputAttribute($attributes[$sample_end_time_id], array_merge($defAttrOptions, array('suffixTemplate' => 'nosuffix'))) . "<span class=\"attr-trailer\"> hh:mm</span><br />" : "<span style=\"display: none;\">Sample attribute '" . self::ATTR_END_TIME . "' not assigned to this survey</span>");
       data_entry_helper::$javascript .= "\njQuery('.attr-trailer').prev('br').remove();\n";
       unset($defAttrOptions['suffixTemplate']);
       unset($defAttrOptions['validation']);
       if (user_access($args['edit_permission'])) {
           //  users with admin permissions can override the closing of the
           // sample by unchecking the checkbox.
           // Because this is attached to the sample, we have to include the sample required fields in the
           // the post. This means they can't be disabled, so we enable all fields in this case.
           // Normal users can only set this to closed, and they do this using a button/hidden field.
           $r .= data_entry_helper::outputAttribute($attributes[$sample_closure_id], $defAttrOptions);
           // In addition admin users can delete a survey/sample.
           $r .= data_entry_helper::checkbox(array('label' => lang::get('Deleted'), 'fieldname' => 'sample:deleted', 'id' => 'main-sample-deleted'));
       } else {
           // hidden closed
           $r .= "<input type=\"hidden\" id=\"main-sample-closed\" name=\"" . $closedFieldName . "\" value=\"" . $closedFieldValue . "\" />\n";
       }
       data_entry_helper::$javascript .= "\n\$.validator.messages.required = \"" . lang::get('validation_required') . "\";\n\$.validator.defaults.onsubmit = false; // override default - so that we handle all submission validation.\n";
       if (!$surveyReadOnly) {
           // NB that we don't even include the buttons when readonly.
           data_entry_helper::$javascript .= "\njQuery('#read-only-survey').hide();\njQuery('#ro-sur-occ-warn').hide();\n";
           $r .= "<input type=button id=\"close1\" class=\"ui-state-default ui-corner-all \" value=\"" . lang::get('LANG_Save_Survey_Details') . "\";\n        onclick=\"var result = \$('#SurveyForm input').valid();\n          var result2 = \$('#SurveyForm select').valid();\n          if (!result || !result2) {\n              return;\n            }\n            jQuery('#close1').addClass('loading-button');\n            jQuery('#SurveyForm').submit();\">\n";
           if (!user_access($args['edit_permission'])) {
               if ($mode == 1) {
                   data_entry_helper::$javascript .= "jQuery('#close2').hide();\n";
               }
               $r .= "<input type=button id=\"close2\" class=\"ui-state-default ui-corner-all \" value=\"" . lang::get('LANG_Save_Survey_And_Close') . "\"\n        onclick=\"if(confirm('" . lang::get('LANG_Close_Survey_Confirm') . "')){\n          var result = \$('#SurveyForm input').valid();\n          var result2 = \$('#SurveyForm select').valid();\n          if (!result || !result2) {\n              return;\n            }\n            jQuery('#main-sample-closed').val('1');\n            jQuery('#close2').addClass('loading-button');\n            jQuery('#SurveyForm').submit();\n          };\">\n";
           }
       }
       $r .= "</form></div>\n";
       data_entry_helper::$javascript .= "\nalertIndiciaError = function(data){\n\tvar errorString = \"" . lang::get('LANG_Indicia_Warehouse_Error') . "\";\n\tif(data.error){\terrorString = errorString + ' : ' + data.error;\t}\n\tif(data.errors){\n\t\tfor (var i in data.errors){\n\t\t\terrorString = errorString + ' : ' + data.errors[i];\n\t\t}\n\t}\n\talert(errorString);\n\t// the most likely cause is authentication failure - eg the read authentication has timed out.\n\t// prevent further use of the form:\n\t\$('.loading-panel').remove();\n\t\$('.loading-hide').removeClass('loading-hide');\n};\nerrorPos = null;\nclearErrors = function(formSel) {\n\tjQuery(formSel).find('.inline-error').remove();\n\terrorPos = null;\n};\nmyScrollTo = function(selector){\n\tjQuery(selector).filter(':visible').each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\nmyScrollToError = function(){\n\tjQuery('.inline-error,.error').filter(':visible').prev().each(function(){\n\t\tif(errorPos == null || jQuery(this).offset().top < errorPos){\n\t\t\terrorPos = jQuery(this).offset().top;\n\t\t\twindow.scroll(0,errorPos);\n\t\t}\n\t});\n};\njQuery('#SurveyForm').ajaxForm({\n\tasync: false,\n\tdataType:  'json',\n    beforeSubmit:   function(data, obj, options){\n    \tvar valid = true;\n    \tclearErrors('form#SurveyForm');\n    \tif (!jQuery('form#SurveyForm > input').valid()) {\n\t\t\tmyScrollToError();\n  \t\t\tjQuery('.loading-button').removeClass('loading-button');\n\t\t\treturn false;\n  \t\t};\n  \t\tSurveyFormRetVal = true;\n  \t\tif(jQuery('#main-sample-deleted:checked').length == 0){ // only do check if not deleting\n          jQuery.ajax({ // now check if there are any other samples with this combination of date and location\n            type: 'GET',\n            url: \"" . $svcUrl . "/data/sample?mode=json&view=detail\" +\n                \"&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n                \"&orderby=id&callback=?&location_id=\"+jQuery('#imp-location').val()+\"&date_start=\"+jQuery('#SurveyForm [name=sample\\:date]').val(),\n            data: {},\n            success: function(detData) {\n              for(i=0, j=0; i< detData.length; i++){\n                if(detData[i].id != jQuery('#SurveyForm [name=sample\\:id]').val()) j++;\n              }\n              if(j) {\n              \tSurveyFormRetVal = confirm(\"" . lang::get('LANG_Survey_Already_Exists') . "\");\n              }\n            },\n            dataType: 'json',\n            async: false\n          });\n        }\n\t\treturn SurveyFormRetVal;\n\t},\n    success:   function(data){\n       // this will leave all the fields populated.\n       \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n          jQuery('#occ-form').show();\n          jQuery('#na-occ-warn,#mergeSurveys').hide();";
       if (!user_access($args['edit_permission'])) {
           // don't need to worry about record_status value for non admins as they can't modify when closed.
           data_entry_helper::$javascript .= "\n          if(jQuery('#main-sample-closed').val() == '1'){\n            jQuery('#read-only-survey,#ro-sur-occ-warn').show();\n            jQuery('#close1,#close2,#occ-form').hide(); //can't enter any more occurrences\n            jQuery('#SurveyForm').children().attr('disabled','disabled');\n          };\n";
       } else {
           data_entry_helper::$javascript .= "\n          jQuery('#occurrence\\\\:record_status').val(jQuery('#smpAttr\\\\:" . $attributes[$sample_closure_id]['attributeId'] . ":checked').length > 0 ? 'C' : 'I');\n          if(jQuery('#main-sample-deleted:checked').length > 0){\n            jQuery('#return-to-main').click();\n            return;\n          };\n";
       }
       data_entry_helper::$javascript .= "// If sample_id filled in -> we have a previously saved collection, so possibly have subsamples.\nif(jQuery('#SurveyForm > input[name=sample\\:id]').val() != ''){\n    // Put up warning dialogue that we are checking the subsamples: include a progress bar: set to zero%.\n    var dialog = \$('<span id=\"subsample-progress-span\"><p>'+\"" . lang::get('Please wait whilst some data integrity checks are carried out.') . "\"+'</p><div id=\"subsample-progress\"></div></span>').dialog({ title: \"" . lang::get('Checks') . "\", zIndex: 4000 });\n    jQuery('#subsample-progress').progressbar({value: 0});\n    jQuery.ajax({ // get all subsamples/occurrences to check if the dates match\n            type: 'GET',\n            url: \"" . $svcUrl . "/report/requestReport?report=library/occurrences/occurrences_list_for_parent_sample.xml&reportSource=local&mode=json&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n                \"&callback=?&sample_id=\"+data.outer_id+\"&survey_id=&date_from=&date_to=&taxon_group_id=&smpattrs=&occattrs=\",\n            data: {},\n            success: function(subData) {\n              jQuery('#subsample-progress').data('max',subData.length+1);\n              var mainDate = \$.datepicker.formatDate('yy-mm-dd', jQuery('#SurveyForm > input[name=sample\\:date]').datepicker(\"getDate\"));\n              for(i=0; i< subData.length; i++){ // loop through all subsamples\n                jQuery('#subsample-progress').progressbar('option','value',(i+1)*100/jQuery('#subsample-progress').data('max'));\n                var values = {};\n                var url = '';\n                // Check if date on subsamples matches supersample date: if not set up a post array for the sample, with correct date.\n                if(subData[i].date_start != mainDate){\n                  values['sample:id']=subData[i].sample_id;\n                  values['sample:date']=mainDate;\n                  url=\"" . iform_ajaxproxy_url($node, 'sample') . "\";\n                }\n";
       // Send AJAX request to set occurrence to 'C' if closed : use sync
       if (!user_access($args['edit_permission'])) {
           data_entry_helper::$javascript .= "                if(jQuery('#main-sample-closed').val() == '1'){\n";
       } else {
           data_entry_helper::$javascript .= "                if(jQuery('#smpAttr\\\\:" . $attributes[$sample_closure_id]['attributeId'] . ":checked').length > 0){\n";
       }
       // If records are already verified, they are left verified, as if the records themselves are saved
       // they will flagged as no longer verified: But have to force a re verification if date is changed.
       data_entry_helper::$javascript .= "\n                  if(subData[i].record_status == 'I' || typeof values['sample:id'] != 'undefined'){\n                    values['occurrence:id']=subData[i].occurrence_id;\n                    values['occurrence:record_status']='C';\n                    url=(url == '' ? \"" . iform_ajaxproxy_url($node, 'occurrence') . "\" : \"" . iform_ajaxproxy_url($node, 'smp-occ') . "\");\n                  }\n                } else { // any occurrences on unclosed collections must be flagged as 'I' - reopening unverifies.\n                  if(subData[i].record_status != 'I'){\n                    values['occurrence:id']=subData[i].occurrence_id;\n                    values['occurrence:record_status']='I';\n                    url=(url == '' ? \"" . iform_ajaxproxy_url($node, 'occurrence') . "\" : \"" . iform_ajaxproxy_url($node, 'smp-occ') . "\");\n                  }\n                }\n                if(url!=''){\n                  values['website_id']=" . $args['website_id'] . ";\n                  jQuery.ajax({ type: 'POST', url: url, data: values, dataType: 'json', async: false});\n                }\n              }\n            },\n            dataType: 'json',\n            async: false\n    });\n    dialog.dialog('close');\n    dialog.dialog('destroy');\n    jQuery('#subsample-progress-span').remove();\n}\n\n\t\t\twindow.scroll(0,0);\n            jQuery('#SurveyForm > input[name=sample\\:id]').removeAttr('disabled').val(data.outer_id);\n            jQuery('#occ-form > input[name=sample\\:parent_id]').val(data.outer_id);\n            jQuery('#occ-form > input[name=sample\\:date]').val(jQuery('#SurveyForm > input[name=sample\\:date]').val());\n            loadAttributes('sample_attribute_value', 'sample_attribute_id', 'sample_id', data.outer_id, 'smpAttr');\n            switch(\"" . $args["on_save_survey_nav"] . "\"){\n\t\t\t\tcase \"list\":\n\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[2];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"survey\":\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:";
       if (!user_access($args['edit_permission'])) {
           data_entry_helper::$javascript .= "\n\t\t\t\t\tif(jQuery('#main-sample-closed').val() == 0){\n\t\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\t\t\t\$(a).click();\n\t\t\t\t\t};";
       } else {
           data_entry_helper::$javascript .= "\n\t\t\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\t\t\$(a).click();";
       }
       data_entry_helper::$javascript .= "\n\t\t\t\t\tbreak;\n\t\t\t}\n        } else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error');\n    \t\t\tif (lastIndex != -1 && lastIndex  == (data.error.length - 16)){\n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\t// TODO translation\n\t\t\t\t\t\tfor (i in data.errors){\n\t\t\t\t\t\t\tvar label = \$('<p/>').addClass('inline-error').html(data.errors[i]);\n\t\t\t\t\t\t\tlabel.insertAfter('[name='+i+']');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\treturn;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n        }\n\t},\n    complete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n});\n// In this case, all the samples attributes are on the survey tab, and all the occurrence attributes are on the occurrence tab. No need to worry about getting the correct form.\nloadAttributes = function(attributeTable, attributeKey, key, keyValue, prefix){\n    jQuery.ajax({\n        type: \"GET\",\n        url: \"" . $svcUrl . "/data/\" + attributeTable + \"?mode=json&view=list\" +\n        \t\"&reset_timeout=true&nonce=" . $readAuth['nonce'] . "&auth_token=" . $readAuth['auth_token'] . "\" +\n   \t\t\t\"&\" + key + \"=\" + keyValue + \"&callback=?\",\n        data: {},\n        success: (function(attrPrefix, attrKey) {\n          var retVal = function(attrdata) {\n            if(!(attrdata instanceof Array)){\n              alertIndiciaError(attrdata);\n            } else if (attrdata.length>0) {\n              for (var i=0;i<attrdata.length;i++){\n                // in all cases if the attribute already has the <prefix>:<X>:<Y> format name we leave. Other wise we update <prefix>:<X> to <prefix>:<X>:<Y>\n                // We leave all values unchanged.\n                // need to be careful about Cloud: this is a drop down, but it is not language specific: the termlist is\n                // always in english, so the iso won't match.\n                if (attrdata[i].id){\n                  if (attrdata[i].iso == null || attrdata[i].iso == '') // no iso - not a look up.\n                    jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n                  else {\n                    if (attrdata[i].iso == '" . $language . "') // this is our actual language so OK\n                      jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n                    else {// not our language: look up all the other attrs, and if we don't find one of this id for our language, use this one.\n                      var found = false;\n                      for (var j=0;j<attrdata.length;j++)\n                        found = found || (i!=j && attrdata[i][attrKey] == attrdata[j][attrKey] && attrdata[j].iso == '" . $language . "');\n                      if(!found)\n                        jQuery('[name='+attrPrefix+'\\:'+attrdata[i][attrKey]+']').attr('name', attrPrefix+':'+attrdata[i][attrKey]+':'+attrdata[i].id);\n                    }\n                  }\n                }\n              }\n            }};\n          return retVal;\n          })(prefix, attributeKey),\n\t\tdataType: 'json',\n\t    async: false\n\t});\n}";
       // Set up Occurrence List tab: don't include when creating a new sample as it will have no occurrences
       // Grid populated at a later point
       $r .= "<div id=\"occurrenceList\" class=\"mnhnl-btw-datapanel\"><div id=\"occ_grid\"></div>\n  <form method=\"post\" action=\"" . data_entry_helper::$base_url . "/index.php/services/report/requestReport?report=reports_for_prebuilt_forms/MNHNL/mnhnl_btw_occurrences_report.xml&reportSource=local&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth['nonce'] . "&mode=csv\">\n    <input type=\"hidden\" id=\"params\" name=\"params\" value='{\"survey_id\":" . $args['survey_id'] . ", \"sample_id\":" . data_entry_helper::$entity_to_load['sample:id'] . "}' />\n    <input type=\"submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Download_Occurrences') . "\">\n  </form></div>";
       if ($occReadOnly) {
           // NB that we don't even include the buttons when readonly.
           data_entry_helper::$javascript .= "\njQuery('#ro-occ-occ-warn').show();\njQuery('#ro-sur-occ-warn').hide();\n";
       } else {
           data_entry_helper::$javascript .= "\njQuery('#ro-occ-occ-warn').hide();\n";
       }
       if ($mode == 1) {
           data_entry_helper::$javascript .= "jQuery('#occ-form').hide();";
       } else {
           data_entry_helper::$javascript .= "jQuery('#na-occ-warn').hide();";
       }
       // Set up Occurrence tab: don't allow entry of a new occurrence until after top level sample is saved.
       data_entry_helper::$entity_to_load = $childSample;
       $attributes = data_entry_helper::getAttributes(array('id' => data_entry_helper::$entity_to_load['occurrence:id'], 'valuetable' => 'occurrence_attribute_value', 'attrtable' => 'occurrence_attribute', 'key' => 'occurrence_id', 'fieldprefix' => 'occAttr', 'extraParams' => $readAuth));
       $extraParams = $readAuth + array('taxon_list_id' => $args['list_id'], 'view' => 'detail', 'query' => urlencode(json_encode(array('in' => array('language_iso', array('lat', iform_lang_iso_639_2($args['language'])))))));
       if ($occReadOnly) {
           // if the occurrence has been downloaded, no one can modify it.
           $disabledText = "disabled=\"disabled\"";
           $defAttrOptions['disabled'] = $disabledText;
       }
       $species_ctrl_args = array('label' => lang::get('LANG_Species'), 'fieldname' => 'occurrence:taxa_taxon_list_id', 'table' => 'taxa_taxon_list', 'captionField' => 'taxon', 'valueField' => 'id', 'columns' => 2, 'extraParams' => $extraParams, 'disabled' => $disabledText, 'defaultCaption' => data_entry_helper::$entity_to_load['occurrence:taxon']);
       $r .= "  <div id=\"occurrence\" class=\"mnhnl-btw-datapanel\">\n    <p id=\"ro-occ-occ-warn\"><strong>" . lang::get('LANG_Read_Only_Occurrence') . "</strong></p>\n    <p id=\"ro-sur-occ-warn\"><strong>" . lang::get('LANG_Read_Only_Survey') . "</strong></p>\n    <p id=\"na-occ-warn\"><strong>" . lang::get('LANG_Page_Not_Available') . "</strong></p>\n    <form method=\"post\" id=\"occ-form\" action=\"" . iform_ajaxproxy_url($node, 'smp-occ') . "\" >\n    <input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:survey_id\" name=\"sample:survey_id\" value=\"" . $args['survey_id'] . "\" />\n    <input type=\"hidden\" id=\"sample:parent_id\" name=\"sample:parent_id\" value=\"" . $parentSample['sample:id'] . "\" />\n    <input type=\"hidden\" id=\"sample:date\" name=\"sample:date\" value=\"" . data_entry_helper::$entity_to_load['sample:date'] . "\" />\n    <input type=\"hidden\" id=\"sample:id\" name=\"sample:id\" value=\"" . data_entry_helper::$entity_to_load['sample:id'] . "\" />\n    <input type=\"hidden\" id=\"occurrence:id\" name=\"occurrence:id\" value=\"" . data_entry_helper::$entity_to_load['occurrence:id'] . "\" />\n    <input type=\"hidden\" id=\"occurrence:record_status\" name=\"occurrence:record_status\" value=\"" . ($closedFieldValue == '0' ? 'I' : 'C') . "\" />\n    <input type=\"hidden\" id=\"occurrence:downloaded_flag\" name=\"occurrence:downloaded_flag\" value=\"N\" />\n    " . data_entry_helper::autocomplete($species_ctrl_args) . "\n    " . ($occurrence_confidence_id ? data_entry_helper::outputAttribute($attributes[$occurrence_confidence_id], array_merge($languageFilteredAttrOptions, array('noBlankText' => ''))) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_CONFIDENCE . "' not assigned to this survey</span>") . "\n    " . data_entry_helper::sref_and_system(array('label' => lang::get('LANG_Spatial_ref'), 'systems' => array('2169' => 'Luref (Gauss Luxembourg)'))) . "\n    <p>" . lang::get('LANG_Click_on_map') . "</p>\n    " . data_entry_helper::outputAttribute($attributes[$occurrence_count_id], array_merge($defAttrOptions, array('default' => 1))) . "\n    " . ($occurrence_approximation_id ? data_entry_helper::outputAttribute($attributes[$occurrence_approximation_id], $defAttrOptions) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_APPROXIMATION . "' not assigned to this survey</span>") . "\n    " . data_entry_helper::outputAttribute($attributes[$occurrence_territorial_id], array_merge($defAttrOptions, array('default' => 1, 'id' => 'occ-territorial'))) . "\n    " . data_entry_helper::outputAttribute($attributes[$occurrence_atlas_code_id], $languageFilteredAttrOptions) . "\n    " . ($occurrence_overflying_id ? data_entry_helper::outputAttribute($attributes[$occurrence_overflying_id], $defAttrOptions) : "<span style=\"display: none;\">Occurrence attribute '" . self::ATTR_OVERFLYING . "' not assigned to this survey</span>") . "\n    " . data_entry_helper::textarea(array('label' => lang::get('LANG_Comment'), 'fieldname' => 'occurrence:comment', 'disabled' => $disabledText));
       if (!$surveyReadOnly && !$occReadOnly) {
           if ($mode == 3) {
               $r .= data_entry_helper::checkbox(array('label' => lang::get('Delete'), 'fieldname' => 'sample:deleted', 'id' => 'occ-sample-deleted'));
           }
           $r .= "<input type=\"submit\" id=\"occ-submit\" class=\"ui-state-default ui-corner-all\" value=\"" . lang::get('LANG_Save_Occurrence_Details') . "\" />";
       }
       $r .= "  </form>\n";
       data_entry_helper::$javascript .= "\n// because of ID tracking it is easier to rebuild entire list etc.\nretriggerGrid = function(){\n  \$('div#occ_grid').empty();\n  occListLayer.destroyFeatures();\n  activateAddList = 1;\n  thisOccID = -1;\n  \$('div#occ_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_occurrences', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['taxon', 'territorial', 'count'],\n    reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n    actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n            '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "',\n            parent_id : jQuery('#SurveyForm [name=sample\\:id]').val(),\n            territorial_attr_id : '" . $occurrence_territorial_id . "',\n            count_attr_id : '" . $occurrence_count_id . "'},\n    itemsPerPage : 12,\n    callback : addListFeature ,\n    cssOdd : ''\n  });\n}\n\njQuery('#occ-form').ajaxForm({\n\tasync: false,\n\tdataType:  'json',\n    beforeSubmit:   function(data, obj, options){\n    \tvar valid = true;\n    \tclearErrors('form#occ-form');\n    \tif (!jQuery('form#occ-form > input').valid()) { valid = false; }\n    \tif (!jQuery('form#occ-form > select').valid()) { valid = false; }\n    \tif(!valid) {\n\t\t\tmyScrollToError();\n\t\t\treturn false;\n\t\t};\n\t\tjQuery('#occ-submit').addClass('loading-button');\n\t\treturn true;\n\t},\n    success:   function(data){\n       // this will leave all the fields populated.\n       \tif(data.success == 'multiple records' && data.outer_table == 'sample'){\n\t\t\twindow.scroll(0,0);\n\t\t\t// cant use reset form, as returns it to original values: if this was called with occurrence_id =<x> then it would repopulate with original occurrence's values\n\t\t\t// website_id, survey_id, record_status, downloaded_flag, sample:entered_sref_system are constants and are left alone. parent_id, date are only set referring to parent sample.\n\t\t\tjQuery('form#occ-form').find('[name^=occAttr\\:]').each(function(){\n\t\t\t\tvar name = jQuery(this).attr('name').split(':');\n\t\t\t\tjQuery(this).attr('name', name[0]+':'+name[1]);\n\t\t\t});\n\t\t\tjQuery('form#occ-form').find('[name=occurrence\\:id],[name=sample\\:id]').val('').attr('disabled', 'disabled');\n\t\t\tjQuery('form#occ-form').find('[name=occurrence\\:taxa_taxon_list_id],[name=occurrence\\:taxa_taxon_list_id\\:taxon],[name=sample\\:entered_sref],[name=sample\\:geom],[name=occurrence\\:comment]').val('');\n\t\t\tjQuery('form#occ-form').find('[name=occAttr\\:" . $occurrence_confidence_id . "]').find('option').removeAttr('selected');\n\t\t\tjQuery('form#occ-form').find('[name=occAttr\\:" . $occurrence_count_id . "]').val('1');\n\t\t\tjQuery('form#occ-form').find('input[name=occAttr\\:" . $occurrence_approximation_id . "],input[name=occAttr\\:" . $occurrence_overflying_id . "]').removeAttr('checked','checked');\n\t\t\tjQuery('form#occ-form').find('#occ-territorial').attr('checked','checked');\n\t\t\tjQuery('label[for=occ-sample-deleted]').remove(); // sample deleted only applicable when editing an existing occurrence. After saving reverts to Add Occurreence: no delete. Remove label then actual checkbox\n\t\t\tjQuery('form#occ-form').find('[name=sample\\:deleted]').remove(); // This removes both parts of the checkbox.\n\t\t\tsetAtlasStatus();\n\t\t\tretriggerGrid();\n\t\t\tlocationLayer.map.editLayer.destroyFeatures();\n\t\t\tvar a = \$('ul.ui-tabs-nav a')[1];\n\t\t\t\$(a).empty().html('<span>" . lang::get('LANG_Add_Occurrence') . "</span>');\n\t\t\tswitch(\"" . $args["on_save_occurrence_nav"] . "\"){\n\t\t\t\tcase \"list\":\n\t\t\t\t\ta = \$('ul.ui-tabs-nav a')[2];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"survey\":\n\t\t\t\t\ta = \$('ul.ui-tabs-nav a')[0];\n\t\t\t\t\t\$(a).click();\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n        } else {\n\t\t\tif(data.error){\n\t\t\t\tvar lastIndex = data.error.lastIndexOf('Validation error');\n    \t\t\tif (lastIndex != -1 && lastIndex  == (data.error.length - 16)){\n\t\t\t\t\tif(data.errors){\n\t\t\t\t\t\t// TODO translation\n\t\t\t\t\t\tfor (i in data.errors){\n\t\t\t\t\t\t\tvar label = \$('<p/>').addClass('inline-error').html(data.errors[i]);\n\t\t\t\t\t\t\tlabel.insertAfter('[name='+i+']');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmyScrollToError();\n\t\t\t\t\t\treturn;\n  \t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\talertIndiciaError(data);\n        }\n\t},\n    complete: function (){\n  \t\tjQuery('.loading-button').removeClass('loading-button');\n  \t}\n});\nsetAtlasStatus = function() {\n  if (jQuery(\"#occ-territorial:checked\").length == 0) {\n      jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val('');\n  } else {\n      if(jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val() == '') {\n        // Find the BB02 option (depends on the language what val it has)\n        var bb02;\n        jQuery.each(jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").find('option'), function(index, option) {\n          if (option.text.substr(0,4)=='BB02') {\n            bb02 = option.value;\n            return; // just from the each loop\n          }\n        });\n        jQuery(\"select[name=occAttr\\:" . $occurrence_atlas_code_id . "],select[name^=occAttr\\:" . $occurrence_atlas_code_id . "\\:]\").val(bb02);\n      }\n  }\n};\njQuery(\"#occ-territorial\").change(setAtlasStatus);\nif(\$.browser.msie) {\n    jQuery(\"#occ-territorial\").click(function() {\n        \$(this).change();\n    });\n}\n\n";
       if ($mode != 3) {
           data_entry_helper::$javascript .= "setAtlasStatus();\n";
       }
       // reset the atlas when not looking at a old occurrence.
       $r .= '</div>';
       // add map panel.
       $options = iform_map_get_map_options($args, $readAuth);
       $olOptions = iform_map_get_ol_options($args);
       // $options['layers'] = array('locationLayer', 'occListLayer');
       $options['searchLayer'] = 'false';
       $options['initialFeatureWkt'] = null;
       $options['proxy'] = '';
       $options['scroll_wheel_zoom'] = false;
       $options['width'] = 'auto';
       // TBD remove from arglist
       $r .= "<div class=\"mnhnl-btw-mappanel\">\n";
       $r .= data_entry_helper::map_panel($options, $olOptions);
       // for timing reasons, all the following has to be done after the map is loaded.
       // 1) feature selector for occurrence list must have the map present to attach the control
       // 2) location placer must have the location layer populated and the map present in
       //    order to zoom the map into the location.
       // 3) occurrence list feature adder must have map present in order to zoom into any
       //    current selection.
       data_entry_helper::$onload_javascript .= "\n\n\nlocationChange = function(obj){\n  locationLayer.destroyFeatures();\n  if(obj.value != ''){\n    jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location/\"+obj.value +\n      \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "\" +\n      \"&callback=?\", function(data) {\n            if (data.length>0) {\n              var parser = new OpenLayers.Format.WKT();\n              for (var i=0;i<data.length;i++)\n        {\n          if(data[i].centroid_geom){\n            " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n            feature.style = {label: data[i].name,\n\t\t\t\t\t\t     strokeColor: \"Green\",\n                             strokeWidth: 2,\n                             fillOpacity: 0};\n            centre = feature.geometry.getCentroid();\n            centrefeature = new OpenLayers.Feature.Vector(centre, {}, {label: data[i].name});\n            locationLayer.addFeatures([feature, centrefeature]);\n          }\n          if(data[i].boundary_geom){\n            " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n            feature.style = {strokeColor: \"Blue\", strokeWidth: 2};\n            locationLayer.addFeatures([feature]);\n          }\n          locationLayer.map.zoomToExtent(locationLayer.getDataExtent());\n        }\n      }\n    });\n     jQuery.getJSON(\"" . $svcUrl . "\" + \"/data/location\" +\n      \"?mode=json&view=detail&auth_token=" . $readAuth['auth_token'] . "&nonce=" . $readAuth["nonce"] . "&callback=?&parent_id=\"+obj.value, function(data) {\n            if (data.length>0) {\n              var parser = new OpenLayers.Format.WKT();\n              for (var i=0;i<data.length;i++)\n        {\n          if(data[i].centroid_geom){\n            " . self::readBoundaryJs('data[i].centroid_geom', $args['map_projection']) . "\n            locationLayer.addFeatures([feature]);\n          }\n          if(data[i].boundary_geom){\n            " . self::readBoundaryJs('data[i].boundary_geom', $args['map_projection']) . "\n            feature.style = {label: data[i].name,\n              labelAlign: \"cb\",\n              strokeColor: \"Blue\",\n                        strokeWidth: 2};\n            locationLayer.addFeatures([feature]);\n           }\n         }\n      }\n        });\n  }\n};\n// upload location initial value into map.\njQuery('#imp-location').each(function(){\n  locationChange(this);\n});\njQuery('#imp-location').unbind('change');\njQuery('#imp-location').change(function(){\n  locationChange(this);\n});\nvar selected = \$('#controls').tabs('option', 'selected');\n\n// Only leave the click control activated for edit/add occurrence tab.\nif(selected != 1){\n    locationLayer.map.editLayer.clickControl.deactivate();\n}\n\$('#controls').bind('tabsshow', function(event, ui) {\n        if(ui.index == 1)\n        {\n         locationLayer.map.editLayer.clickControl.activate();\n        }\n        else\n        {\n         locationLayer.map.editLayer.clickControl.deactivate();\n        }\n    }\n);\nactivateAddList = 1;\nthisOccID = " . $thisOccID . ";\naddListFeature = function(div, r, record, count) {\n  if(activateAddList == 0)\n    return;\n  if(r == count)\n    activateAddList = 0;\n    var parser = new OpenLayers.Format.WKT();\n    " . self::readBoundaryJs('record.geom', $args['map_projection']) . "\n    if(record.id != thisOccID || 1==" . ($surveyReadOnly ? 1 : 0) . " || 1==" . ($occReadOnly ? 1 : 0) . "){\n      feature.attributes.id = record.id;\n      feature.attributes.taxon = record.taxon;\n      feature.attributes.count = record.count;\n      occListLayer.addFeatures([feature]);\n      if(record.id == " . $thisOccID . "){\n        var bounds=feature.geometry.getBounds();\n        locationLayer.map.setCenter(bounds.getCenterLonLat());\n      }\n    } else {\n      locationLayer.map.editLayer.destroyFeatures();\n      locationLayer.map.editLayer.addFeatures([feature]);\n      var bounds=feature.geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      locationLayer.map.setCenter(centre);\n    }\n};\nhighlight = function(id){\n  if(id == " . $thisOccID . "){\n    if(occListLayer.map.editLayer.features.length > 0){\n      var bounds=occListLayer.map.editLayer.features[0].geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      occListLayer.map.setCenter(centre);\n      return;\n    }\n  }\n  for(var i = 0; i < occListLayer.features.length; i++){\n    if(occListLayer.features[i].attributes.id == id){\n      control.unselectAll();\n      var bounds=occListLayer.features[i].geometry.getBounds()\n      var centre=bounds.getCenterLonLat();\n      occListLayer.map.setCenter(centre);\n      control.select(occListLayer.features[i]);\n      return;\n    }\n  }\n}\n";
       if ($mode != 1) {
           data_entry_helper::$onload_javascript .= "\n\$('div#occ_grid').indiciaDataGrid('rpt:reports_for_prebuilt_forms/MNHNL/mnhnl_btw_list_occurrences', {\n    indiciaSvc: '" . $svcUrl . "',\n    dataColumns: ['taxon', 'territorial', 'count'],\n    reportColumnTitles: {taxon : '" . lang::get('LANG_Species') . "', territorial : '" . lang::get('LANG_Territorial') . "', count : '" . lang::get('LANG_Count') . "'},\n    actionColumns: {'" . lang::get('LANG_Show') . "' : \"" . url('node/' . $node->nid, array('query' => 'occurrence_id=£id£')) . "\",\n            '" . lang::get('LANG_Highlight') . "' : \"script:highlight(£id£);\"},\n    auth : { nonce : '" . $readAuth['nonce'] . "', auth_token : '" . $readAuth['auth_token'] . "'},\n    parameters : { survey_id : '" . $args['survey_id'] . "',\n            parent_id : '" . $parentSample['sample:id'] . "',\n            territorial_attr_id : '" . $occurrence_territorial_id . "',\n            count_attr_id : '" . $occurrence_count_id . "'},\n    itemsPerPage : 12,\n    callback : addListFeature ,\n    cssOdd : ''\n  });\n\n// activateAddList = 0;\n\n";
       }
       $r .= "</div><div><form><input id=\"return-to-main\" type=\"button\" value=\"" . lang::get('LANG_Return') . "\" onclick=\"window.location.href='" . url('node/' . $node->nid, array('query' => 'Main')) . "'\"></form></div></div>\n";
       if (method_exists(get_called_class(), 'getTrailerHTML')) {
           $r .= call_user_func(array(get_called_class(), 'getTrailerHTML'), $args);
       }
       return $r;
   }
 /**
  * Private function that builds a parameters form according to a parameterRequest recieved
  * when calling a report. If the autoParamsForm is false then an empty string is returned.
  * @param $response
  * @return string HTML for the form.
  */
 private static function get_report_grid_parameters_form($response, $options, $params)
 {
     if ($options['autoParamsForm'] || $options['paramsOnly']) {
         // get the url parameters. Don't use $_GET, because it contains any parameters that are not in the
         // URL when search friendly URLs are used (e.g. a Drupal path node/123 is mapped to index.php?q=node/123
         // using Apache mod_alias but we don't want to know about that)
         $reloadUrl = self::get_reload_link_parts();
         $r = '';
         if ($options['completeParamsForm'] == true) {
             $r .= '<form action="' . $reloadUrl['path'] . '" method="get" id="' . $options['id'] . '-params">' . "\n";
             $r .= '<fieldset><legend>' . lang::get('Report Parameters') . '</legend>';
         }
         // Output any other get parameters from our URL as hidden fields
         foreach ($reloadUrl['params'] as $key => $value) {
             // since any param will be from a URL it could be encoded. So we don't want to double encode if they repeatedly
             // run the report.
             $value = urldecode($value);
             // ignore any parameters that are going to be in the grid parameters form
             if (substr($key, 0, 6) != 'param-') {
                 $r .= "<input type=\"hidden\" value=\"{$value}\" name=\"{$key}\" />\n";
             }
         }
         foreach ($response['parameterRequest'] as $key => $info) {
             // Skip parameters if we have been asked to ignore them
             if (isset($options['ignoreParams']) && in_array($key, $options['ignoreParams'])) {
                 continue;
             }
             $ctrlOptions = array('label' => $info['display'], 'helpText' => $info['description'], 'fieldname' => 'param-' . (isset($options['id']) ? $options['id'] : '') . "-{$key}");
             // If this parameter is in the URL or post data, put it in the control
             if (isset($params[$key])) {
                 $ctrlOptions['default'] = $params[$key];
             }
             if ($info['datatype'] == 'lookup' && isset($info['population_call'])) {
                 // population call is colon separated, of the form direct|report:table|view|report:idField:captionField
                 $popOpts = explode(':', $info['population_call']);
                 // @todo Support report calls to populate the lookup
                 $ctrlOptions = array_merge($ctrlOptions, array('table' => $popOpts[1], 'valueField' => $popOpts[2], 'captionField' => $popOpts[3], 'blankText' => '<' . lang::get('please select') . '>', 'extraParams' => $options['readAuth']));
                 $r .= data_entry_helper::select($ctrlOptions);
             } elseif ($info['datatype'] == 'lookup' && isset($info['lookup_values'])) {
                 // Convert the lookup values into an associative array
                 $lookups = explode(',', $info['lookup_values']);
                 $lookupsAssoc = array();
                 foreach ($lookups as $lookup) {
                     $lookup = explode(':', $lookup);
                     $lookupsAssoc[$lookup[0]] = $lookup[1];
                 }
                 $ctrlOptions = array_merge($ctrlOptions, array('blankText' => '<' . lang::get('please select') . '>', 'lookupValues' => $lookupsAssoc));
                 $r .= data_entry_helper::select($ctrlOptions);
             } else {
                 $r .= data_entry_helper::text_input($ctrlOptions);
             }
         }
         if ($options['completeParamsForm'] == true) {
             $r .= '<input type="submit" value="' . lang::get($options['paramsFormButtonCaption']) . '"/>' . "\n";
             $r .= "</fieldset></form>\n";
         }
         return $r;
     } else {
         return $r;
     }
 }
 /**
  * Return the generated form output.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  * This array always contains a value for language.
  * @param object $node The Drupal node object.
  * @param array $response When this form is reloading after saving a submission, contains the response from the service call.
  * Note this does not apply when redirecting (in this case the details of the saved object are in the $_GET data).
  * @return Form HTML.
  */
 public static function get_form($args, $node, $response = null)
 {
     if (!hostsite_get_user_field('indicia_user_id')) {
         return 'Please ensure that you\'ve filled in your surname on your user profile before creating or editing groups.';
     }
     self::createBreadcrumb($args);
     iform_load_helpers(array('report_helper', 'map_helper'));
     $args = array_merge(array('include_code' => false, 'include_dates' => false, 'include_logo_controls' => true, 'include_sensitivity_controls' => true, 'include_report_filter' => true, 'include_linked_pages' => true, 'include_private_records' => false, 'include_administrators' => false, 'include_members' => false, 'filter_types' => '{"":"what,where,when","Advanced":"source,quality"}', 'indexed_location_type_ids' => '', 'other_location_type_ids' => '', 'data_inclusion_mode' => 'choose'), $args);
     $args['filter_types'] = json_decode($args['filter_types'], true);
     $reloadPath = self::getReloadPath();
     data_entry_helper::$website_id = $args['website_id'];
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     if (!empty($_GET['group_id'])) {
         self::loadExistingGroup($_GET['group_id'], $auth, $args);
     }
     // maintain compatibility with form settings from before group type became multiselect.
     if (empty($args['group_type'])) {
         $args['group_type'] = array();
     } elseif (!is_array($args['group_type'])) {
         $args['group_type'] = array($args['group_type']);
     }
     if (count($args['group_type']) === 1) {
         $response = data_entry_helper::get_population_data(array('table' => 'termlists_term', 'extraParams' => $auth['read'] + array('id' => $args['group_type'][0])));
         self::$groupType = strtolower($response[0]['term']);
     }
     self::$groupType = lang::get(self::$groupType);
     $r = "<form method=\"post\" id=\"entry_form\" action=\"{$reloadPath}\" enctype=\"multipart/form-data\">\n";
     $r .= '<fieldset><legend>' . lang::get('Fill in details of your {1} below', self::$groupType) . '</legend>';
     $r .= $auth['write'] . "<input type=\"hidden\" id=\"website_id\" name=\"website_id\" value=\"" . $args['website_id'] . "\" />\n";
     $r .= data_entry_helper::hidden_text(array('fieldname' => 'group:id'));
     // if a fixed choice of group type, can use a hidden input to put the value in the form.
     if (count($args['group_type']) === 1) {
         $r .= '<input type="hidden" name="group:group_type_id" value="' . $args['group_type'][0] . '"/>';
     }
     if (!empty(data_entry_helper::$entity_to_load['group:title'])) {
         hostsite_set_page_title(lang::get('Edit {1}', data_entry_helper::$entity_to_load['group:title']));
     }
     $r .= data_entry_helper::text_input(array('label' => lang::get('{1} name', ucfirst(self::$groupType)), 'fieldname' => 'group:title', 'validation' => array('required'), 'class' => 'control-width-6', 'helpText' => lang::get('Provide the full title of the {1}', self::$groupType)));
     if ($args['include_code']) {
         $r .= data_entry_helper::text_input(array('label' => lang::get('Code'), 'fieldname' => 'group:code', 'class' => 'control-width-4', 'helpText' => lang::get('Provide a code or abbreviation identifying the {1}', self::$groupType)));
     }
     $r .= data_entry_helper::textarea(array('label' => ucfirst(lang::get('{1} description', self::$groupType)), 'fieldname' => 'group:description', 'helpText' => lang::get('LANG_Description_Field_Instruct', self::$groupType), 'class' => 'control-width-6'));
     // If adding a new group which should have a parent group of some type or other, but no parent
     // group is specified in the from_group_id parameter, then let the user pick a group to link as the parent.
     if (empty($_GET['group_id']) && !empty($args['parent_group_type']) && !empty($args['parent_group_relationship_type']) && empty($_REQUEST['from_group_id'])) {
         // There should be a parent group, but none provided, so allow the user to pick one.
         $r .= data_entry_helper::select(array('label' => ucfirst(lang::get('{1} parent', self::$groupType)), 'fieldname' => 'from_group_id', 'table' => 'groups_user', 'captionField' => 'title', 'valueFields' => 'group_id', 'extraParams' => $auth['read'] + array('group_type_id' => $args['parent_group_type'], 'user_id' => hostsite_get_user_field('indicia_user_id'), 'view' => 'detail'), 'validation' => array('required'), 'blankText' => lang::get('<please select>')));
     }
     if (count($args['group_type']) !== 1) {
         $params = array('termlist_external_key' => 'indicia:group_types', 'orderby' => 'sortorder,term');
         if (!empty($args['group_type'])) {
             $params['query'] = json_encode(array('in' => array('id' => array_values($args['group_type']))));
         }
         $r .= data_entry_helper::select(array('label' => ucfirst(lang::get('{1} type', self::$groupType)), 'fieldname' => 'group:group_type_id', 'validation' => array('required'), 'table' => 'termlists_term', 'valueField' => 'id', 'captionField' => 'term', 'extraParams' => $auth['read'] + $params, 'class' => 'control-width-4', 'blankText' => lang::get('<please select>'), 'helpText' => lang::get('What sort of {1} is it?', self::$groupType)));
     }
     $r .= self::groupLogoControl($args);
     $r .= self::joinMethodsControl($args);
     if ($args['include_sensitivity_controls']) {
         $r .= data_entry_helper::checkbox(array('label' => lang::get('Show records at full precision'), 'fieldname' => 'group:view_full_precision', 'helpText' => lang::get('Any sensitive records added to the system are normally shown blurred to a lower grid reference precision. If this box ' . 'is checked, then group members can see sensitive records explicitly posted for the {1} at full precision.', self::$groupType)));
     }
     $r .= self::dateControls($args);
     if ($args['include_private_records']) {
         $r .= data_entry_helper::checkbox(array('label' => lang::get('Records are private'), 'fieldname' => 'group:private_records', 'helpText' => lang::get('Tick this box if you want to withold the release of the records from this {1} until a ' . 'later point in time, e.g. when a project is completed.', self::$groupType)));
         // If an existing group with private records, then we might need to display a message warning the user about releasing the records.
         // Initially hidden, we use JS to display it when appropriate.
         if (!empty(data_entry_helper::$entity_to_load['group:id']) && data_entry_helper::$entity_to_load['group:private_records'] === 't') {
             $r .= '<p class="warning" style="display: none" id="release-warning">' . lang::get('You are about to release the records belonging to this group. Do not proceed unless you intend to do this!') . '</p>';
         }
     }
     $r .= self::memberControls($args, $auth);
     $r .= '</fieldset>';
     $r .= self::reportFilterBlock($args, $auth, $hiddenPopupDivs);
     $r .= self::inclusionMethodControl($args);
     $r .= self::formsBlock($args, $auth, $node);
     // auto-insert the creator as an admin of the new group, unless the admins are manually specified
     if (!$args['include_administrators'] && empty($_GET['group_id'])) {
         $r .= '<input type="hidden" name="groups_user:admin_user_id[]" value="' . hostsite_get_user_field('indicia_user_id') . '"/>';
     }
     $r .= '<input type="hidden" name="groups_user:administrator" value="t"/>';
     $r .= '<input type="submit" class="indicia-button" id="save-button" value="' . (empty(data_entry_helper::$entity_to_load['group:id']) ? lang::get('Create {1}', self::$groupType) : lang::get('Update {1} settings', self::$groupType)) . "\" />\n";
     $r .= '</form>';
     $r .= $hiddenPopupDivs;
     data_entry_helper::enable_validation('entry_form');
     // JavaScript to grab the filter definition and store in the form for posting when the form is submitted
     data_entry_helper::$javascript .= "\r\n\$('#entry_form').submit(function() {\r\n  \$('#filter-title-val').val('" . lang::get('Filter for user group') . " ' + \$('#group\\\\:title').val() + ' ' + new Date().getTime());\r\n  \$('#filter-def-val').val(JSON.stringify(indiciaData.filter.def));\r\n});\n";
     // for existing groups, prevent removal of yourself as a member. Someone else will have to do this for you so we don't orphan groups.
     if (!empty(data_entry_helper::$entity_to_load['group:id'])) {
         data_entry_helper::$javascript .= "\$('#groups_user\\\\:admin_user_id\\\\:sublist input[value=" . hostsite_get_user_field('indicia_user_id') . "]').closest('li').children('span').remove();\n";
     }
     return $r;
 }
 /**
  * Return the generated output for the main sample tab.
  * @param array $args List of parameter values passed through to the form depending on how the form has been configured.
  *                    This array always contains a value for language.
  * @param integer $nid The Drupal node object's ID.
  * @param object $auth The full read-write authorisation.
  * @return HTML.
  */
 private static function get_sample_tab($args, $nid, $auth, $attributes, &$packageAttr)
 {
     global $user;
     if (isset(data_entry_helper::$entity_to_load['sample:date']) && preg_match('/^(\\d{4})/', data_entry_helper::$entity_to_load['sample:date'])) {
         // Date has 4 digit year first (ISO style) - convert date to expected output format
         // @todo The date format should be a global configurable option. It should also be applied to reloading of custom date attributes.
         $d = new DateTime(data_entry_helper::$entity_to_load['sample:date']);
         data_entry_helper::$entity_to_load['sample:date'] = $d->format('d/m/Y');
     }
     // are there any option overrides for the custom attributes?
     if (isset($args['custom_attribute_options']) && $args['custom_attribute_options']) {
         $blockOptions = get_attr_options_array_with_user_data($args['custom_attribute_options']);
     } else {
         $blockOptions = array();
     }
     $systems = array();
     $list = explode(',', str_replace(' ', '', $args['spatial_systems']));
     foreach ($list as $system) {
         $systems[$system] = lang::get("sref:{$system}");
     }
     $options = iform_map_get_map_options($args, $auth['read']);
     $olOptions = iform_map_get_ol_options($args);
     if (!empty(data_entry_helper::$entity_to_load['sample:wkt'])) {
         $options['initialFeatureWkt'] = data_entry_helper::$entity_to_load['sample:wkt'];
     }
     if (!isset($options['standardControls'])) {
         $options['standardControls'] = array('layerSwitcher', 'panZoomBar');
     }
     $options['tabDiv'] = 'sample';
     // we pass through the read auth. This makes it possible for the get_submission method to authorise against the warehouse
     // without an additional (expensive) warehouse call, so it can get subsample details.
     $r = '<div id="sample">' . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . get_user_profile_hidden_inputs($attributes, $args, isset(data_entry_helper::$entity_to_load['sample:id']), $auth['read']) . data_entry_helper::text_input(array('label' => lang::get('Location Name'), 'fieldname' => 'sample:location_name', 'class' => 'control-width-5', 'validation' => array('required'))) . data_entry_helper::date_picker(array('label' => lang::get('Date'), 'fieldname' => 'sample:date')) . self::_build_package_control($args, $packageAttr) . get_attribute_html($attributes, $args, array('extraParams' => $auth['read']), null, $blockOptions) . data_entry_helper::textarea(array('fieldname' => 'sample:comment', 'label' => lang::get('Overall comment'))) . data_entry_helper::sref_and_system(array('label' => lang::get('Grid Reference'), 'systems' => $systems)) . '<p class="ui-state-highlight page-notice ui-corner-all">' . t('Use the search box to find a nearby town or village, then drag the map to pan and click on the map to set the centre grid reference of the transect. ' . 'Alternatively if you know the grid reference you can enter it in the Grid Ref box above: this will then be drawn automatically on the map.') . '</p>' . (isset(data_entry_helper::$entity_to_load['sample:id']) ? '' : data_entry_helper::georeference_lookup(array('label' => lang::get('Search for place'), 'driver' => $args['georefDriver'], 'georefPreferredArea' => $args['georefPreferredArea'], 'georefCountry' => $args['georefCountry'], 'georefLang' => $args['language'], 'readAuth' => $auth['read']))) . map_helper::map_panel($options, $olOptions) . (self::$readOnly ? '' : '<br/><input type="submit" value="' . lang::get('Save') . '" title="' . lang::get('Saves any data entered across all the tabs.') . '" />') . '</div>';
     return $r;
 }
 /**
  * Helper function to output the HTML for a forgotten password form widget.
  * This is a composite control which presents a configurable collection of input and
  * display controls to support a forgotten password request on a web page.
  * The control is wrapped with a <form> element but you need to specify where the 
  * request should be sent for processing.
  *
  * All the elements in the control are wrapped within a <form> with an id of indicia-forgotten-password-control
  * so if you don't wish to specify classes on all the sub elements you can style them using
  * CSS selectors such as
  * #indicia-forgotten-password-control input[type="text"] 
  *
  * @param array $options Options array with the following possibilities:<ul>
  * <li><b>action_url</b><br/>
  * Required. String defining the URL which the login data will be sent to for processing.</li>
  * <li><b>control_method</b><br/>
  * Optional. String defining the http method (either post or get) to be used to send the data for processing. 
  * Default is 'post'.</li>
  * <li><b>control_id</b><br/>
  * Optional. String defining the id for the enclosing <form>. Default is 'indicia-forgotten-password-control'.</li>
  * <li><b>show_fieldset</b><br/>
  * Optional. Boolean defining if the fields will be contained in a fieldset. Default is false.</li>
  * <li><b>fieldset_class</b><br/>
  * Optional. Only relevant if show_fieldset is true. CSS class names to use on the fieldset element.
  * Default is to omit class attribute.</li>
  * <li><b>legend_label</b><br/>
  * Optional. Only relevant if show_fieldset is true. The text to show on the fieldset legend.
  * Default is 'Forgotten password user details'. Todo: make this default language aware?</li>
  * <li><b>login_text</b><br/>
  * Optional. Explainatory text to be shown before the fields. If 'show_fieldset' is true,
  * the text will be inside the fieldset. 
  * Default is <i>'You may enter either your user name or your email address in the field below, 
  * and an email will be sent to you. In this email will be a link to a webpage which will 
  * allow you to enter a new password. This ensures that only a person with access to your 
  * registered email account will be able to change your password.'</i>.  Todo: make this default language aware?</li>
  * <li><b>name_label</b><br/>
  * Optional. Text for the username field label. Defaults to 'User Name or Email Address'.
  * Todo: make this default language aware?</li>
  * <li><b>name_field</b><br/>
  * Optional. Name for the username HTML input field. Defaults to 'userid'.</li>
  * <li><b>name_class</b><br/>
  * Optional. CSS class names to use on the username HTML text input element.
  * Default is an empty class attribute.</li>
  * <li><b>login_uri</b><br/>a
  * Optional. URI to return to the user login page.
  * If supplied, a login link will be shown below the submit button.
  * Default is not to display a login link.</li>
  * <li><b>login_label</b><br/>
  * Optional. Text to display on the optional link back to the login page.
  * Ignored unless the login_uri is supplied.
  * Defaults to 'Return to the login page.'.
  * Todo: make this default language aware?</li>
  * <li><b>links_class</b><br/>
  * Optional. CSS class names to use on the optional 'return to login' link if required.
  * Default is to omit the class attribute.</li>
  * <li><b>button_label</b><br/>
  * Optional. Text to show on the form submit button. Defaults to 'Request Forgotten Password Email'.
  * Todo: make this default language aware?</li>
  * <li><b>button_field</b><br/>
  * Optional. Name for the submit button field. Defaults to 'password_email_submit'.</li>
  * <li><b>button_class</b><br/>
  * Optional. CSS class names to use on the login submit button.
  * Default is to omit the class attribute.</li>
  * </ul>
  *
  * @return string HTML to insert into the page for the login control.
  */
 public static function forgotten_password_control($options = array())
 {
     $r = '';
     $method = array_key_exists('control_method', $options) ? ' method="' . $options['control_method'] . '"' : ' method="post"';
     $id = array_key_exists('control_id', $options) ? ' id="' . $options['control_id'] . '"' : ' id="indicia-forgotten-password-control"';
     $action = ' action="' . $options['action_url'] . '"';
     $r .= '<form' . $id . $method . $action . '>' . "\n";
     $fieldset = false;
     if (array_key_exists('show_fieldset', $options) && $options['show_fieldset']) {
         $fieldset = true;
     }
     if ($fieldset) {
         $class = array_key_exists('fieldset_class', $options) ? ' class="' . $options['fieldset_class'] . '"' : '';
         $r .= str_replace('{class}', $class, '<fieldset>{class}') . "\n";
         $legend_label = array_key_exists('legend_label', $options) ? $options['legend_label'] : 'Forgotten password user details';
         $r .= '<legend>' . $legend_label . '</legend>' . "\n";
     }
     $text = array_key_exists('forgotten_password_text', $options) ? $options['forgotten_password_text'] : 'You may enter either your user name or your email address in the field below, ' . 'and an email will be sent to you. In this email will be a link to a webpage which will ' . 'allow you to enter a new password. This ensures that only a person with access to your ' . 'registered email account will be able to change your password.';
     $r .= '<p>' . $text . '</p>' . "\n";
     $label = array_key_exists('name_label', $options) ? $options['name_label'] : 'User Name or Email Address';
     $fieldname = array_key_exists('name_field', $options) ? $options['name_field'] : 'userid';
     $class = array_key_exists('name_class', $options) ? $options['name_class'] : '';
     $r .= data_entry_helper::text_input(array('label' => $label, 'fieldname' => $fieldname, 'class' => $class));
     if ($fieldset) {
         $r .= '</fieldset>' . "\n";
     }
     $label = array_key_exists('button_label', $options) ? $options['button_label'] : 'Request Forgotten Password Email';
     $fieldname = array_key_exists('button_field', $options) ? $options['button_field'] : 'password_email_submit';
     $class = array_key_exists('button_class', $options) ? ' class="' . $options['button_class'] . '"' : '';
     $r .= '<input type="submit" name="' . $fieldname . '" id="' . $fieldname . '" value="' . $label . '"' . str_replace('{class}', $class, '{class} />') . "\n";
     if (array_key_exists('login_uri', $options)) {
         $label = array_key_exists('login_label', $options) ? $options['login_label'] : 'Return to the login page.';
         $class = array_key_exists('links_class', $options) ? ' class="' . $options['links_class'] . '"' : '';
         $r .= '<br /><a href="' . $options['login_uri'] . '"' . $class . '>' . $label . '</a>' . "\n";
     }
     $r .= '</form>' . "\n";
     return $r;
 }