<?php

/**
 *		sabreTools Module for plugin to Drupal 7 Framework
 *
 *		Common utility functions for Sabre Software
 *
 *    directly include into code files as needed
*/


/*
 *  _st_get_site_version()
 *
 *  retrieves the current source code version, based on the version file in the root dir
 *  "version.1-2.070-1.1.28"
 * <p class="vh-version"><?php print _st_get_version(); ?></p>
 */
function _st_get_site_version() {
  $versions = glob("version.*");
  if (count($versions) > 1) { rsort($versions); }
  return (isset($versions[0]) ? $versions[0] : "");
}


/*    _st_set_server_timezone()
 *
 *    pushes the server timezone setting to the browser Drupal.settings.sabreTools area
 *    for reference during time handling operations in the browser
 */
function _st_add_js_timezone($user_tz = True) {
  //moment js libs
  //$tz = variable_get('date_default_timezone', date_default_timezone_get());
  //$tz = "America/New_York";    // DEBUG
  $tz = _st_get_timezone($user_tz);
  drupal_add_js(array('sabreTools' => array('server_timezone' => $tz)), 'setting');

  $sabreTools = drupal_get_path('module', 'sabreTools');
  drupal_add_js($sabreTools . '/js/vendor/moment/moment.min.js');
  drupal_add_js($sabreTools . '/js/vendor/moment/moment-timezone.min.js');
  drupal_add_js($sabreTools . '/js/vendor/moment/moment-timezone-data.js');
}

/*
 *		_st_generate_base_no()
 *
 * 		prep a new report Base No for display -- doesn't get calculated until submit
 *		$report_type[RT] = DR | ENG | SD | TC | EL
 * 		RTXX-XXX-XX
 * 		RTXX == Current 2 digit year (ex:  DR13 )
 * 		-XXX- == Julian date (the nth day out of 365 for the current day this year, ex: 010, Jan 10)
 * 		-XX == RT count for the current day (nth report of the day, ex:  05, 5th report filed for the day).
 */
function _st_generate_report_base_no($report_type, $sim_dev_id = '') {

	$report_type = strtoupper($report_type);
	switch ($report_type) {
		case 'DR':
		case 'ENG':
		case 'SD':
		case 'TC':
    case 'QTG':
			// date format ( z == nth day of the current year (zero-indexed), y == 2 digit year)
			$newdatestamp = strtotime('+1 day', time());
			return sprintf('%s%s-%03u-', $report_type, date('y', $newdatestamp), date('z', $newdatestamp));
    case 'EL':
      // diff from the other reports
      // EL--YY-I--ZZZZ
      // date format ( y == 2 digit year, i== $sim_dev_id [optional], zzzz== elog#)
      // if present, appends '-' at end
      $dev_id = ( strlen($sim_dev_id) ? $sim_dev_id . '-' : '' );
			return sprintf('%s--%s-%s', $report_type, date('y'), $dev_id);
		default:
			return '';  // FAIL
	}
}

/*
  *	_st_generate_report_no($report_type, $report_no_base)
  *
	* calculate a new Report No
	* $report_type[RT] = DR | ENG | SD | TC | EL
	* RTXX-XXX-XX
	* RTXX == Current 2 digit year (ex:  DR13 )
	* -XXX- == Julian date (the nth day out of 365 for the current day this year, ex: 010, Jan 10)
	* -XX == RT count for the current day (nth report of the day, ex:  05, 5th report filed for the day).
 */
function _st_generate_report_no($report_type, $report_no_base) {

	$search_key = $report_no_base . '%';  //append wildcard to dr_no for searching purposes.
	$rpt_count = 0;
	$report_type = strtoupper($report_type);
  $last_rpt_no = '';
	$sql = '';
  $new_report_no = '';

	switch($report_type) {
		case 'DR':
			//----------------- Calculate DR No ------------------------
			// find the highest numbered DR for today
			$sql = "SELECT dr_no FROM {qms_discrepancy_log}
							WHERE dr_no LIKE :rpt_no_base ORDER BY dr_no DESC LIMIT 1";
			break;
		case 'ENG':
			//----------------- Calculate ENG No ------------------------
			// find the highest numbered ENG for today
			$sql = "SELECT eng_no FROM {qms_engineering}
							WHERE eng_no LIKE :rpt_no_base ORDER BY eng_no DESC LIMIT 1";
			break;
		case 'SD':
			//----------------- Calculate SD No ------------------------
			// find the highest numbered SD for today
			$sql = "SELECT sd_no FROM {qms_simulator_downtime}
							WHERE sd_no LIKE :rpt_no_base ORDER BY sd_no DESC LIMIT 1";
			break;
		case 'TC':
			//----------------- Calculate TC No ------------------------
			// find the highest numbered TC for today
			$sql = "SELECT tc_no FROM {qms_trouble_call_log}
							WHERE tc_no LIKE :rpt_no_base ORDER BY tc_no DESC LIMIT 1";
			break;
    case 'QTG':
			//----------------- Calculate QTG No ------------------------
			// find the highest numbered QTG for today
			$sql = "SELECT qtg_no FROM {qms_qtg_events}
							WHERE qtg_no LIKE :rpt_no_base ORDER BY qtg_no DESC LIMIT 1";
			break;
		case 'EL':
			//----------------- Calculate EL No ------------------------
      // !!! DIFFERENT THAN THE OTHER GENERATED NUMBERS
      // EL--YY-I-   (YY=year, I=device id)
      // next sequential number for the sim I
      //$search_key = _st_left($report_no_base, 6) . '%';

			// find the highest numbered EL for this sim for the year
			$sql = "SELECT el_no FROM {sch_elogs}
							WHERE el_no LIKE :rpt_no_base ORDER BY el_no DESC LIMIT 1";
			break;
		default:
			return '';  //FAIL
	}

	$result = db_query($sql, array(':rpt_no_base' => $search_key));

	if ( $result->rowCount() > 0 ) {
		$last_rpt_no = $result->fetchField();
	}

  if ( 'EL' == $report_type ) {
    // get the last 4 digits of the last report number
    $rpt_count = (int) (substr($last_rpt_no, -4));
    $rpt_count++;  // increment to the next report number;
    $new_report_no = sprintf('%s%04u', $report_no_base, $rpt_count);
    // format the new report #
  }
  else {
    // all other reports

    // ENG, SD, TC, QTG
    // get the last 2 digits of the last report number
    // negative means to search from the right
    $ndigits = -2;

    // if DR, get last 3 digits of the last report number
    if ( 'DR' == $report_type ) {
      $ndigits = -3;
    }
    $rpt_format = '%s%0' . abs($ndigits) . 'u';

    $rpt_count = (int) (substr($last_rpt_no, $ndigits));
    $rpt_count++;  // increment to the next report number;

    $new_report_no = sprintf($rpt_format, $report_no_base, $rpt_count);       // format the new report #
  }

	return $new_report_no;
}



/*
 *		_st_generate_options()
 *
 *		creates the edit & delete options links in results tables where permissions allow
 */
function _st_generate_options($path, $id, $destination = '') {

  /*
  if ( $element_id <> '' ) {
		$links = l( t('Edit'), "$path/edit/$id", array('attributes' => array('class' => $element_id . '-edit') ) );
		$links .= "&nbsp;&nbsp;";
		$links .= l( t('Delete'), "$path/delete/$id", array('attributes' => array('class' => $element_id . '-delete') ) );
  } */

  if (strlen($destination)) {
    $links = l( t('Edit'), "$path/edit/$id", array('attributes' => array('class' => array('qms-link-edit')),
                                                   'query' => array('destination' => $destination)) ) .
						 l( t('Delete'), "$path/delete/$id", array('attributes' => array('class' => array('qms-link-delete')),
                                                   'query' => array('destination' => $destination)) );
  }
	else {
		$links = l( t('Edit'), "$path/edit/$id", array('attributes' => array('class' => array('qms-link-edit')))) .
						 l( t('Delete'), "$path/delete/$id", array('attributes' => array('class' => array('qms-link-delete'))));
	}
	return $links;
}


/*
 *	_st_get_user_email()
 */
function _st_get_user_email($user_id) {
	if ( (int)$user_id == 0 ) {
		return '';
	}
	return db_query("SELECT mail FROM {users} WHERE uid = :uid", array(':uid' => $user_id))->fetchField();
}



/*
 *	convert_symbols()
 */
function _st_convert_symbols($var) {
	return html_entity_decode($var, ENT_QUOTES, 'UTF-8');
}

/*
 *  _st_add_theme_pager()
 *
 *	returns a string with the themed pager for the last db query
 */
function _st_add_theme_pager() {
	return theme('pager', array('tags' => array(), 'quantity' => QMS_RECORDS_PER_PAGE));
}


/*
 *		_st_build_breadcrumb(&$breadcrumb)
 */
function _st_build_breadcrumb(&$breadcrumb) {

	if ( !is_array($breadcrumb) || empty($breadcrumb) ) {
		return;
	}

  // Adding the title of the current page to the breadcrumb.
	$title = drupal_get_title();

	$app_code = variable_get(SABRE_APP_CODE, SABRE_APP_CODE_QMS);

	if ( $app_code == SABRE_APP_CODE_QMS ) {
    $arg0 = arg(0);

		switch ($arg0) {
			case 'discrepancy':
      case 'preflight':
			case 'shiftlog':
			case 'engineering':
			case 'simulator_downtime':
			case 'punchclock':
			case 'troublecall':
				$breadcrumb[] = t('QMS Entry');
				$breadcrumb[] = $title;
				break;
			case 'feedback':
				if ( arg(1) == 'add') {
					$breadcrumb[] = t('QMS Entry');
					$breadcrumb[] = $title;
				}
				else {
					$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
					$breadcrumb[] = $title;
				}
				break;
			case 'search':
				$breadcrumb[] = t('QMS Search');
				$breadcrumb[] = $title;
				break;
			case 'qmssettings':
        if ( arg(1) ) {
          //[0] is always home
					$breadcrumb[1] = l( t('QMS Settings'), 'qmssettings');
				}
				$breadcrumb[] = $title;
				break;
			case 'atachapter':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('ATA Chapters'), 'qmssettings/atachapters');
				$breadcrumb[] = $title;
				break;
			case 'corrective_action':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('Corrective Actions'), 'qmssettings/corrective_actions');
				$breadcrumb[] = $title;
				break;
			case 'customer':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('Customers'), 'qmssettings/customers');
				$breadcrumb[] = $title;
				break;
			case 'engloadupdate':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('Load Updated'), 'qmssettings/engloadpdated');
				$breadcrumb[] = $title;
				break;
			case 'job':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('Jobs'), 'qmssettings/jobs');
				$breadcrumb[] = $title;
				break;
			case 'prevmaint':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('Preventative Maintenance'), 'qmssettings/prevmaintlist/' . arg(2));
				$breadcrumb[] = $title;
				break;
			case 'punchclockevent':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('Punch Clock Events'), 'qmssettings/punchclockevents');
				$breadcrumb[] = $title;
				break;
			case 'simulator':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('Simulators'), 'qmssettings/simulators');
				$breadcrumb[] = $title;
				break;
      case 'trouble_cause':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('ATA Chapters'), 'qmssettings/trouble_causes');
				$breadcrumb[] = $title;
				break;
			case 'usergroup':
				$breadcrumb[] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[] = l( t('User Groups'), 'qmssettings/usergroups');
				$breadcrumb[] = $title;
				break;
			case 'reports':
        if ( '' == arg(1) ) {
          $breadcrumb[1] = $title;
        }
        else {
          $breadcrumb[1] = l( t('Reports'), 'reports');
          $breadcrumb[2] = $title;
        }
				break;
			case 'user':
				$breadcrumb[1] = l( t('QMS Settings'), 'qmssettings');
				$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
				$breadcrumb[3] = $title;
			case 'admin':
				$current_path = current_path();
				if ( $current_path == 'admin/people') {
					// we override this elsewhere with 'User Accounts'
					$breadcrumb[1] = l( t('QMS Settings'), 'qmssettings');
					//$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
					$breadcrumb[2] = t('User Accounts');
				}
				else if ( $current_path == 'admin/people/create') {
					// we override this elsewhere with 'User Accounts'
					$breadcrumb[1] = l( t('QMS Settings'), 'qmssettings');
					$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
					$breadcrumb[3] = t('Create User Account');
				}
				else if ( $current_path == 'admin/people/permissions') {
					$breadcrumb[1] = l( t('QMS Settings'), 'qmssettings');
					$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
					$breadcrumb[3] = t('User Permissions');
				}
				else if ( $current_path == 'admin/people/permissions/roles') {
					$breadcrumb[1] = l( t('QMS Settings'), 'qmssettings');
					$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
					$breadcrumb[3] = t('User Roles');
				}
				else if ( (arg(3) == 'roles') && (arg(4) == 'edit') ) {
					$breadcrumb[1] = l( t('QMS Settings'), 'qmssettings');
					$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
					$breadcrumb[3] = l( t('User Roles'), 'admin/people/permissions/roles');
					$breadcrumb[4] = t('Edit Role');
				}
				break;
			default:
				$breadcrumb[] = $title;
			}
		}
		else if ( $app_code == SABRE_APP_CODE_SCHEDULER ) {

			switch (arg(0)) {
				case 'elog':
          if ( user_access('view manage menu')) {
            $breadcrumb[] = l( t('Today\'s Sessions'), 'manager/home');
            $breadcrumb[] = $title;
          }
          else {
            $breadcrumb[] = l( t('Current Sessions'), 'user/home');
            $breadcrumb[] = $title;
          }
					break;
				case 'customers':
				case 'exceptions':
				case 'schedules':
				case 'simulators':
				case 'sessions':
				case 'patterns':
					$breadcrumb[] = l( t('Manage'), 'manage');
					$breadcrumb[] = $title;
					break;
				case 'customer':  //add, edit, delete
					$breadcrumb[] = l( t('Manage'), 'manage');
					$breadcrumb[] = l( t('Customers'), 'customers');
					$breadcrumb[] = $title;
					break;
				case 'exception':  //add, edit, delete
					$breadcrumb[] = l( t('Manage'), 'manage');
					$breadcrumb[] = l( t('Exceptions'), 'exceptions');
					$breadcrumb[] = $title;
					break;
				case 'group':
					$breadcrumb[] = l( t('Manage'), 'manage');
					$breadcrumb[] = l( t('Customers'), 'customers');
					$breadcrumb[] = $title;
					break;
				case 'schedule': //add, edit, delete
					$breadcrumb[] = l( t('Manage'), 'manage');
					$breadcrumb[] = l( t('Schedules'), 'schedules');
					$breadcrumb[] = $title;
					break;
				case 'simulator': //add, edit, delete, view
          if ( 'status' == arg(1)) {
            $breadcrumb[] = $title;
          }
          else {
            $breadcrumb[] = l( t('Manage'), 'manage');
            $breadcrumb[] = l( t('Simulators'), 'simulators');
            $breadcrumb[] = $title;
          }
					break;
				case 'session': //add, edit, delete, view
					$breadcrumb[] = l( t('Manage'), 'manage');
					$breadcrumb[] = l( t('Sessions'), 'sessions');
					$breadcrumb[] = $title;
					break;
				case 'pattern': //add, edit, delete, view
					$breadcrumb[] = l( t('Manage'), 'manage');
					$breadcrumb[] = l( t('Schedule Patterns'), 'patterns');
					$breadcrumb[] = $title;
					break;
				case 'reports':
					$breadcrumb[] = l( t('Manage'), 'manage');
					$breadcrumb[] = l( t('Reports'), 'manage');
					$breadcrumb[] = $title;
					break;
				case 'admin':
					$current_path = current_path();
					if ( $current_path == 'admin/people') {
						// we override this elsewhere with 'User Accounts'
						$breadcrumb[] = l( t('Manage'), 'manage');
						$breadcrumb[] = $title;
					}
					else if ( $current_path == 'admin/people/create') {
						// we override this elsewhere with 'User Accounts'
						$breadcrumb[1] = l( t('Manage'), 'manage');
						$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
						$breadcrumb[3] = t('Create User Account');
					}
					else if ( $current_path == 'admin/people/permissions') {
						$breadcrumb[1] = l( t('Manage'), 'manage');
						$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
						$breadcrumb[3] = t('User Permissions');
					}
					else if ( $current_path == 'admin/people/permissions/roles') {
						$breadcrumb[1] = l( t('Manage'), 'manage');
						$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
						$breadcrumb[3] = t('User Roles');
					}
					else if ( (arg(3) == 'roles') && (arg(4) == 'edit') ) {
						$breadcrumb[1] = l( t('Manage'), 'manage');
						$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
						$breadcrumb[3] = l( t('User Roles'), 'admin/people/permissions/roles');
						$breadcrumb[4] = t('Edit Role');
					}
					break;
				case 'user':  // user/%/ edit
					if (( arg(1) == 'home') || ( arg(1) == 'view90days')) {
						//$breadcrumb[0] = $title;
						$breadcrumb[0] = t('Welcome');
					}
					else {
						// we override this elsewhere with 'User Accounts'
						$breadcrumb[1] = l( t('Manage'), 'manage');
						$breadcrumb[2] = l( t('User Accounts'), 'admin/people');
						$breadcrumb[3] = $title;
					}
					break;
        case 'kiosk':
          $breadcrumb[0] = t('Welcome');
          break;
				default:
					$breadcrumb[] = $title;
			}
		}

		// SHARED
		/*
		switch ($title) {
			default:
				$breadcrumb[] = $title;
		}
		*/
}

// array_key_relative - Returns a key in an associative array relative to another key without using foreach. Very useful for finding previous key or finding next key in array, etc
// - Written by Jamon Holmgren (www.jamonholmgren.com). Last revised 8/18/2009. Free for any use.
// function array_key_relative(array $array, string $current_key, int $offset)
function _st_array_key_relative($array, $current_key, $offset = 1) {
    // create key map
    $keys = array_keys($array);
    // find current key
    $current_key_index = array_search($current_key, $keys);
    // return desired offset, if in array, or false if not
    if(isset($keys[$current_key_index + $offset])) {
        return $keys[$current_key_index + $offset];
    }
    return false;
}

// substring functions form the left of the string
function _st_left($str, $length) {
     return substr($str, 0, $length);
}
// and from the right of the string
// returns $length # of chars
function _st_right($str, $length) {
     return substr($str, -$length);
}


/*
 *	_st_add_keyword_search_condition()
 *
 * 	IN/OUT: 	db $query object
 *	IN:				search_field, database field being searched
 *  IN: 			search_text, string passed from browser
 *
 */
function _st_add_keyword_search_condition(&$query, $search_field, $search_text) {

	if ( $search_text == '' ) {
		return;
	}

	// splits the search string into keywords - keeping the quoted phrases together
	$search_list = preg_split( "/[\s,]*\\\"([^\\\"]+)\\\"[\s,]*|[\s,]+/",
															$search_text, 0, PREG_SPLIT_DELIM_CAPTURE );

	$keywords = array();
	$db_or = db_or();
	foreach ($search_list as $kw) {
		$key = trim($kw);
		if ( strlen($key) ) {
			$keywords[] = $key;
		}
	}
	$num_keys = count($keywords);

	if ( $num_keys > 0 ) {
		if ( $num_keys == 1 ) {
			// can't do a db OR condition if there is only a single condition
			// handle it as a normal condition
			$query->condition($search_field, '%' . $keywords[0] . '%', 'LIKE');
		}
		else {
			foreach ($keywords as $kw) {
				$db_or->condition($search_field, '%' . $kw . '%', 'LIKE');
			}
			$query->condition($db_or);
		}

		/*  //----> this is a problem in cases of multiple search phrases
		$match_keywords = implode(" ", $keywords);
		$query->where("MATCH (:f) AGAINST (:t1)", array(':f' => $search_field, ':t1' => $match_keywords));

		$like_keywords = '%' . implode("% OR " . $search_field . " LIKE %", $keywords) . '%';
		$query->where("MATCH (:f1) AGAINST (:t1) OR :f2 LIKE :t2",
													array(':f1' => $search_field,
																':f2' => $search_field,
																':t1' => $match_keywords,
																':t2' => $like_keywords));
		$query->where("(" . $search_field . " LIKE :t2)", array(':t2' => $like_keywords));
		*/
	}
}


/**
 * 	_st_connect_database()
 *	$app identifies if its scheduler or QMS for the log entries
 *  $db_alias must be registered in Drupal settings.php
 *
 */
function _st_connect_database($app, $db_alias) {
	try{
		// connect to the qms database
	  db_set_active($db_alias);

		return True;
	}
	catch (Exception $e) {
		watchdog($app, '_st_connect_database() ' . $e->getMessage(), array(), WATCHDOG_WARNING);
		return False;
	}
}

/**
 * 	_st_disconnect_database()
 *	$app identifies if its scheduler or QMS for the log entries
 */
function _st_disconnect_database($app) {
	try {
		$msg = '';
		// switch back to the default database
		db_set_active();
		return True;
	}
	catch (Exception $e) {
		watchdog($app, '_st_disconnect_database() ' . $e->getMessage(), array(), WATCHDOG_WARNING);
		return False;
	}
}

/*
 *		_st_clean_ckeditor_text()
 *		trims the raw text returned from the editor, trims it to the max allowed and strips
 *		any illegal tags <body><head><html> and their accompanying end tags
 *		if these are left in the editor text, they will break the page when redisplayed
 *
 */

function _st_clean_ckeditor_text($text, $max_len = QMS_TEXTAREA_MAX) {
	$text = substr(trim($text), 0, $max_len);
	$allowed_tags = "<p><a><blockquote><h1><h2><h3><h4><h5><h6><hr><ol><ul<li><dl><dd><dt><lh><table><caption>" .
									"<tr><td><th><code><em><strong><b><i><img><big><small><br><sub><sup><span>";

	$result =  strip_tags($text, $allowed_tags);
	return $result;
}

/*
 *	_st_send_drupal_email()
 *
 *  sends the QMS system emails
 */
function _st_send_drupal_email($key, $subject, $body, $to) {
	if ( strlen($to) == 0 ) {
		return;
	}

  $do_not_reply = '<hr /><p><strong>' .
                  t('DO NOT REPLY DIRECTLY TO THIS EMAIL') .
                  '. <br />' .
                  t('THIS IS A SYSTEM GENERATED EMAIL') .
                  '. </strong></p><hr />';

	// format an email message to send out
	$module = 'sabreQMS';
	$language = language_default();
	$params = array();
	$from = variable_get('site_mail', Null);
	$send = False;
	$system = drupal_mail_system($module, $key);

	$message = drupal_mail($module, $key, $to, $language, $params, $from, $send);
	$message['headers']['Content-Type'] = 'text/html; charset=UTF-8; format=flowed';
	$message['subject'] = $subject;
	$message['body'] = $do_not_reply . $body;

	$email_status = $system->mail($message);

	if ($email_status) {
		watchdog('_st_send_drupal_email', "Emails sent: $subject [to] %emails", array('%emails' => $to), WATCHDOG_INFO);
	} else {
		watchdog('_st_send_drupal_email', "Email with subject: $subject failed to send");
	}

	return $email_status;
}

/*
 * _st_get_cache_name()     !!!!! FOR SABRE TOOLS CACHES ONLY -- NOT QMS OR SCHEDULER !!!!
 * constructs the cache name for user/session specific caches
 * for forms, just echos the const name
 *
 */

function _st_get_cache_name($cache_name_const) {

	$name = '';

	switch ($cache_name_const) {
		// this group is the shared cache across all ST users
		case ST_YEAR_LIST:
			$name = $cache_name_const;
			break;
		default:		// this is to handle user-specific cache, such as searches
			global $user;
			$name = $cache_name_const . '_' . $user->uid . '_' . $user->sid;
	}
	return $name;
}

/*
 * _st_clear_cache_name()     !!!!! FOR SABRE TOOLS CACHES ONLY -- NOT QMS OR SCHEDULER !!!!
 * constructs the cache name for user/session specific caches
 * for forms, just echos the const name
 *
 */

function _st_clear_cache($cache_name_const) {
	switch ($cache_name_const) {
		case ST_YEAR_LIST:
			$name = $cache_name_const;
			break;
		default:
			global $user;
			$name = $cache_name_const . '_' . $user->uid . '_' . $user->sid;
	}
	cache_clear_all($name, 'cache', TRUE);
}

/*
 *	_st_add_text_editor()
 *	For form building, adds a text area to the form array along with any additional fields needed by the
 *	ckeditor text editor library; also handles if the text editor is not activated in the system
 *
 *	IN:  $form array
 *	IN:	 $settings array defined as follows
 *
 *	$settings = array(
 *		'name' => $name,  // used for both the text area id, name
 *		'title' => $title,
 *		'text' =>	$text,
 *		'required' => True | False,
 *		'disabled' => True | False,
 *		// this is only needed for cases of multiple editors on a single page (only 1 length needed)
 *		'omit_length' => True | False,
 *		// add text area to an existing fieldset
 *		'fieldset' => $fieldset_name,
 *    // prefix and suffix options for the text area
 *    'prefix' => $prefix,
 *    'suffix => $suffix,
 *  );
 *
 */
function _st_add_text_editor(&$form, $text_settings) {

	if ( !isset($text_settings['name']) ) {
		$text_settings['name'] = 'text_area';
	}
	if ( !isset($text_settings['text']) ) {
		$text_settings['text'] = '';
	}

	// WYSIWYG EDITOR??  Is this feature enabled allowing for the editor
	$ckeditor_activated  = variable_get(QMS_VAR_WYSIWYG_EDITOR, 1);  // if not set, default to ON

	$text = $text_settings['text'];

	// this is a kluge to allow for required fields with CKEditor
	// Still looks required, but rather than Drupal checking the wrong field value
	// we do the checking in the validation routine with the POST variable

	if ( isset($text_settings['required']) && (True == $text_settings['required']) ) {
		$text_settings['title'] .=
			'<span class="form-required" title="' . t('This field is required.') . '"> *</span>';
	}

	if ( $ckeditor_activated ) {
		global $base_url;

		$form['ckeditor_module_path'] = array(
			'#type' =>'textfield',
			'#default_value' => $base_url . '/' . drupal_get_path('module', 'sabreTools') .
														'/js/sabreTools.ckeditor.config.js',
			'#attributes' => array('class' => array('qms-hidden-field'),
															'id' => 'qms-ckeditor-config'),
		);
		$text = _st_convert_symbols($text);
	}
	else {
		// handled as a normal text area
		// remove html tags and encoded chars in the event they were stored that way by ckeditor previously
		$text = trim(strip_tags(_st_convert_symbols($text)));
	}
	$text_settings['text'] = $text;

	// build form text area options array
	$text_area = array(
		'#type' => 'textarea',
		'#title' => $text_settings['title'],
		'#default_value' => $text_settings['text'],
		// fakey fakey.  If it's really required, we show it in the title,
		// but we bypass Drupal validation for ckeditor,
		'#required' => False,
		'#disabled' =>  (isset($text_settings['disabled']) ? $text_settings['disabled'] : False),
		'#attributes' => array('id' => 'qms_' . $text_settings['name'],  // underscores here instead of dashes
														'name' => 'qms_' . $text_settings['name']),  // required by CKEditor
		'#prefix' => (isset($text_settings['prefix']) ? $text_settings['prefix'] : ''),
		'#suffix' => (isset($text_settings['suffix']) ? $text_settings['suffix'] : ''),
	);

	// set text area options into $form structure
	if ( isset($text_settings['fieldset']) && strlen($text_settings['fieldset']) ) {
		// text area is to be nested inside of a fieldset
		$form[$text_settings['fieldset']][$text_settings['name']] = $text_area;
	}
	else {
		// handle normally
		$form[$text_settings['name']] = $text_area;
	}



	// CKEDITOR field value storage and handling
	// this is a kluge to handle discrepancy text contents in the event of a validation error
	// on submit, the CKEditor field value for Text is stored here for Drupal processing
	// in the event of a validation error, the value is sent back to the browser by Drupal, set back
	// into the CKEditor by javascript

	// for using as an id, replace the underscores with dashes in the name
	$id = str_replace('_', '-', $text_settings['name']);

	$form[$text_settings['name'] . '_editor_value'] = array(
		'#type' => 'textarea',
		'#default_value' => $text_settings['text'],
		'#attributes' => array('id' => 'qms-' . $id . '-editor-value'),
		// Need to wrap this textarea in a hidden div since our standard method of using qms-hidden-field class
		// will not work on a textarea due to conflicts with CKEditor
		'#prefix' => '<div id="qms-' . $id . '-textarea-hidden" class="qms-hidden-field">',
		'#suffix' => '</div>',
	);

	if ( (False == isset($text_settings['omit_length'])) ||
			 ( isset($text_settings['omit_length']) && (False == $text_settings['omit_length']) ) ) {
		$form['max_text_length'] = array(
			'#type' => 'textfield',
			'#default_value' => QMS_TEXTAREA_MAX,
			'#attributes' => array('id' => 'qms-max-text-length',
															'class' => array('qms-hidden-field')),
		);
	}

}

/*
 *		_st_setup_paged_search()
 *
 *	IN: $init array object
 *			array(
 *				'table_name' => '',
 *				'table_alias' => '',
 *				'table_header => array,
 *				'pager_path' => '',
 *				'order' => 'sort column name',
 *				'order_default' => 'default col name if none set in variable table',
 *				'sort' => 'asc' | 'desc',
 *				'sort_default' => 'if none set in variable table, asc or desc',
 *				'variable' => True | False -- use the sort & order settings with the variable_get() function
 *				'num_records' => number | defaults to QMS_RECORDS_PER_PAGE
 *        'no_header_sort' True | False -- ignore the header sort
 *			)
 *
 *  RETURN:	 $query object
 */
function _st_setup_paged_search(&$init) {

	if ( !isset($init['table_name']) 		||
			 !isset($init['table_alias']) 	||
			 !isset($init['table_header']) 	||
			 !isset($init['pager_path']) 		||
			 !isset($init['order']) 				||
			 !isset($init['sort']) 					)  {
		return (object) Null;
	}
	if ( !isset($init['order_default'])) { $init['order_default'] = ''; }
	if ( !isset($init['sort_default'])) { $init['sort_default'] = ''; }


	// need to force this or pager picks up the wrong path
	$_GET['q'] = $init['pager_path'];

	if ( !isset($_GET['sort']) )
	{
		if ( isset($init['variable']) && ( True == $init['variable']) ) {
			// set the default sort based on the user settings
			$_GET['order'] = variable_get($init['order'], $init['order_default']);
			$_GET['sort'] = variable_get($init['sort'], $init['sort_default']);
		}
		else {
			$_GET['order'] = $init['order'];
			$_GET['sort'] = $init['sort'];
		}
	}

	$num_records = isset($init['num_records']) ? $init['num_records'] : QMS_RECORDS_PER_PAGE;


	// Need to use the DB abstration layer here for the paging features
	$query = db_select($init['table_name'], $init['table_alias']);





  if ( isset($init['no_header_sort'] ) && ($init['no_header_sort'] == True) ) {
    $query->extend('PagerDefault')
				->limit($num_records);
  }
  else {
    $query->extend('PagerDefault')
				->limit($num_records)
				->extend('TableSort')
        ->orderByHeader($init['table_header']);
  }

	return $query;
}

/*
 *		_st_execute_paged_search()
 *
 *	IN: $query object
 *  RETURN:	 $results object from query
 */

function _st_execute_paged_search(&$query, &$max_count, $num_per_page = QMS_RECORDS_PER_PAGE) {

	//This is handled as a GET
	// this is the index of the next page being requested
	$page = 0;
	if ( isset($_GET['page'])) {
		$page = (int)$_GET['page'];
	}

	$max_count = $query->countQuery()->execute()->fetchField();

	pager_default_initialize($max_count, $num_per_page);

	$offset = $num_per_page * $page;

	return $query->range($offset, $num_per_page)->execute();
}


/*
 *	_st_format_record_timestamp_table($report)
 *
 *	Accepts either a discrepancy or shiftlog record object
 *	Formats the created + updated timestamps and user info into a table for display on
 *  the DR or SL form and view-only screens
 *
 *  _get_user_name() is native to each respective app, not in ST
 */
function _st_format_record_timestamp_table($report)  {
	$ts_table = '';
	$created_row = '';
	$updated_row = '';  // this may not always be visible
  $f_created_date = '';
  $f_updated_date = '';

  $appcode = variable_get(SABRE_APP_CODE, SABRE_APP_CODE_QMS);

	if ( (!empty($report->created_by_user)) || (!empty($report->created_date))       ) {

    $created_date = '';
    if ( isset($report->created_date) && $report->created_date ) {
      $created_date = $report->created_date;
    }

		$email = _st_get_user_email($report->created_by_user);  // this may return '' if created_by_user==0
		$user_link = ( strlen($email) ? l(_get_user_name($report->created_by_user), 'mailto:' . $email) : _get_user_name($report->created_by_user) );

    if ( $created_date || $report->created_by_user ) {

      if ($created_date) {
        if ($appcode == SABRE_APP_CODE_QMS) {
          $f_created_date = _st_format_date($created_date, 'medium');
        } else {
          $f_created_date = _st_format_system_date($created_date, 'medium');
        }
      }
      $created_row =
        '<tr><td style="width:15%">' . t('Created: ') . '</td><td>' .
				( $report->created_by_user ? $user_link . ', ' : '' ) . $f_created_date .
        ( !empty($report->created_by_ip_address) ? ' from '. $report->created_by_ip_address : '') .
        '</td></tr>';
    }


	}
	else {
		$created_row = '<tr><td style="width:15%">&nbsp;</td><td>&nbsp;</td></tr>';
	}
	if ( (isset($report->updated_by_user) && $report->updated_by_user) ||
        isset($report->updated_date) ) {

    $updated_date = '';
    if ( isset($report->updated_date) && $report->updated_date ) {
      $updated_date = $report->updated_date;
    }

		$email = _st_get_user_email($report->updated_by_user);  // this may return '' if created_by_user==0
		$user_link = ( strlen($email) ? l(_get_user_name($report->updated_by_user), 'mailto:' . $email) : _get_user_name($report->updated_by_user) );

    if ( $updated_date || $report->updated_by_user ) {
      if ($updated_date) {
        if ($appcode == SABRE_APP_CODE_QMS) {
          $f_updated_date = _st_format_date($updated_date, 'medium');
        } else {
          $f_updated_date = _st_format_system_date($updated_date, 'medium');
        }
      }

      $updated_row =
        '<tr><td style="width:15%">' . t('Updated: ') . '</td><td>' .
				( $report->updated_by_user ? $user_link . ', ' : '') . $f_updated_date .
        ( !empty($report->updated_by_ip_address) ? ' from '. $report->updated_by_ip_address : '') .
        '</td></tr>';
    }
	}

	$ts_table = '<div class="qms-desc"><table class="qms-plain-table" style="font-size:95%">' .
									$created_row . $updated_row . '</table></div><hr />';
	return $ts_table;
}

/*
 *			_calc_seconds_to_hours_minutes()
 *
 *			IN:		seconds (int)
 *			OUT:  hours (int), minutes (int)
 */

function _st_calc_seconds_to_hours_minutes($seconds, &$hours, &$mins) {
	$hours = $seconds / (60 * 60) % 24;
	$mins = $seconds / 60 % 60;
}


/*
 *		_st_get_simulator_notification_email_list()
 *
 *    Only works for the QMS database
 *
 *		returns a string of comma-separated emails of users to notify for the specified event
 */
function _st_get_simulator_notification_email_list($app, $simulator_id, $notify_type) {

  try {

    // all simulator notification settings are handled through QMS
    // if being called by Scheduler, handle the database switch
    if ($app != APP_QMS) {
      _st_connect_database($app, QMS_DB_QMS);
    }

    $emails = "";

    $query1 = db_select('users', 'u');
    $query1->innerJoin('qms_notifications', 'n', 'u.uid = n.user_id');
    $query1->condition('n.simulator_id', $simulator_id);
    $query1->condition('n.user_id', 0, '>');
    $query1->condition('u.status', 1);
    $query1->fields('u', array('mail'));

    $query2 = db_select('users', 'u');
    $query2->rightJoin('qms_user_groups_users', 'ug', 'u.uid = ug.user_id');
    $query2->innerJoin('qms_notifications', 'n', 'n.user_group_id = ug.user_group_id');
    $query2->condition('n.simulator_id', $simulator_id);
    $query2->condition('n.user_group_id', 0, '>');
    $query2->condition('u.status', 1);
    $query2->fields('u', array('mail'));


    switch ($notify_type) {
      case QMS_NOTIFY_DISCREPANCY_NEW:
        $query1->condition('n.notify_discrepancy_new', 1);
        $query2->condition('n.notify_discrepancy_new', 1);
        break;
      case QMS_NOTIFY_DISCREPANCY_UPDATED:
        $query1->condition('n.notify_discrepancy_updated', 1);
        $query2->condition('n.notify_discrepancy_updated', 1);
        break;
      case QMS_NOTIFY_DISCREPANCY_CLOSED:
        $query1->condition('n.notify_discrepancy_closed', 1);
        $query2->condition('n.notify_discrepancy_closed', 1);
        break;
      case QMS_NOTIFY_SHIFT_LOG:
        $query1->condition('n.notify_shift_log', 1);
        $query2->condition('n.notify_shift_log', 1);
        break;
      case QMS_NOTIFY_SIMULATOR_DOWNTIME:
        $query1->condition('n.notify_simulator_downtime', 1);
        $query2->condition('n.notify_simulator_downtime', 1);
        break;
      case QMS_NOTIFY_PREFLIGHT_OPEN:
        $query1->condition('n.notify_preflight_open', 1);
        $query2->condition('n.notify_preflight_open', 1);
        break;
      case QMS_NOTIFY_PREFLIGHT_NEW:
        $query1->condition('n.notify_preflight_new', 1);
        $query2->condition('n.notify_preflight_new', 1);
        break;
      case QMS_NOTIFY_TROUBLE_CALL:
        $query1->condition('n.notify_trouble_call', 1);
        $query2->condition('n.notify_trouble_call', 1);
      case QMS_NOTIFY_ELOG:
        $query1->condition('n.notify_elog', 1);
        $query2->condition('n.notify_elog', 1);
    }

    $query1->union($query2);

    $results = $query1->execute()->fetchAll();


    // switch the database back
    if ($app != APP_QMS) {
      _st_disconnect_database($app);
    }

    foreach ( $results as $user ) {
      $emails .= ( strlen($emails) ? (', ' . $user->mail) : $user->mail );
    }
    return $emails;
  }
  catch (Exception $e) {
    watchdog($app, '_st_get_simulator_notification_email_list() ' . $e->getMessage(), array(), WATCHDOG_WARNING);
		return False;
  }
}


/*
 *    _st_format_sim_name()
 */
function _st_format_sim_name($sim_name = '', $device_id = '', $active = 1) {

  if ( !strlen($sim_name) ) { return ''; }

  $sim_name .= (isset($device_id) && strlen($device_id)) ? '-' . $device_id : '';
  $sim_name .= (!$active ? '*' : '');

  return $sim_name;
}


/*
 *    _st_date_diff_seconds()
 *
 *  IN:     $ts1,             // timestamp 1
 *          $ts2,             // timestamp 2
 *  RETURN: $total_seconds    // number of seconds in the interval
 *
 * -->accommodates DST -- requires PHP 5.3 or greater
 */
function _st_date_diff_seconds($ts1, $ts2) {

  $date1 = new DateTime();
  //$date1->setTimezone(new DateTimeZone('GMT'));
  $date1->setTimestamp($ts1);

  $date2 = new DateTime();
  //$date2->setTimezone(new DateTimeZone('GMT'));
  $date2->setTimestamp($ts2);

  $interval = $date1->diff($date2);

  $total_seconds = ($interval->days*86400) +
                   ($interval->h*3600) +
                   ($interval->i*60) +
                   $interval->s;
  return $total_seconds;
}


/*
 *    _st_format_timestamp()
 *
 *  IN:     $date_str,             // date string to convert to unixtime with respect to timezone
 *                                 // '+1 day', '-2 weeks'
 *          $options               // array
 *              'fail_empty'       // if True, return ts = 0, otherwise, use the current timestamp
 *              'timezone'         // use a specified tz
 *              'user_tz           // user the user's tz
 *              'modify'           // modify the date '+|-' an interval
 *  RETURN: unix timestamp
 */
function _st_format_timestamp($date_str, $options = array()) {
  try {

    $fail_empty = !empty($options['fail_empty']) ? $options['fail_empty'] : False;
    if ($fail_empty && empty($date_str)) {
      return 0;
    }
    if (empty($date_str)) { $date_str = null; }

    $check_user = !empty($options['user_tz']) ? $options['user_tz'] : True;
    $tz = (!empty($options['timezone']) ? $options['timezone'] : _st_get_timezone($check_user) );

    $d = new DateTime($date_str, new DateTimeZone($tz));
    if (!empty($options['modify'])) {
      $d->modify($options['modify']);
    }
    //return (int) $d->format('U');
    return $d->getTimestamp();
  } catch(Exception $e) {
    watchdog('sabreTools', '_st_format_timestamp() ' . $e->getMessage() . "\n" . var_export($e->getTraceAsString(), True), array(), WATCHDOG_ERROR);
  }
}


function _st_format_system_timestamp($date_str) {
  return _st_format_timestamp($date_str, array('user_tz' => False));
}


/*
 * _st_modify_timestamp
 * IN:  $ts             // timestamp
 *      $modify         // modify timestamp using strtotime methods:  '+1 day', '-2 months'
        $options        // array of optional options
          'timezone'      // timezone (if you already have it)
          'user_tz'    // check the user's timezone settings first? (defaults True)

 * RET: modified timestamp
 */
function _st_modify_timestamp($ts = 0, $modify='', $options = array()) {

  $check_user = !empty($options['user_tz']) ? $options['user_tz'] : True;
  $tz = (!empty($options['timezone']) ? $options['timezone'] : _st_get_timezone($check_user) );

  $d = new DateTime('now', new DateTimeZone($tz));
  if (empty($ts)) {
    $ts = $d->getTimestamp();
  }
  if (!empty($modify)) {
    $d->setTimestamp($ts);
    $d->modify($modify);
    $ts = $d->getTimestamp();
  }
  return $ts;
}


function _st_modify_system_timestamp($ts = 0, $modify='', $timezone = '') {
  return _st_modify_timestamp($ts, $modify, array('user_tz' => False, 'timezone' => $timezone));
}

/*
 *    _st_format_date()
 *
 *  IN:     $ts             // unix timestamp to format
 *          $format         // drupal date format (short, medium, or long) or
 *                          // or custom 'Y-m-d' or iso = 'Y-m-d H:i:s'
 *          $options        // array of optional options
 *              'custom_format' // if $format == 'custom'
 *              'modify'        // plain text to modify the date by '+1 day'
 *              'timezone'            // timezone (if you already have it)
 *              'user_tz'    // check the user's timezone settings first? (defaults True)
 *              'fail_empty' // if True, returns empty string if $ts == 0
 *
 *  RETURN: string  // formatted date with user or default system timezone
 *          boolean FALSE if error
 */
function _st_format_date($ts=0, $format='short', $options = array()) {

  try {
    $format_opts = array('short', 'medium', 'long', 'iso');
    $custom_format = '';

    $fail_empty = !empty($options['fail_empty']) ? $options['fail_empty'] : False;
    if ($fail_empty && empty($ts)) {
      return '';
    }

    $check_user = !empty($options['user_tz']) ? $options['user_tz'] : True;
    $tz = (!empty($options['timezone']) ? $options['timezone'] : _st_get_timezone($check_user) );
    $modify = (!empty($options['modify']) ? $options['modify'] : '');

    if ($format == 'custom') {
      if (is_string($options)) {
        $custom_format = $options;
      } else {
        $custom_format = (!empty($options['custom_format']) ? $options['custom_format'] : '');
      }
    } else if (in_array($format, $format_opts)) {
      if ($format == 'iso') {
        $custom_format = 'Y-m-d H:i:s';
      } else {
        $custom_format = variable_get("date_format_$format", 'Y-m-d H:i');
      }
    } else {
      $custom_format = $format;
      $format = 'custom';
    }


    $d = new DateTime('now', new DateTimeZone($tz));
    if (!empty((int)$ts)) {
      $d->setTimestamp((int)$ts);
    }
    if (!empty($modify)) {
      $d->modify($modify);
    }
    $s = $d->format($custom_format);
    return $s;
    //return format_date($ts, $format, $custom_format, $tz);
    //return format_date($ts, $format, $custom_format);
  } catch(Exception $e) {
    watchdog('sabreTools', '_st_format_date() ' . $e->getMessage() . "\n" . var_export($e->getTraceAsString(), True), array(), WATCHDOG_ERROR);
  }
}


/*
 *  function _st_format_system_date
 */
function _st_format_system_date($ts=0, $format='short', $custom_format = '') {
  return _st_format_date($ts, $format, array('user_tz' => False, 'custom_format' => $custom_format));
}


/*
 *  _st_get_time()
 *  RET: string   // 'H:i:s' based on the user's timezone or the default timezone
 */
function _st_get_time($user_tz=True) {
  $tz = _st_get_timezone($user_tz);
  $d = new DateTime('now', new DateTimeZone($tz));
  return $d->format('H:i:s');
}

/*
 *  allows for consistency throughout SIMmetry in the event we change how we
 *  reference timezones
 */
function _st_get_timezone($user_tz=True) {
  return date_default_timezone($user_tz);
}


function _st_get_ip_address() {
  return (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
}


/*
 * _format_schedule_date
 *
 * based on the main grid schedule
 */
function _st_format_schedule_date($ts=0, $format='short', $timezone = '', $modify='') {

  $options = array(
    'modify' => $modify,
    'timezone' => (isset($timezone) ? $timezone : ''),
    'user_tz' => False,
  );

  return _st_format_date($ts, $format, $options);
}

/*
 *
 */
function _st_format_schedule_timestamp($date_str, $timezone, $modify = '') {
  return _st_format_timestamp($date_str, array(
                                            'user_tz' => False,
                                            'timezone' => $timezone,
                                            'modify' => $modify));
}


