/**
  * 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 integer $nid The Drupal node object's ID.
  * @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, $nid, $response = null)
 {
     global $user;
     //    if (!function_exists('module_exists') || !module_exists('iform_ajaxproxy'))
     //      return 'This form must be used in Drupal with the Indicia AJAX Proxy module enabled.';
     if (!function_exists('module_exists') || !module_exists('easy_login')) {
         return 'FATAL INTERNAL CONFIGURATION ERROR: This form must be used in Drupal with the Easy Login module enabled.';
     }
     if (!function_exists('module_exists') || !module_exists('species_packages')) {
         return 'FATAL INTERNAL CONFIGURATION ERROR: This form must be used in Drupal with the custom species_packages module enabled.';
     }
     // assuming easy login
     $userId = hostsite_get_user_field('indicia_user_id');
     if (empty($userId)) {
         return '<p>FATAL ERROR: Could not identify user.</p>';
     }
     // something is wrong
     $r = isset($response['error']) ? data_entry_helper::dump_errors($response) : '';
     iform_load_helpers(array('map_helper', 'report_helper'));
     $auth = data_entry_helper::get_read_write_auth($args['website_id'], $args['password']);
     self::$sampleId = null;
     self::$occurrenceId = false;
     if (isset(data_entry_helper::$entity_to_load['sample:id']) && data_entry_helper::$entity_to_load['sample:id'] != "") {
         // have just posted a (failed) edit to an existing parent sample.
         self::$sampleId = data_entry_helper::$entity_to_load['sample:id'];
     } else {
         if (isset(data_entry_helper::$entity_to_load['sample:survey_id']) && data_entry_helper::$entity_to_load['sample:survey_id'] != "") {
             // have just posted a (failed) edit to a new parent sample.
             self::$sampleId = null;
         } else {
             if (isset($response['outer_id'])) {
                 // have just successfully posted either a new parent sample, or an update to an existing one.
                 self::$sampleId = $response['outer_id'];
                 data_entry_helper::load_existing_record($auth['read'], 'sample', self::$sampleId, 'detail', false, true);
                 if (!isset($_POST['force_page_reload'])) {
                     return self::get_success_page($args, $auth, $response['outer_id']);
                 }
                 drupal_set_message(lang::get('The Transect you have just saved specified the Species Package to be used. The Transect has been reloaded below, and the Species tab now contains the Species Grid for the Species Package, which will allow you to enter the species data.'));
             } else {
                 if (isset($_GET['sample_id']) && intval($_GET['sample_id']) == $_GET['sample_id']) {
                     self::$sampleId = $_GET['sample_id'];
                     data_entry_helper::load_existing_record($auth['read'], 'sample', self::$sampleId, 'detail', false, true);
                 } else {
                     self::$sampleId = null;
                 }
             }
         }
     }
     if (isset($_GET['occurrence_id']) && intval($_GET['occurrence_id']) == $_GET['occurrence_id']) {
         self::$occurrenceId = $_GET['occurrence_id'];
         if (self::$sampleId == null) {
             // fill in the sample_id from the occurrence if don't already have it
             $occurrence = data_entry_helper::get_population_data(array('table' => 'occurrence', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => self::$occurrenceId)));
             // this throws an error exception if any error.
             // this gives
             if (count($occurrence) == 1) {
                 $subsample = data_entry_helper::get_population_data(array('table' => 'sample', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $occurrence[0]['sample_id'])));
                 if (count($subsample) == 1) {
                     self::$sampleId = $subsample[0]['parent_id'];
                     data_entry_helper::load_existing_record($auth['read'], 'sample', self::$sampleId, 'detail', false, true);
                 }
             }
         }
     }
     if (isset(data_entry_helper::$entity_to_load['sample:survey_id']) && data_entry_helper::$entity_to_load['sample:survey_id'] != $args['survey_id']) {
         drupal_set_message(t('The data entry form you have selected to use is configured for a particular survey:') . ' ID ' . $args['survey_id'] . ' ' . t('The sample you have chosen to view is not assigned to this survey.'), 'error');
         drupal_goto('<front>');
     }
     if (isset(data_entry_helper::$entity_to_load['sample:parent_id']) && data_entry_helper::$entity_to_load['sample:parent_id'] != '' && data_entry_helper::$entity_to_load['sample:parent_id'] !== null) {
         drupal_set_message(t('An attempt has been made to access a non top level sample.'));
         drupal_goto('<front>');
     }
     $survey = data_entry_helper::get_population_data(array('table' => 'survey', 'extraParams' => $auth['read'] + array('view' => 'detail', 'id' => $args['survey_id'], 'website_id' => $args['website_id'])));
     if (count($survey) != 1) {
         return "FATAL INTERNAL CONFIGURATION ERROR: Supplied form survey_id value (" . $args['survey_id'] . ") is not valid survey for this website (" . $args['website_id'] . ").<br/>";
     }
     $surveyTitle = $survey[0]['title'];
     if (self::$sampleId == null) {
         $packages = species_packages_get_packages($user->uid, $args['survey_id']);
         if ($packages === false || is_array($packages) && count($packages) == 0) {
             drupal_set_message(t('You have not yet selected a species package that is compatible with survey') . ' : &quot;' . $surveyTitle . '&quot;', 'error');
             drupal_set_message(str_replace('#link#', '<a href="' . url('user/' . $user->uid . '/edit') . '">' . t('this link') . '</a>', t('You can set the species package on your user account page, which can be accessed using #link#. If you have already selected a species package, and wish to add another or wish to change your selection, please contact your Hub Manager.')));
             drupal_goto('<front>');
         }
         self::$readOnly = false;
     } else {
         self::$readOnly = !isset($response['error']) && data_entry_helper::$entity_to_load['sample:created_by_id'] != hostsite_get_user_field('indicia_user_id') && (empty($args['edit_permission']) || !hostsite_user_has_permission($args['edit_permission']));
     }
     if (self::$readOnly) {
         drupal_set_message(t('In order to save changes to existing records, you must either be the creator of the entry, or have been given the appropriate permission.'));
     }
     // In readonly mode, the forms are replaced by divs and there are no save buttons.
     //    $r .= '<span style="display:none;">'.print_r($packages,true).'</span>';
     //	$r .= '<span style="display:none;">'.print_r(array($user->uid, $args, $packageAttr), true).'</span>' .
     $attributes = data_entry_helper::getAttributes(array('id' => self::$sampleId, 'valuetable' => 'sample_attribute_value', 'attrtable' => 'sample_attribute', 'key' => 'sample_id', 'fieldprefix' => 'smpAttr', 'extraParams' => $auth['read'], 'survey_id' => $args['survey_id'], 'sample_method_id' => $args['transect_level_sample_method_id']));
     $packageAttr = self::extract_package_attr($attributes, true);
     if (!$packageAttr) {
         return "FATAL INTERNAL CONFIGURATION ERROR: This form must be used with a survey which has a &#x22;Species Package&#x22; sample attribute defined for it (integer, required on parent).<br/>";
     }
     self::_remove_options($args);
     $r .= (self::$readOnly ? '<div id="data_entry_form">' : '<form method="post" id="data_entry_form">' . $auth['write']) . '<input type="hidden" name="website_id" value="' . $args['website_id'] . '"/>' . (isset(data_entry_helper::$entity_to_load['sample:id']) ? '<input type="hidden" name="sample:id" value="' . data_entry_helper::$entity_to_load['sample:id'] . '"/>' : '') . '<input type="hidden" name="sample:survey_id" value="' . $args['survey_id'] . '"/>' . '<input type="hidden" name="sample:sample_method_id" value="' . $args['transect_level_sample_method_id'] . '" />';
     if (isset(data_entry_helper::$entity_to_load['sample:id'])) {
         $r .= "<h2>" . data_entry_helper::$entity_to_load['sample:location_name'] . " on " . data_entry_helper::$entity_to_load['sample:date'] . (self::$readOnly ? ' ' . lang::get('READ ONLY') : '') . "</h2>\n";
     }
     $r .= "<div id=\"tabs\">\n";
     $tabs = array();
     $smpTab = self::get_sample_tab($args, $nid, $auth, $attributes, $packageAttr);
     $mediaTab = self::get_media_tab($args, $nid, $auth);
     $occTab = self::get_occurrences_tab($args, $nid, $auth, $packageAttr);
     // Note this messes with the templates, so done last just in case
     $tabs['#sample'] = t($args['sample_tab_label']);
     if ($occTab != "") {
         $tabs['#occurrences'] = t($args['occurrence_tab_label']);
     }
     if ($mediaTab != "") {
         $tabs['#media'] = t($args['media_tab_label']);
     }
     $r .= data_entry_helper::tab_header(array('tabs' => $tabs));
     data_entry_helper::enable_tabs(array('divId' => 'tabs', 'style' => 'Tabs', 'active' => $occTab != "" && (self::$occurrenceId || self::$sampleId) ? 'occurrences' : 'sample'));
     $r .= $smpTab . $occTab . $mediaTab . '</div>' . (self::$readOnly ? '</div>' : '</form>');
     if (!self::$readOnly) {
         // custom version of enable validation code
         data_entry_helper::$validated_form_id = 'data_entry_form';
         data_entry_helper::$javascript .= "indiciaData.validatedFormId = '" . data_entry_helper::$validated_form_id . "';\n";
         // prevent double submission of the form
         data_entry_helper::$javascript .= "\$('#data_entry_form').submit(function(e) {\r\n  if (typeof \$('#data_entry_form').valid === 'undefined' || \$('#data_entry_form').valid()) {\r\n    if (typeof indiciaData.formSubmitted==='undefined' || !indiciaData.formSubmitted) {\r\n      \$('<p>" . lang::get('Please wait whilst the data is saved.') . "</p>').dialog({ title: '" . lang::get('Saving Data') . "', buttons: { '" . lang::get('OK') . "' : function() { \$( this ).dialog('close'); } } });\r\n      indiciaData.formSubmitted=true;\r\n    } else {\r\n      e.preventDefault();\r\n      return false;\r\n    }\r\n  }\r\n});\n";
         data_entry_helper::add_resource('validation');
     }
     return $r;
 }
 /** 
  * Works out the list of download format options available to the user. This depends on the 
  * permissions settings in the form configuration
  * @param array $args Form parameters
  * @return array Associative array of download formats
  */
 private static function get_download_formats($args)
 {
     $r = array();
     foreach ($args as $arg => $value) {
         if ($value && preg_match('/^([a-z_]+)_format_permission$/', $arg, $matches) && hostsite_user_has_permission($value)) {
             $r[$matches[1]] = lang::get("format_{$matches['1']}");
         }
     }
     return $r;
 }