<?php


class User {
 	private $file;
 	var $userInfo;
 	const YES = "yes";
 /*	private const BLOCKED = 1;
 	private const DELETED = 1;*/
 	
	static private $instance=null;

	public static function getInstance(){
		if(self::$instance==null) self::$instance = new User();
		return self::$instance;
	}	 	

	public function __construct(){
		$this->file = new File();
		$indexes = new Indexes(Config::get("private_system_indexes_path"));
	}

	function getConfig($output=true){
	 	
	 	$configObj = (object) array();
	 	$configObj->drives = (object) array();

	 	if($this->userInfo->privilegies->full_file_access==true)
	 		$configObj->drives->server = true;
	 	$configObj->drives->public = true;
	 	$configObj->drives->private = true;
	 	
	 	
	 	$configObj->userInfo = $this->userInfo;
	 	
	 	// file extensions description	 
	 	$extDesXmlStr = Util::readFile("resources/extensionsDescription/english.txt");
	 	if($extDesXmlStr!==false)
	 		$configObj->extensionsDescription = WddxSerializer::deserialize($extDesXmlStr);
	 	
	 	// display properties
		$dpXmlSrt = Util::readFile(Config::get("private_system_path")."/config/users/".$this->userInfo->username."_dp.txt");
	 	if($dpXmlSrt!==false)
	 		$configObj->displayProperties = DataSerializer::deserialize($dpXmlSrt);
	 	 	
	 	// aplication association
		$aaXmlSrt = Util::readFile(Config::get("private_system_path")."/config/users/".$this->userInfo->username."_aa.txt");
	 	if($aaXmlSrt!==false)
	 		$configObj->applicationAssociation = DataSerializer::deserialize($aaXmlSrt);
		
		// aplication states
		$asXmlPath = Config::get("private_system_path")."/config/users/".$this->userInfo->username."_as.txt";
		if(is_file($asXmlPath)){
			$asXmlSrt = Util::readFile($asXmlPath);
		 	if($asXmlSrt!==false){
		 		$configObj->applicationStates = DataSerializer::deserialize($asXmlSrt);
		 	}
		}else{
	 		Util::writeFile($asXmlPath, DataSerializer::serialize((object) array()));
	 		$configObj->applicationStates = (object) array();
	 	}
	 		
	 	// theme
	 	$themeXmlStr = Util::readFile("resources/themes/".$configObj->displayProperties->theme);
	 	if($themeXmlStr!==false)
	 		$configObj->theme = WddxSerializer::deserialize($themeXmlStr);
	 
	 	// User language
	 	$configObj->languageData = Languages::getInstance()->getLanguage((object) array("language"=>$this->userInfo->language), false);

	 	// default language
		$configObj->defaultLanguageData = Languages::getInstance()->getLanguage((object) array("language"=>"__default"), false, true);
	 
	 			
	 	// all aplications
		$applXmlSrt = Util::readFile(Config::get("private_system_path")."/modules/applicationsInfo.xml");
	 	if($applXmlSrt!==false)
	 		$configObj->applicationsInfo = WddxSerializer::deserialize($applXmlSrt);
	 		
	 	// get keys
		/* 	for ($i=0; $i<count($configObj->applicationsInfo); $i++){
		 		if(!empty($configObj->applicationsInfo[$i]->directoryName)){
		 		 	$filePath = Config::get("private_system_path")."/modules/".$configObj->applicationsInfo[$i]->directoryName."/key.txt";
		 			if(is_file($filePath)){
		 				$configObj->applicationsInfo[$i]->key = Util::readFile($filePath);
		 			}
		 		}
	
		 		// removing not allowed applications
		 		if($configObj->userInfo->privilegies->user_and_privilegies==false && !in_array($configObj->applicationsInfo[$i]->name,  $configObj->userInfo->applicationsArray) && $configObj->applicationsInfo[$i]->name!="FWindows"){
		 		 	array_splice($configObj->applicationsInfo, $i, 1);
		 		 	$i--;
		 		}
		 	}
	 	 */
	 	 
	 	/*if($configObj->userInfo->privilegies->user_and_privilegies==true){
	 		$configObj->applicationsCounter = $this->getApplicationsCounter();
	 	}*/
	
	 	// upgrades
	 	$configObj->upgradesInfo = Config::get("upgradesInfo");
	 	
	 	// application url
	 	$configObj->fwindowsURL = Config::get("fwindowsURL");
	 	$configObj->httpPublicURL = Config::get("httpPublicURL");
	 	$configObj->userHttpPublicURL = Config::get("httpPublicURL")."/".$this->userInfo->username;
	 	
	 	// fonts for embedding
		$fontsContent = Util::readFile(Config::get("private_system_fonts_path")."/fonts.txt");
	 	if($fontsContent!==false)
	 		$configObj->fonts = DataSerializer::deserialize($fontsContent);
	 
	 	
	 	// OSTALO DODJE OVDE
		
		if($output)
	 		Response::sendOKResponse($configObj);
	 	else
	 		return $configObj;

 	}
 	
 	// PUBLIC
 /*	public function setAnonymousConfig($d){
 		
 		$dynConfig = new DynamicConfigStorage(Config::get("private_system_path")."/config/system/anonymousConfig.txt");
		$dynConfig->setValue($d->variableName,$d->variableValue);
 		
 		Response::sendOKResponse((object) array());
 	}
 	*/
 	
 	private function getApplicationsCounter(){
 		
 		$ud = new UD();
 	 	$FaF = $ud->getFoldersAndFiles(Config::get("private_system_accounts_path"));
	 	if($FaF<0)
	 		return null;

		
	 	$applicationsCounter = array();
	 	for($i=0; $i<count($FaF); $i++){
	 		
	 		$userXml = Util::readFile(Config::get("private_system_accounts_path")."/".$FaF[$i]['name']);
	 		if($userXml!==false){
	 			$userObj = DataSerializer::deserialize($userXml);
	 			for($k=0; $k<count($userObj->applicationsArray); $k++){
		 			$applName = $userObj->applicationsArray[$k];
		 			$applicationsCounter[$applName] +=1;
	 			}
			}	
	 		
		}
		
		return $applicationsCounter;
 		
	}
	
	
	private function createUserFiles($username, $group){
	 
	 	// return group system access
	 	$groupObj = DataSerializer::deserialize(Util::readFile(Config::get("private_system_accountsGroups_path")."/".$group.".txt"));
		$systemAccess = $groupObj->privilegies->full_file_access;
		 
	 	$dppath = Config::get("private_system_path")."/config/users/".$username."_dp.txt";
	 	Util::copyFile("resources/templates/displayProperties.txt", $dppath);
	 	
	 	$applAssocPath = Config::get("private_system_path")."/config/users/".$username."_aa.txt";
	 	Util::copyFile("resources/templates/applicationAssociation.txt", $applAssocPath);
	 	
	 	//server
	 	if($systemAccess==true){
	 		Util::copyFile("resources/templates/Server.sc", Config::get("private_users_path")."/".$username."/Desktop/Server.sc");
	 		Util::copyFile("resources/templates/desktopShortCutsMaster.txt", Config::get("private_system_path")."/config/users/".$username."_dsc.txt");
		}else{
			Util::copyFile("resources/templates/desktopShortCuts.txt", Config::get("private_system_path")."/config/users/".$username."_dsc.txt");
		}
		//public
	 	Util::copyFile("resources/templates/Public.sc", Config::get("private_users_path")."/".$username."/Desktop/Public.sc");
	 	//private
	 	Util::copyFile("resources/templates/Private.sc", Config::get("private_users_path")."/".$username."/Desktop/Private.sc");
	 		
	 	// copy wallpapers
	 	Util::copyDir( "resources/wallpapers", Config::get("private_users_path")."/".$username."/System/Wallpapers" );
	 
	 	/*// copy fonts // DEPRECATED // FONTS ARE SHARED FOR ALL USERS
	 	Util::createDirectoryIfNotExist( Config::get("private_system_path")."/fonts/".$username);
	 	Util::createDirectoryIfNotExist( Config::get("private_system_path")."/fonts/".$username."/swf");
	 	Util::copyDir( "resources/fonts", Config::get("private_system_path")."/fonts/".$username);*/
	 	
	}
	
	private function removeUserFiles($username){

	 	Util::deleteFile(Config::get("private_system_path")."/config/users/".$username."_dp.txt");
	 	Util::deleteFile(Config::get("private_system_path")."/config/users/".$username."_aa.txt");
		Util::deleteFile(Config::get("private_system_path")."/config/users/".$username."_dsc.txt");
	 	Util::deleteFile(Config::get("private_system_path")."/config/users/".$username."_as.txt");
	 
	 	/*// copy fonts // DEPRECATED // FONTS ARE SHARED FOR ALL USERS
	 	Util::deleteDirectoryAndAllItsContent( Config::get("private_system_path")."/fonts/".$username, Config::get("system_path")."/fonts/".$username);
	 	*/
	}
	private function createUsersPrivateDirectories($username){
		global $config;
		
		$userRootDir = Config::get("private_users_path")."/".$username;
		if( Util::createDirectoryIfNotExist($userRootDir)){
			Util::createDirectoryIfNotExist($userRootDir."/ApplicationData");
			Util::createDirectoryIfNotExist($userRootDir."/Desktop");
			Util::createDirectoryIfNotExist($userRootDir."/MyDocuments");
			Util::createDirectoryIfNotExist($userRootDir."/RecycleBin");
			Util::createDirectoryIfNotExist($userRootDir."/RecycleBin/Files");
			Util::createDirectoryIfNotExist($userRootDir."/System");
			Util::createDirectoryIfNotExist($userRootDir."/System/Wallpapers");
			Util::createDirectoryIfNotExist($userRootDir."/System/Wallpapers/Thumbs");
			Util::createDirectoryIfNotExist($userRootDir."/Tmp");

			return true;
		}else{
			return false; 
		}
		
	}
	private function removeUsersPrivateDirectories($username){	
		global $config;
		if(strlen($username)>4){
			$userRootDir = Config::get("private_users_path")."/".$username;
			Util::deleteDirectoryAndAllItsContent($userRootDir, Config::get("private_users_path"));
		}
	}
	 
	private function createUsersPublicDirectories($username){
		global $config;
		
		$userRootDir = Config::get("public_path")."/".$username;
		if(Util::createDirectoryIfNotExist($userRootDir)){
			return true;
		}else{
			return false; 
		}
		
	}

	private function removeUsersPublicDirectories($username){	
		global $config;
		if(strlen($username)>4){
			$userRootDir = Config::get("public_path")."/".$username;
			Util::deleteDirectoryAndAllItsContent($userRootDir, Config::get("public_path"));
		}
	}

	
	// -------------------------------------
	// -------------------------------------
	public function editGroup($d){
		//required > groupName, username, password
		
		// check
	 	if(empty($d->groupName)){
			Response::sendResponse(false, null, "auth", "required_fields");
	 	}

		//create new user file(update old)	
		$groupFile = Config::get("private_system_accountsGroups_path")."/".$d->groupName.".txt";
		
		/*$this->installOrUninstallApplicatonsFroGroup($d);
		$this->updateApplicationAssociationforGroup($d);*/
		
		if(!Util::writeFile($groupFile, DataSerializer::serialize(Util::cloneObject($d)))){
			Response::sendResponse(false, null, "file", "write_error");
		}
		
		// >>>>>>>>>>>>>>>>>>>>>>>>>>>
		// add additional applications
	//	$this->updateApplicationAssociation($d);
		// add additional applications
	 	// <<<<<<<<<<<<<<<<<<<<<<<<<<<

		// send response
		Response::sendResponse(true, $d, "auth", "suc_group_edit");

 	}

	public function registerGroup($d){
		//required > groupName
		
		// check
	 	if(empty($d->groupName)){
			Response::sendResponse(false, null, "auth", "required_fields");
	 	}

		$groupFile = Config::get("private_system_accountsGroups_path")."/".$d->groupName.".txt";
		if(is_file($groupFile)){
		 	Response::sendResponse(false, null, "auth", "group_exist");
		}

		
		//create new user file
		$groupData = Util::cloneObject($d);
		$groupData->language = "English";

		if(!Util::writeFile($groupFile, DataSerializer::serialize($groupData))){
			Response::sendResponse(false, null, "file", "write_error");
		}
		
		// update (create new) applcaition association file for this group
	//	$this->updateApplicationAssociation($d->groupName, $d->applicationsArray, true);
		
		
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
		// send response
		Response::sendResponse(true, $retObj, "auth", "suc_reg_group");

 	}

	public function registerUser($d){
		//required > fullName, username, password
		
		// check
	 	if(empty($d->fullName) || empty($d->username) || empty($d->password) || empty($d->group) || empty($d->email)){
			Response::sendResponse(false, null, "auth", "required_fields");
	 	}
		if(strlen($d->username)<5){
		 	Response::sendResponse(false, null, "auth", "username_length");
		}
		if(strlen($d->password)<5){
		 	Response::sendResponse(false, null, "auth", "password_length");
		}
		if($d->password!=$d->password2){
		 	Response::sendResponse(false, null, "auth", "password_confirm");
		}

		$userFile = Config::get("private_system_accounts_path")."/".$d->username.".txt";
		if(is_file($userFile)){
		 	Response::sendResponse(false, null, "auth", "username_exist");
		}

		
		//create new user file
		$userData = Util::cloneObject($d);
		$userData->language = "English";
		unset($userData->password2);
		if(!Util::writeFile($userFile, DataSerializer::serialize($userData))){
			Response::sendResponse(false, null, "file", "write_error");
		}
		
		$this->createUsersPrivateDirectories($d->username);
		$this->createUsersPublicDirectories($d->username);
		$this->createUserFiles($d->username, $d->group);
		
		
		$this->updateAllApplicationAssociation($d->username);
		$this->copyAllApplicationsUserFiles($d->username);
		// >>>>>>>>>>>>>>>>>>>>>>>>>>>
		// add additional applications
		//$this->updateApplicationAssociation($d);
		// add additional applications
	 	// <<<<<<<<<<<<<<<<<<<<<<<<<<<
		
		// make index

		Indexes::setValue("group_user", $d->group, $d->username);
		Indexes::setValue("user_group", $d->username, $d->group);
		
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
		// send response
		Response::sendResponse(true, $retObj, "auth", "suc_reg");

 	}

	public function editUser($d){
		//required > fullName, username, password
		
		// check
	 	if(empty($d->fullName) || empty($d->username) || empty($d->password) || empty($d->group)){
			Response::sendResponse(false, null, "auth", "required_fields");
	 	}
		if(strlen($d->username)<5){
		 	Response::sendResponse(false, null, "auth", "username_length");
		}
		if(strlen($d->password)<5){
		 	Response::sendResponse(false, null, "auth", "password_length");
		}
		if($d->password!=$d->password2){
		 	Response::sendResponse(false, null, "auth", "password_confirm");
		}


		//create new user file(update old)	
		$userFile = Config::get("private_system_accounts_path")."/".$d->username.".txt";
		$userData = Util::cloneObject($d);

		if(!Util::writeFile($userFile, DataSerializer::serialize($userData))){
			Response::sendResponse(false, null, "file", "write_error");
		}
		
		// >>>>>>>>>>>>>>>>>>>>>>>>>>>
		// add additional applications
		//$this->updateApplicationAssociation($d);
		// add additional applications
	 	// <<<<<<<<<<<<<<<<<<<<<<<<<<<
	 	
	
		Indexes::updateValue("group_user", $d->group, $d->username);	
		Indexes::updateValueByKeyOnePerOne("user_group", $d->username, $d->group);

	 	$retObj = $this->getAllGroupsAndUsersIndexes(false);

		/*if($d->username == $this->userInfo->username)
	 		$retObj->config = $this->getConfig(false);*/
			 	 		
		// send response
		Response::sendResponse(true, $retObj, "auth", "suc_edit");

 	}

	// PUBLIC
	// only one deletion per request // to do multiple
	public function removeGroups($d){ 
		 // only one deletion per request // to do multiple
		$groupName = $d->groups[0];

		if($groupName=="Master" || $groupName=="Anonymous" )
			Response::sendResponse(true, null, "auth", "a_cannot_delete_system_group");
		
	/*	print_r(Indexes::getValues("group_user"));
		print_r(Indexes::getValues("user_group"));
		print_r(Indexes::getValues("deletedUser"));
		print_r(Indexes::getValues("blockedUser"));
		print_r(Indexes::getValues("deletedGroups"));
		print_r(Indexes::getValues("blockedGroups"));
		
		return;
		*/

		
		$usersInGroup = Indexes::getValue("group_user", $groupName);

		if(count($usersInGroup)>0){
			 Response::sendResponse(false, $retObj, "auth", "a_group_not_empty_cannot_del");
		 }
		
		
		// first remove all users in group
	/*	$reqObj = (object) array();
		$reqObj->users = $usersInGroup;
		$allUsersRemoved = $this->removeUsers($reqObj);
		
		if($allUsersRemoved==false){
			Response::sendResponse(false, $retObj, "auth", "a_cannot_delete_all_in_group");
		}*/
	
		$groupFile = Config::get("private_system_accountsGroups_path")."/".$groupName.".txt";
		$groupToDelInfo = DataSerializer::deserialize(Util::readFile($groupFile));

		// delete user file
		if(!Util::deleteFile($groupFile))
			Response::sendResponse(false, null, "auth", "a_cannot_delete_group");
			
		// remove index
		Indexes::removeValueByKeyValue("blockedGroups", $groupToDelInfo->groupName, YES);
		Indexes::removeValueByKeyValue("deletedGroups", $groupToDelInfo->groupName, YES);
		
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
		//$retObj->allExecuted = $allExecuted;

	 	Response::sendResponse(true, $retObj, "auth", "suc_deleted_group");

	}
	
	// PUBLIC
	public function removeUsers($d, $output=true){

		$allExecuted = true;	
		foreach ($d->users as $key=>$value){
			$exec = $this->removeUser($d->users[$key]);
			$allExecuted = ($allExecuted &&  $exec);
		}
	
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
		$retObj->allExecuted = $allExecuted;
		
		if($output){
			if($allExecuted)
	 			Response::sendResponse(true, $retObj, "auth", "suc_deleted_user");
			else
				Response::sendResponse(true, $retObj, "auth", "suc_deleted_user_with_exeption");
		}
		else{
			return $retObj;
		}	
	}

	private function removeUser($username){

	 	if($username==$this->userInfo->username)
	 	 	return false;
	 	
	 	
	 	/*if(!Priv::getUserPermission($d->username))
	 		Response::sendResponse(false, null, "priv", "cannot_delete");*/
		$userFile = Config::get("private_system_accounts_path")."/".$username.".txt";
		$userToDelInfo = DataSerializer::deserialize(Util::readFile($userFile));

		if($userToDelInfo->firstMaster===true){
			// echo "a";
			return false;
		}
		
		// delete user file
		if(!Util::deleteFile($userFile)){
			// echo "b";
			return false;
			
		}
		
		// remove index
		Indexes::removeValueByKeyValue("group_user", $userToDelInfo->group, $userToDelInfo->username);	
		Indexes::removeValueByKeyValue("user_group", $userToDelInfo->username, $userToDelInfo->group);
		Indexes::removeValueByKeyValue("blockedUsers", $userToDelInfo->username, YES);
		Indexes::removeValueByKeyValue("deletedUsers", $userToDelInfo->username, YES);
		
		
		$this->removeUsersPrivateDirectories($username);
		$this->removeUsersPublicDirectories($username);
		$this->removeUserFiles($username);
		
		return true;
		
	}

	// PUBLIC
	public function blockGroups($d){
	 	
		foreach ($d->names as $key=>$value){
			$this->blockGroup($d->names[$key], $d->flag);
		}
	
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
	 	
		if($d->flag==true)
	 		Response::sendResponse(true, $retObj, "auth", "suc_block_user_flag");
	 	else
			Response::sendResponse(true, $retObj, "auth", "suc_unblock_user_flag");
			
	}
	private function blockGroup($group, $flag){
	 	
	 	if($group==$this->userInfo->group || $group=="Master"){
	 	 	return;
	 	}
	 
	 	if($flag == true)
	 		Indexes::setValue("blockedGroups", $group, YES);
	 	else 
	 		Indexes::removeValueByKeyValue("blockedGroups", $group, YES);
	 	
	}
	// PUBLIC
	public function setDeletedFlagToGroups($d){
	 	
		foreach  ($d->names as $key=>$value){
			$this->setDeletedFlagToGroup($d->names[$key], $d->flag);
		}
		
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
		
		if($d->flag==true)
	 		Response::sendResponse(true, $retObj, "auth", "suc_deleted_group_flag");
	 	else
			Response::sendResponse(true, $retObj, "auth", "suc_undeleted_group_flag");
			
	}
	private function setDeletedFlagToGroup($group, $flag){
	
	 	if($group==$this->userInfo->group || $group=="Anonymous" || $group=="Master"){
	 	 	return;
	 	}
 		
	 	if($flag==true){
	 		Indexes::setValue("deletedGroups", $group, YES);
	 	}
	 	else{
	 		Indexes::removeValueByKeyValue("deletedGroups", $group, YES);
	 	}
	 		
	}
	// PUBLIC
	public function blockUsers($d){
	 	
	 	$allExecuted = true;
		foreach ($d->names as $key=>$value){
		 	$exec = $this->blockUser($d->names[$key], $d->flag);
			$allExecuted = ($allExecuted && $exec);
		}
	
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
		//$retObj->allExecuted = $allExecuted;
		
		if($d->flag==true)
			if($allExecuted)
	 			Response::sendResponse(true, $retObj, "auth", "suc_block_user_flag");
	 		else 
	 			Response::sendResponse(true, $retObj, "auth", "suc_block_user_flag_with_exception");	
	 	else
			Response::sendResponse(true, $retObj, "auth", "suc_unblock_user_flag");
			
	}
	private function blockUser($username, $flag){
	 	
	 	if($username==$this->userInfo->username){
	 	 	return false;
	 	}
	 	
		$userFile = Config::get("private_system_accounts_path")."/".$username.".txt";
		$userToBlockInfo = DataSerializer::deserialize(Util::readFile($userFile));

		if($userToBlockInfo->firstMaster==true)
			return false;
	 
	 	if($flag == true)
	 		Indexes::setValue("blockedUsers", $username, YES);
	 	else 
	 		Indexes::removeValueByKeyValue("blockedUsers", $username, YES);
	 		
	 	return true;
	 	
	}

	// PUBLIC
	public function setDeletedFlagToUsers($d){
	 	
		$allExecuted = true;
		foreach  ($d->names as $key=>$value){
				$exec = $this->setDeletedFlagToUser($d->names[$key], $d->flag);
				$allExecuted = ($allExecuted && $exec);
		}
		
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
		//$retObj->allExecuted = $allExecuted;
		
		if($d->flag==true)
			if($allExecuted)
	 			Response::sendResponse(true, $retObj, "auth", "suc_deleted_user_flag");
	 		else
	 			Response::sendResponse(true, $retObj, "auth", "suc_deleted_user_flag_with_exception");	
	 	else
			Response::sendResponse(true, $retObj, "auth", "suc_undeleted_user_flag");
			
	}
	private function setDeletedFlagToUser($username, $flag){
	
		if($username==$this->userInfo->username){
 	 		return false;
 		}
 		
 		$userFile = Config::get("private_system_accounts_path")."/".$username.".txt";
		$userToDelInfo = DataSerializer::deserialize(Util::readFile($userFile));

		if($userToDelInfo->firstMaster==true){
			return false;
		}
			
	 	if($flag==true){
	 		Indexes::setValue("deletedUsers", $username, YES);
	 	}
	 	else{
	 		Indexes::removeValueByKeyValue("deletedUsers", $username, YES);
	 	}
	 	return true;	
	}

	// PUBLIC
	// sign in if username/password match one of the users
 	public function signIn($d){
 	 	
 	 	$this->signOut();
 	 	
 	 	$userFile = Config::get("private_system_accounts_path")."/".$d->username.".txt";

 	 	if(!is_file($userFile)){
 	 		Response::sendResponse(false, null, "auth", "wrong_username");
		}
		
 	 	//retrive user data	
 	 	$userInfo = DataSerializer::deserialize(Util::readFile($userFile));
 	 	
 	 	//md5
 	 	if(Config::get("md5_password")){
			$d->password=md5($d->password);
		}
		
 	 	if($d->password!=$userInfo->password){
 	 		Response::sendResponse(false, null, "auth", "wrong_password");
 	 	}
 	 	
 	 	// clear password for security
 	 	unset($userInfo->password);
 
 		// adding droup data
 		$groupFile = Config::get("private_system_accountsGroups_path")."/".$userInfo->group.".txt";
 		$groupInfo = DataSerializer::deserialize(Util::readFile($groupFile));
 		foreach($groupInfo as $k => $v) $userInfo->$k = $v;

 		//start session
 		session_id(md5(microtime().(round(rand()*10000))));
 		session_start();
 		$this->setSessionData($userInfo);
 		$userInfo->session = session_id();
 		
		// send response
		Response::sendResponse(true, $userInfo, "auth", "suc_signin");
		
 	}

	// PUBLIC
 	public function signOut(){
		session_start();
		session_destroy();
 	}
 	
	// PUBLIC
 	public function isSignedIn($session){
 	 	
	  	if(empty ($session)){ 
		  Response::sendResponse(false, null, "auth", "no_session");
		}
		
		session_id($session);
		session_start();
		
		$sessionData = $this->getSessionData();
	
		$userFile = Config::get("private_system_accounts_path")."/".$sessionData->username.".txt";
		if(!is_file($userFile)){
		 	$this->signOut();
		 	Response::sendResponse(false, null, "auth", "not_singin");
		}
		
		$this->userInfo = DataSerializer::deserialize(Util::readFile($userFile));
		unset($this->userInfo->password);
		
		// adding droup data
 		$groupFile = Config::get("private_system_accountsGroups_path")."/".$this->userInfo->group.".txt";
 		$groupInfo = DataSerializer::deserialize(Util::readFile($groupFile));
 		foreach($groupInfo as $k => $v) $this->userInfo->$k = $v;
		

		return true;
		
	}
	
	// PUBLIC	
	public function getGroup($groupName){
	 	  
		$groupFile = Config::get("private_system_accountsGroups_path")."/".$groupName.".txt";
 	 	if(!is_file($groupFile)){
 	 		Response::sendResponse(false, null, "auth", "group_doesnot_exist");
		}
		
		$groupInfo = DataSerializer::deserialize(Util::readFile($groupFile));
		
		// clear password for security
 	 	//unset($userInfo->password);
 	 	
		Response::sendOKResponse($groupInfo);
	}
	
	// PUBLIC	
	public function getUser($username){
	 	  
		$userFile = Config::get("private_system_accounts_path")."/".$username.".txt";
 	 	if(!is_file($userFile)){
 	 		Response::sendResponse(false, null, "auth", "user_doesnot_exist");
		}
		
		$userInfo = DataSerializer::deserialize(Util::readFile($userFile));
		
		// clear password for security
 	 	// unset($userInfo->password);
 	 	
		Response::sendOKResponse($userInfo);
	}
	
	// PUBLIC
	public function getUsersPanelInfo($output=true){
		$retObj = $this->getAllGroupsAndUsersIndexes(false);
	
		/*
		$dynConfig = new DynamicConfigStorage(Config::get("private_system_path")."/config/system/anonymousConfig.txt");
		$retObj->anonymousAllow = $dynConfig->getValue("anonymousAllow");
 		$retObj->anonymousEmailConfirm = $dynConfig->getValue("anonymousEmailConfirm");
 		$retObj->anonymousVerificationImage = $dynConfig->getValue("anonymousVerificationImage");
 		*/
 		
 		Response::sendOKResponse($retObj);
		
	}
	 
	// PUBLIC	
	public function getAllGroupsAndUsersIndexes($output=true){
	 	
	 	$retObj = (object) array();
	 	$retObj->groups =  $this->file->getFoldersAndFiles(Config::get("private_system_accountsGroups_path"));
		$retObj->group_user =  Indexes::getValues("group_user");
		$retObj->user_group =  Indexes::getArray("user_group");
		$retObj->blockedUsers =  Indexes::getArray("blockedUsers");
		$retObj->blockedGroups =  Indexes::getArray("blockedGroups");
		$retObj->deletedUsers =  Indexes::getArray("deletedUsers");
		$retObj->deletedGroups =  Indexes::getArray("deletedGroups");

		if($output)
			Response::sendOKResponse($retObj);
		else 
			return $retObj;
		
	}
	// PUBLIC
	public function getAllGroups(){
	 	
	 	$FaF = $this->file->getFoldersAndFiles(Config::get("private_system_accountsGroups_path"));
	 	if($FaF<0){
	 		Response::sendErrorResponse($this->file->getErrorID($FaF), $this->file->getErrorMsg($FaF));
		}
		Response::sendOKResponse($FaF);
		
	}


	
	// PUBLIC
	public function getAllUsers(){
	 	
	 	$FaF = $this->file->getFoldersAndFiles(Config::get("private_system_accounts_path"));
	 	if($FaF<0){
	 		Response::sendErrorResponse($this->file->getErrorID($FaF), $this->file->getErrorMsg($FaF));
		}
		Response::sendOKResponse($FaF);
		
	}
 	public function getAllUsersCount(){
 	 	$FaF = $this->file->getFoldersAndFiles(Config::get("private_system_accounts_path"));
 		return count($FaF);
	}
 	
 
 	// PUBLIC 
 	public function getAccountsAndPrivilegiesArray(){
	
		$data = (object) array();
		
		$data->privilegiesArray = Privilegies::$privilegiesArray;
		$data->mustHaveApplicationsArray = Privilegies::$mustHaveApplicationsArray;
		$data->extensionsArray = Privilegies::$extensionsArray;
	
		$applicationsInfo = WddxSerializer::deserialize(Util::readFile(Config::get("private_system_path")."/modules/applicationsInfo.xml"));
		for($i=0; $i<count($applicationsInfo); $i++){
			if(!empty($applicationsInfo[$i]->clazz))
				$data->applicationsArray[] = $applicationsInfo[$i]->name;
		}
		
		Response::sendOKResponse($data);
	}
		
	public function addApplicationToUserInfo($applName){
	 	
	 	$userInfo = $this->getUserInfo(true);
	 	if(is_array($userInfo->applicationsArray)){
			$userInfo->applicationsArray[] = $applName;
			$userFile = Config::get("private_system_accounts_path")."/".$userInfo->username.".txt";
			Util::writeFile($userFile, DataSerializer::serialize($userInfo));
		}
	
	}
	
  	public function getUserInfo(){
		
		$userInfo = $this->getUserInfoWithPassword();
		unset($userInfo->password);
		return $userInfo;
		
 	}

 	private function getUserPassword(){
	  	$userInfo = $this->getUserInfoWithPassword();
 		return $userInfo->password;
 	}
 	
	private function getUserInfoWithPassword(){
 	 	
 	 	$userInfo = $this->getSessionData();
 	 
		$userFile = Config::get("private_system_accounts_path")."/".$userInfo->username.".txt";
 	 	if(!is_file($userFile)){
 	 		return false;
		}
		
		$userInfo = DataSerializer::deserialize(Util::readFile($userFile));
 	 	
		unset($userInfo->password);
 	 	
		return $userInfo;
		
 	}
	
	
	// update user application-asociation with all (external modules) applications file extensions
	// not service method
	public function updateAllApplicationAssociation($username, $applName=null){

		$applicationsInfo = WddxSerializer::deserialize(Util::readFile(Config::get("private_system_path")."/modules/applicationsInfo.xml"));
	 	$applicationAssociation = DataSerializer::deserialize(Util::readFile(Config::get("private_system_path")."/config/users/".$username."_aa.txt"));
		$desktopShortcuts = DataSerializer::deserialize(Util::readFile(Config::get("private_system_path")."/config/users/".$username."_dsc.txt"));
		
	 	for($i=0; $i<count($applicationsInfo); $i++){
	 	 	if($applName!=null && $applicationsInfo[$i]->name!=$applName){
		 		continue; 
			}
		
			$applInfo = $applicationsInfo[$i];
			 	
	 	 	$re = $applicationsInfo[$i]->recommendedExtensions;
	 		if(!empty($applicationsInfo[$i]->externalSWF) && is_array($re)){
	 			for($k=0; $k<count($re); $k++){
	 			 	$ext = $re[$k];
	 				$applicationAssociation->$ext = $applicationsInfo[$i]->name;
	 			}
	 		}

	 		// update desktop icon
		 	if($applInfo->desktopShortcut){
		 	 	$dsc = (object) array();
				$dsc->name = $applInfo->desktopShortcut->name;
				$dsc->x = $applInfo->desktopShortcut->x;
				$dsc->y = $applInfo->desktopShortcut->y;
				$exist = false;
				for($k=0; $k<count($desktopShortcuts); $k++){
					if($desktopShortcuts[$k]->name == $dsc->name ){
						$desktopShortcuts[$k]->x = $dsc->x;
						$desktopShortcuts[$k]->y = $dsc->y;
						$exist = true;
					}
				}
				if(!$exist){
					 $desktopShortcuts[] = $dsc;
				}
			}
	 	}
	 	
	 
		
		Util::writeFile(Config::get("private_system_path")."/config/users/".$username."_aa.txt", DataSerializer::serialize($applicationAssociation));
		Util::writeFile(Config::get("private_system_path")."/config/users/".$username."_dsc.txt", DataSerializer::serialize($desktopShortcuts));
		
	}
	// not service method
	public function copyAllApplicationsUserFiles($username, $applName=null){

		$applicationsInfo = WddxSerializer::deserialize(Util::readFile(Config::get("private_system_path")."/modules/applicationsInfo.xml"));
		
		for($i=0; $i<count($applicationsInfo); $i++){
		 	if($applName!=null && $applicationsInfo[$i]->name!=$applName){
		 		continue; 
			}
		 	$uf = $applicationsInfo[$i]->userFiles;
			if(is_array($uf)){
				for($k=0; $k<count($uf); $k++){
					$fromAbsolute = Config::get("private_system_path")."/modules/".$uf[$k]->from;
					
					$toPath = $uf[$k]->to;
					$toDrive = Util::getDriveFromPath($toPath);
					$toRelPath = Util::getRelativePathFromPath($toPath);
 	  
 	 				$toDriveAbsPath = UserFileSystem::getInstance()->getDriveRootDir($toDrive, $username);
 	 				$toRealPath = $toDriveAbsPath .  $toRelPath ;
 	 				if($uf[$k]->type=="file"){
						$this->file->createAbsolutePath($toDriveAbsPath, substr($toRelPath , 0, strrpos($toRelPath , "/")));
						Util::copyFile($fromAbsolute, $toRealPath);
					}else if($uf[$k]->type=="dir"){
					 	$this->file->createAbsolutePath($toDriveAbsPath, $toRelPath);
					}
			
				}
			}
		}
	}
	
	/*
	private function updateApplicationAssociation($d){
		
		$applicationsInfo = WddxSerializer::deserialize(Util::readFile(Config::get("private_system_path")."/modules/applicationsInfo.xml"));
	 	$applicationAssociation = DataSerializer::deserialize(Util::readFile("resources/templates/applicationAssociation.txt"));
	 	for($i=0; $i<count($d->applicationsArray); $i++){
			if(!in_array($d->applicationsArray[$i], Privilegies::$mustHaveApplicationsArray)){
				for($k=0; $k<count($applicationsInfo); $k++){
					if($d->applicationsArray[$i]==$applicationsInfo[$k]->name){
						//add extensions
						$recExt = $applicationsInfo[$k]->recommendedExtensions;
						if(is_array($recExt)){
							for($n=0; $n<count($recExt); $n++){
							 	$ext = $recExt[$n];
								$applicationAssociation->$ext = $d->applicationsArray[$i];
							}
						}
					}
				}
			}
		}
		
		Util::writeFile(Config::get("private_system_path")."/config/".$d->username."_aa.txt", DataSerializer::serialize($applicationAssociation));
		
	}
	*/

	private function setSessionData($userInfo){
		$_SESSION["userInfo"] = $userInfo;
	}
	private function getSessionData(){
		return $_SESSION["userInfo"];
	}
	
	// session test
	public static function setTestSessionData($data){
		$_SESSION["test"] = $data;
	}
	public static function getTestSessionData(){
		return $_SESSION["test"];
	}
}