<?php
define("KEY_SALT_1","J3@LDkd%3!ldkwi6") ;
define("KEY_SALT_2","9KDI^ldk#lk29lQa")	;
// define("KEY_IV","Kd$1f@4wxiu!dlj(8Od#1kdrxmfil0*d") ;
//using smsun key
define("KEY_IV","Kd$1f@4wxiu!dlj(") ;

require_once(PATH_LIB . "xxtea.php") ;

class Util {
	//Cache busting for js/css.
	//IIS serves these files with an ETag and Last-Modified but no Cache-Control or Expires,
	//so browsers fall back to heuristic freshness (roughly 10% of the file's age) and keep
	//serving a stale copy without even asking the server - which is why an edited script only
	//reaches users once they clear their cache. Stamping the file's modification time into the
	//url makes an edited file a new url, so the browser is obliged to fetch it. Files that did
	//not change keep their url and stay cached.
	private static $asset_ver = array();

	public static function asset($path) {
		if (!isset(self::$asset_ver[$path])) {
			self::$asset_ver[$path] = self::assetVersion($path);
		}
		$v = self::$asset_ver[$path];
		if ($v === "")
			return $path;                                   //unresolved: emit the plain path
		return $path . (strpos($path, '?') === false ? '?' : '&') . 'v=' . $v;
	}

	private static function assetVersion($path) {
		$clean = strtok($path, '?');
		if ($clean === false || $clean === "")
			return "";

		//resolve the same way the browser will: relative to the page that is being served
		$bases = array();
		if (isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME'] != "")
			$bases[] = dirname($_SERVER['SCRIPT_FILENAME']);
		$cwd = getcwd();
		if ($cwd !== false)
			$bases[] = $cwd;

		foreach ($bases as $base) {
			$file = realpath($base . DIRECTORY_SEPARATOR . $clean);
			if ($file !== false && is_file($file)) {
				$t = @filemtime($file);
				if ($t)
					return (string)$t;
			}
		}
		return "";      //never break the page over a missing stat
	}

	public static function isModuleEnabled($module_number){
		$licenseFile = new LicenseFile();
		$licenseFile->read(PATH_CODE . "sbg.lic");
		
		$modules = $licenseFile->getModules();
		
		//return $modules[$module_number] == 1;
		return ModuleInfo::getModuleValue($modules,$module_number);
	}

	public static function getDay($year,$month,$day) {
		$dte = $year . "-" . $month . "-" . $day;
		return date("D", strtotime($dte));
	}
	
	public static function encryptString($text,$key,$iv) {
		if ($iv == "")
			$iv = KEY_IV ;
		if ($key == "")
			$key = KEY_SALT_1 . KEY_SALT_2 ;

		// return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);

		$plaintext = $text;
		$cipher="AES-128-CBC";
		$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
		$ciphertext = base64_encode($ciphertext_raw );
        return $ciphertext;
	}
	
	public static function decryptString($text,$key,$iv) {
		if ($iv == "")
			$iv = KEY_IV ;
		if ($key == "")
			$key = KEY_SALT_1 . KEY_SALT_2 ;

		// return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
        
		$c = base64_decode($text);
		$cipher="AES-128-CBC";
		$original_plaintext = openssl_decrypt($c, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
		return rtrim($original_plaintext, "\0");
	}
	public static function convertLink($link,$key="",$iv="") {
		//return $link ;
		if ($key == "")
			$key = $_SESSION[SE_ID] ;
		if ($iv == "")
			$iv = KEY_IV ;
		
		$encryptkey = Util::createMD5($key,"","",true) ;
		return bin2hex(Util::encryptString($link,$encryptkey,$iv));
	}
	
	public static function convertLink_old($link,$key = "",$iv = "") {
		if ($key == "")
			$key = $_SESSION[SE_ID] ;
		if ($iv == "")
			$iv = KEY_IV ;
		$enc = base64_encode(Util::encryptString($link,$key,$iv));
		$idx = 0 ;
		$cnt = 0 ;
		$len = strlen($enc) - 1 ;
		for ($i=$len; $i >= 0; $i--)
		{
			if ($enc[$i] == "=")
			{
				$cnt++ ;
				$idx = $i ;
			}
			else 
				break ;
		}
		$enc1 = $enc ;
		$enc = str_replace("+","-",$enc) ;
		$enc = str_replace("/","_",$enc) ;
		return trim(substr($enc,0,$idx)) . $cnt ;
	}
	public static function revertLink($text,$key = "",$iv = "") {
		//return $text ;
		if ($key == "")
			$key = $_SESSION[SE_ID] ;
		if ($iv == "")
			$iv = KEY_IV ;
		
		$encryptkey = Util::createMD5($key,"","",true) ;
		return trim(Util::decryptString(pack("H*" , $text),$encryptkey,$iv)) ;
		
	}
	public static function revertLink_old($text,$key = "",$iv = "") {
		if ($key == "")
			$key = $_SESSION[SE_ID] ;
		if ($iv == "")
			$iv = KEY_IV ;
		$last = substr(trim($text),strlen(trim($text))-1,1) ;
		$enc = substr(trim($text),0,strlen(trim($text)) -1) ;
		$enc = str_replace("-","+",$enc) ;
		$enc = str_replace("_","/",$enc) ;
		if ($last > 0)
		{
			for ($j=1;$j <= $last;$j++)
			{
				$enc .= "=" ;
			}
		}
		return trim(Util::decryptString(trim(base64_decode($enc)),$key,$iv)) ;
	}
	public static function createMD5($data,$key1="",$key2="",$hex=false) {
		if ($data == "") return "" ;
		if ($key1=="")
			$d = KEY_SALT_1 . $data ;
		else
			$d = $key1 . $data ;
		if ($key2 == "")
			$d .= KEY_SALT_2 ;
		else
			$d .= $key2 ;
		if ($hex)
			return md5($d) ;
		else 
			return base64_encode(md5($d,true));
	}
	public static function createSHA1($data,$key1="",$key2="",$hex=false) {
		if ($data == "") return "" ;
		if ($key1=="")
			$d = KEY_SALT_1 . $data ;
		else
			$d = $key1 . $data ;
		if ($key2=="")
			$d .= KEY_SALT_2 ;
		else
			$d .= $key2 ;
		if ($hex)
			return sha1($d) ;
		else
			return base64_encode(sha1($d,true)) ;
	}
	public static function createSHA256($data,$key1="",$key2="",$hex=false) {
		if ($data == "") return "" ;
		if ($key1=="")
			$d = KEY_SALT_1 . $data ;
		else
			$d = $key1 . $data ;
		if ($key2=="")
			$d .= KEY_SALT_2 ;
		else
			$d .= $key2 ;
		if ($hex) {
			return hash('sha256', $d);
		} else {
			return base64_encode(hash('sha256', $d, true));
		}
	}
	public static function searchStringLink() {
		$result = Util::getListScript('A') ;
		$result .= Util::getListScript('B')  ;
		$result .= Util::getListScript('C') ;
		$result .= Util::getListScript('D') ;
		return $result ;
	}
    public static function modifyRunningNumberPrefix($str){
        if(strpos($str, "[YEAR]") !== false){
            $str = str_replace("[YEAR]", (new DateTime())->format('Y'), $str);
        }
        return $str;
    }
	private static function getListScript($opt) {
		return "<a href =\"javascript:getList('" . $opt . "')\">" .$opt ."</a>&nbsp;&nbsp;" ;
	}
	public static function createOptionValue($valuelists,$default="",$isnumber=false) {
		$c = "" ;
		if (!is_null($valuelists) && count($valuelists) > 0) {
			foreach ($valuelists as $vl) {
				$c .= "<option " ;
				if ($default != "") {
					if ($default == $vl['code']){
						$c .= "selected=\"selected\" " ;
					}
				}
				if($isnumber)
					$c .= "value=\"" . $vl['code'] . "\">" . sprintf("%f", floatval($vl['desc'])) . "</option>" ;
				else
					$c .= "value=\"" . $vl['code'] . "\">" . $vl['desc'] . "</option>" ;
			}
		}
		return $c ;
	}
	public static function getRemoteIP()
	{
		if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
			$ip=$_SERVER['HTTP_CLIENT_IP'];
		} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
			$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
		} else {
			$ip=$_SERVER['REMOTE_ADDR'];
		}
		return $ip;
	}
	public static function getFirstDate($date=null) {
		if (is_null($date))
			return new DateTime(date('Y-m-01')) ;
		else
			return new DateTime($date->format('Y') . '-' . $date->format('m') . '-01');
	}
	public static function getLastDate($date=null) {
		if (is_null($date))
			return new DateTime(date('Y-m-t')) ;
		else 
			return new DateTime($date->format('Y') . '-' . $date->format('m') . '-' . $date->format('t'));
	}
	public static function getLastDay($year,$month) {
		$d = new DateTime($year . "-" . $month . "-01") ;
		return $d->format('t') ;
	}
	public static function calculateCpfAge($dob,$asatdate=null) {
		$age = 0 ;
		if (is_null($asatdate))
			$asatdate = new DateTime('now');
		//$asatdate = pay date.
		//age shall be applied from the first day of the month after the month of birth date
		$date = new DateTime($asatdate->format('Y-m-01'));
		$date = $date->add(new DateInterval('P1M')); 
		$age = $date->format('Y') - $dob->format('Y') ;
		if ($date->format('md') < $dob->format('md')) { 
			$age-- ; 
		}
		return $age ;
	}
	public static function getLogo($coyid = 0) {
		$fn = Util::getLogoFile(PATH_PICTURE, "company_".$coyid) ;
		if ($fn == "")
			return "" ;
		else {
			if(file_exists(getcwd() . "/web")){
				return "/web/picture/company_" . $coyid . "/" . $fn ;
			}
			else {
				return "../web/picture/company_" . $coyid . "/" . $fn ;
			}
		}
	}
	public static function getLogoEmail($coyid = 0, $url = "")
    {
        $fn = Util::getLogoFile(PATH_PICTURE, "company_" . $coyid);
        if ($fn == "") {
            return "";
        } else {
			if($url = ""){
				$url = "http://".$_SERVER['SERVER_NAME'];
			}
            $image = '<img align="center" alt="Alternate text" border="0" class="center fixedwidth " src="' . $url . '/web/picture/company-' . $coyid . '/' . $fn . '" style="text-decoration: none; -ms-interpolation-mode: bicubic; height: auto; border: 0; width: 100%; max-width: 175px; display: block;" title="Alternate text" width="175"/>';
            return $image;
        }
    }
	public static function getLogoFile($path,$orgid) {
		if (!file_exists($path . $orgid)) {
			mkdir($path . $orgid, 0777, true);
		}
		$files = Util::getFileList($path . $orgid,"logo*.*") ;
		if (count($files) > 0)
			return $files[0] ;
		else 
			return "";
	}
	public static function removeLogoFile($path,$orgid) {
		$files = Util::getFileList($path . $orgid,"logo*.*") ;
		foreach ($files as $f) {
			$fn = $path . $orgid. "\\" . $f ;
			if (file_exists($fn))
				unlink($fn) ;
		}
	}
	public static function validFileExt($ext,$validexts) {
		if ($ext != "") {
			foreach ($validexts as $e) {
				if (strtolower($ext) == strtolower($e))
					return true ;
			}
		}
		return false ;
	}
	public static function getFileList($path=".",$mask="*") {
		$dir = @ dir("$path"); 
		$files = array() ;
		if (!is_null($dir)) {
			while (($file = $dir->read()) !== false) 
			{ 
				if($file !="." && $file!=".." && fnmatch($mask, $file)) 
					$files[] = $file; 
			} 
			$dir->close(); 
		}
		return $files; 
	}
	public static function decryptData($data,$key) {
		return xxtea_decrypt(pack('H*',$data),$key) ;
	}
	public static function encryptData($data,$key) {
		return bin2hex(xxtea_encrypt($data, $key)) ;
	}
	public static function getMonthShortName($month) {
		if ($month == 1)
			return "Jan" ;
		elseif ($month == 2)
			return "Feb" ;
		elseif ($month == 3)
			return "Mar" ;
		elseif ($month == 4)
			return "Apr";
		elseif ($month == 5)
			return "May" ;
		elseif ($month == 6)
			return "Jun";
		elseif ($month == 7)
			return "Jul" ;
		elseif ($month == 8)
			return "Aug" ;
		elseif ($month == 9)
			return "Sep";
		elseif ($month == 10)
			return "Oct" ;
		elseif ($month == 11)
			return "Nov";
		elseif ($month == 12)
			return "Dec";
		else 
			return "";
	}
	public static function getMonthOption() {
		$vls = array() ;
		$vls[] = array('code'=>1,'desc'=>' Jan ') ;
		$vls[] = array('code'=>2,'desc'=>' Feb ') ;
		$vls[] = array('code'=>3,'desc'=>' Mar ') ;
		$vls[] = array('code'=>4,'desc'=>' Apr ') ;
		$vls[] = array('code'=>5,'desc'=>' May ') ;
		$vls[] = array('code'=>6,'desc'=>' Jun ') ;
		$vls[] = array('code'=>7,'desc'=>' Jul ') ;
		$vls[] = array('code'=>8,'desc'=>' Aug ') ;
		$vls[] = array('code'=>9,'desc'=>' Sep ') ;
		$vls[] = array('code'=>10,'desc'=>' Oct ') ;
		$vls[] = array('code'=>11,'desc'=>' Nov ') ;
		$vls[] = array('code'=>12,'desc'=>' Dec ') ;
		return Util::createOptionValue($vls) ;
	}
	public static function getYearOption() {
		$vls = array() ;
		$year = date('Y') - 5 ;
		for ($i = 1 ;$i < 7; $i++) {
			$vls[] = array('code'=>$year + $i,'desc'=>$year + $i) ;
		}
		return Util::createOptionValue($vls) ;
	}

	public static function getTimeDropdown($selected = null, $interval = 30) {
		// If no selected value, use current time rounded UP to nearest interval
		if ($selected === null) {
			$now = time();
			$hour = date('H', $now);
			$minute = date('i', $now);

			// Round UP to next interval
			$roundedMinutes = ceil($minute / $interval) * $interval;
			if ($roundedMinutes >= 60) {
				$roundedMinutes = 0;
				$hour = ($hour + 1) % 24; // wrap around to 00 after 23
			}

			$selected = sprintf("%02d:%02d", $hour, $roundedMinutes);
		}

		$html = "";
		for ($hour = 0; $hour < 24; $hour++) {
			for ($minute = 0; $minute < 60; $minute += $interval) {
				$timeValue = sprintf("%02d:%02d", $hour, $minute); // 24-hour value
				$timeDisplay = date("g:i A", strtotime($timeValue)); // 12-hour format
				$isSelected = ($selected == $timeValue) ? " selected" : "";
				$html .= "<option value='{$timeValue}'{$isSelected}>{$timeDisplay}</option>\n";
			}
		}

		return $html;
	}

	public static function minifyHtml($html) {
		return $html ;
		//$h = str_replace("\r","",$html) ;
		//$h = str_replace("\n","",$h) ;
		//$h = str_replace("\t","",$h) ;
		//return $h ;
	}
	public static function require_once_encryption($path) {
        ob_start();
        
        exec("resolver.exe " . $path);
        $resfile = str_replace(".php", "-real.php", $path);
        require_once ($resfile) ;
        unlink($resfile);
        
		return Util::minifyHtml(ob_get_clean()) ;
	}
	public static function roundOff($amount) {
		if ($amount < 0)
			return ceil($amount) ;
		else
			return floor($amount) ;
	}
	public static function checkPasswordComplexity($pwd){
		if(strlen($pwd) < 8){
			return "Password must be at least 8 characters length.";
		}
		if(preg_match("/[A-Z]/", $pwd) !== 1){
			return "Password must contain at least 1 uppercase letter.";
		}
		if(preg_match("/[a-z]/", $pwd) !== 1){
			return "Password must contain at least 1 lowercase letter.";
		}
		if(preg_match("/[0-9]/", $pwd) !== 1){
			return "Password must contain at least 1 digit character.";
		}
		return "";
	}
	public static function randomPassword($seeder = 0) {
		$dte = new DateTime();
		
		$seed = intval($dte->format('m')) +
				intval($dte->format('d')) +
				(intval($dte->format('Y')) *
				intval($dte->format('h')) *
				intval(intval($dte->format('i')) / 5)) +
				$seeder;
				
		srand($seed);
		$alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
		$pass = array();
		$alphaLength = strlen($alphabet) - 1;
		
		for ($i = 0; $i < 8; $i++) {
			$n = rand(0, $alphaLength);
			$pass[] = $alphabet[$n];
		}
		return implode($pass);
	}
	public static function randomKey($seeder = 0) {
		$dte = new DateTime();
		
		$seed = intval($dte->format('m')) +
				intval($dte->format('d')) +
				(intval($dte->format('Y')) *
				intval($dte->format('h')) *
				intval(intval($dte->format('i')) / 5)) +
				intval($dte->format('s')) +
				intval($dte->format('u')) +
				$seeder;
				
		srand($seed);
		$alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
		$pass = array();
		$alphaLength = strlen($alphabet) - 1;
		
		for ($i = 0; $i < 25; $i++) {
			$n = rand(0, $alphaLength);
			$pass[] = $alphabet[$n];
		}
		return implode($pass);
	}
	public static function getCompanyLogoFile($path,$coyid) {
		if (!file_exists($path . "/company_" . $coyid)) {
			mkdir($path . "/company_" . $coyid, 0777, true);
		}
		$files = Util::getFileList($path . "/company_" . $coyid,"logo*.*") ;
		if (count($files) > 0)
			return $files[0] ;
		else 
			return "";
	}
	public static function getCompanyPayNowQRFile($path,$coyid) {
		if (!file_exists($path .  $coyid)) {
			mkdir($path .  $coyid, 0777, true);
		}
		$files = Util::getFileList($path .  $coyid,"paynowqr.*") ;
		if (count($files) > 0)
			return $files[0] ;
		else 
			return "";
	}
	public static function getBULogoFile($path,$coyid) {
		if (!file_exists($path .  $coyid)) {
			mkdir($path .  $coyid, 0777, true);
		}
		//Log::write($path);
		$files = Util::getFileList($path .  $coyid,"bu_logo.*") ;
		if (count($files) > 0)
			return $files[0] ;
		else 
			return "";
	}
	public static function removeBULogoFile($path,$coyid) {
		$files = Util::getFileList($path . $coyid,"bu_logo.*") ;
		foreach ($files as $f) {
			$fn = $path .  $coyid. "\\" . $f ;
			if (file_exists($fn))
				unlink($fn) ;
		}
	}
	public static function removeAssetPicture($path) {
		$files = Util::getFileList($path) ;
		foreach ($files as $f) {
			$fn = $path. "\\" . $f ;
			if (file_exists($fn))
				unlink($fn) ;
		}
	}
	public static function removeCompanyPayNowQRFile($path,$coyid) {
		$files = Util::getFileList(PATH_PICTURE . $coyid,"paynowqr.*") ;
		foreach ($files as $f) {
			$fn = $path .  $coyid. "\\" . $f ;
			if (file_exists($fn))
				unlink($fn) ;
		}
	}
	public static function checkAccountingPeriodFormat($period) {
		$pattern = '/^\d{4}\/\d{3}$/';
		// Check if the string matches the pattern
		if (preg_match($pattern, $period)) {
		  	return true; // Valid format
		} else {
		  	return false; // Invalid format
		}
	}

	public static function sendNotificationToMobile($token,$title,$body,$screen,$type) {
		// log::write("token");
		// Log::write($token);
		// if(!is_null($token) && count($token) > 0) {
		// 	foreach($token as $device_token) {
			
		// 		log::write($device_token[EmployeeTable::C_TOKEN]);
		// 		if(isset($device_token[EmployeeTable::C_TOKEN])) {
		// 			if($device_token[EmployeeTable::C_TOKEN]!=NULL && $device_token[EmployeeTable::C_TOKEN]!="") {

		// 				$fields = array(
		// 							"type" => "500",
		// 							"turn_off" => "y",
		// 						);

		// 				$fields = json_encode($fields);
						
		// 				$headers = array (
		// 								'Authorization: key=' . FcmRequest::KeyId,
		// 								'Content-Type: application/json'
		// 							);

		// 				$ch = curl_init();
		// 				curl_setopt($ch, CURLOPT_URL, FcmRequest::Url);
		// 				curl_setopt($ch, CURLOPT_POST, true);
		// 				curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		// 				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		// 				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		// 				curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

		// 				$result = curl_exec($ch);
						
						
		// 				if($result === false){
		// 					$response = curl_error($ch);
		// 				}

		// 				curl_close($ch);
		// 			}
		// 		}
		// 	}
		// }
	}
}
?>