<?php
/**
 * This file is part of Wemag Dashboard Management.
 *
 * Wemag Dashboard Management is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Wemag Dashboard Management is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Wemag Dashboard Management.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Copyright 2008 Aart-Jan Boor <aart-jan@wemag.nl>
 * Wemag Advisering <http://www.wemag.nl>
 */
/**
 * This dashlet contains only logic, and is never shown, but is executed every time
 * a dashboard is loaded.
 * It has been created to intercept users without a dashboard
 * so that they can be given a default dashboard.
 *
 */
class ResetDashboardDashlet extends KTBaseDashlet
{
	function ResetDashboardDashlet()
	{
		require_once(KT_DIR . "/thirdparty/pear/JSON.php");

		// no title needed as the dashlet will never be displayed anyway
		$this->sTitle = "";

		/*
		 * Inside the code below, we might create new instances
		 * of this very class. So if we run the code below at all
		 * times, we will get in an unending loop, so we use a global
		 * to prevent this.
		 */
		if($GLOBALS['wemag-dashboard-dashlet-prevent-state-logic']!=1){
			$GLOBALS['wemag-dashboard-dashlet-prevent-state-logic']=1;
				
			$this->oUser = User::get($_SESSION['userID']);
			//find out if the dashboard state is set for this user
			//this is not true if this is the first login of the user
			$current_state = KTUtil::getSystemSetting($this->_getDashboardStateKey());
			if(PEAR::isError($current_state) || $current_state==''){
				//no current dashboard state, so lets set the default one.
				//first see if there actually is a default state
				$default_state = KTUtil::getSystemSetting("wemag-dashboard-management-default-dashboard");
				if(!PEAR::isError($default_state)){
					//Update the current users state with the (validated) default state.
					KTUtil::setSystemSetting($this->_getDashboardStateKey(),$this->_makeDashboardStateValid($default_state));
				}
			}else{ //user already has a dashboard state
				//Find out if any new dashlets have been installed.
				//if there are new dashlets, we will need to update
				//the users dashboard state because KT will, if we don't.
				KTUtil::setSystemSetting($this->_getDashboardStateKey(),$this->_makeDashboardStateValid($current_state));
			}
			$GLOBALS['wemag-dashboard-dashlet-prevent-state-logic']=0;
		}

	}

	/**
	 * Compares $state to the availble dashlets for current user
	 * in the dashlet registry, and makes sure the two are in
	 * alignment, so that the state will be accepted as a valid
	 * one by KT.
	 *
	 * @param string $state The state to compare in JSON format
	 */
	function _makeDashboardStateValid($state){
		$oJSON = new Services_JSON();

		$this->_debug($state,0,"Starting state");
		/*
		 * first we're going to build an array with the class names
		 * of the dashlets in the current state
		 */
		$aDashlets = $oJSON->decode($state);
		//$this->_debug($aDashlets);

		if (!isset($aDashlets->left)){
			$aDashlets->left = array();
		}
		if (!isset($aDashlets->right)){
			$aDashlets->right = array();
		}
		$aMergedList = array_merge($aDashlets->left,$aDashlets->right);
		$aCurrentList = $this->_dashletListToClassNameList($aMergedList);
		$this->_debug($aCurrentList,0,"current list");
		/*
		 * Get an array with all the widgets availble
		 * to the user
		 */
		$aAvailableList = $this->_getAvailableDashlets();
		$this->_debug($aAvailableList,0,"available list");

		/**
		 * Remove dashlets from current state that aren't actually available
		 */
		$aNA = array_diff($aCurrentList,$aAvailableList);
		$this->_debug($aNA,0,"dashlets to be removed");
		foreach($aNA as $sDashlet){
			$c=0;
			$found = false;
			while($found == false && $c<count($aDashlets->right)){
				if($aDashlets->right[$c]->id == $sDashlet){
					unset($aDashlets->right[$c]);
					$found = true;
				}
				$c++;
			}
			$c=0;
			$found = false;
			while($found == false && $c<count($aDashlets->left)){
				if($aDashlets->left[$c]->id == $sDashlet){
					unset($aDashlets->left[$c]);
					$found = true;
				}
				$c++;
			}
		}

		$this->_debug($aDashlets,0,"dashlets after removing");

		/**
		 * Add the missing dashlets
		 */
		$aMissingDashlets = array_diff($aAvailableList,$aCurrentList);
		$this->_debug($aMissingDashlets,0,"dashlets to be added");
		$column=0;
		$right_count = count($aDashlets->right);
		$left_count = count($aDashlets->left);
		if($right_count>$left_count){
			$column=1;
		}
		$autoAddNewDashletsSetting = KTUtil::getSystemSetting("wemag-dashboard-management-plugin-auto-add-new-dashlets");
		foreach($aMissingDashlets as $sDashlet){
			//check for the visibility setting
			$dashlet = new stdClass();
			$dashlet->id=$sDashlet;
			if($autoAddNewDashletsSetting == "true"){
				$dashlet->state = 0;
			}else{
				$dashlet->state = 2;
			}
			if($column==0){
				$aDashlets->left[$left_count]=$dashlet;
				$left_count++;
				$column=1;
			}else{
				$aDashlets->right[$right_count]=$dashlet;
				$right_count++;
				$column=0;
			}
		}
		//Make sure that the keys are nice in order so they wont appear in the JSON
		$aDashlets->right = array_merge(array(),$aDashlets->right);
		$aDashlets->left = array_merge(array(), $aDashlets->left);

		$this->_debug($aDashlets,0,"dashlets after adding");

		$state = $oJSON->encode($aDashlets);
		$this->_debug($state,0,"resulting state");
		return $state;
	}

	/**
	 * Turns a list with dashlet objects/stdClass objects with ids into an array with dashlet class names
	 *
	 * @param array $aDashletList
	 */
	function _dashletListToClassNameList($aDashletList){
		$aCNList = array();
		foreach($aDashletList as $oDashlet)
		{
			if($oDashlet->id != null){
				$aCNList[] = $oDashlet->id;
			}else{
				$aCNList[] = get_class($oDashlet);
			}
		}
		return $aCNList;
	}

	/**
	 * Retrieves avaible dashlets for current user from the dashlet registry.
	 *
	 * @return array available dashlets
	 */
	function _getAvailableDashlets(){
		$dashletRegistry = & KTDashletRegistry::getSingleton();
		$aDashlets = $dashletRegistry->getDashlets($this->oUser);
		return $this->_dashletListToClassNameList($aDashlets);
	}

	/**
	 * @return string the key in the system_settings table for this users dashboard
	 */
	function _getDashboardStateKey(){
		return "dashboard-state-".$this->oUser->iId;
	}

	/**
	 * Function is called to find out if the dashlet should be displayed to the user
	 * as this dashlet only has logic and no presentation, this is of course
	 * never the case
	 *
	 * @param User $oUser user object
	 * @return false
	 */
	function is_active($oUser)
	{
		//never show the dashlet, it doesn't have any content anyways.
		return false;
	}

	/**
	 * Render the dashlet content
	 *
	 * @return string content
	 */
	function render()
	{
		return "No content";
	}

	/**
	 * Used for debugging purposes
	 *
	 * @param $obj object to dump
	 * @param $exit if true, script will terminate
	 * @param $txt text to describde dump
	 */
	function _debug($obj,$exit = true, $txt = ""){
		/*echo "<h2>".$txt."</h2>";
		 echo "<pre>";
		 var_dump($obj);
		 echo "</pre>";
		 if($exit == true ){
			exit;
			}*/
	}
}
?>
