<?php
/***************************************************************************
 *                            class.planete.php
 *                           -------------------
 *   begin                : Jeudi 21 août 2008
 *   update               : Dimanche 7 septembre 2008
 *   email                : nemunaire@gmail.com
 *
 *
 ***************************************************************************/
class Planete extends User{
	var $id,
		$galaxie,
		$ss,
		$position,
		$isolement,
		$nom_planete,
		$image,
		$cases,
		$casesRest,
		$debris_met,
		$debris_cri,
		$metal,
		$cristal,
		$hydrogene,
		$alert_ressources = array(false, false, false),
		$timestamp,
		$energie,
		$energieConso,
		$file_tech,
		$file_bat,
		$file_cas,
		$file_ter,
		$file_vais,
		$coeff_bat = array(),
		$batiments = array(),
		$casernes = array(),
		$terrestres = array(),
		$vaisseaux = array(),
		$modif = array('metal', 'cristal', 'hydrogene', 'timestamp');

	/**
	 * Constructeur
	 * @param    int	$id	id de la planète à importer
     *
     * @return   void
     * @access   public
	 */
	function Planete($id = 0){
		if (!empty($id)) {
			global $var___db, $config, $table_planete;
			global $batimentVAR, $casernenVAR, $nomterrnVAR, $nomvaisnVAR;
			$bdd = new bdd();
			$bdd->connexion();
			$bdd->escape($id);
			$plan = $bdd->unique_query("SELECT * FROM $table_planete WHERE id = $id;");
			$bdd->deconnexion();
			if (!empty($plan)) {
				$this->id = $plan["id"];
				parent::User($plan["id_user"]);
				$this->galaxie = $plan["galaxie"];
				$this->ss = $plan["ss"];
				$this->position = $plan["position"];
				$this->isolement = $plan["isolement"];
				$this->nom_planete = $plan["nom_planete"];
				$this->image = $plan["image"];
				$this->cases = $plan["cases"];
				$this->debris_met = $plan["debris_met"];
				$this->debris_cri = $plan["debris_cri"];
				$this->metal = $plan["metal"];
				$this->cristal = $plan["cristal"];
				$this->hydrogene = $plan["hydrogene"];
				$this->timestamp = $plan["timestamp"];

				foreach($batimentVAR as $bat){
					$this->batiments[] = $plan[$bat];
				}
				$this->file_bat = explode(';', $plan["file_bat"]);
				$this->coeff_bat = array($plan["coeff_mine_m"], $plan["coeff_mine_c"], $plan["coeff_mine_h"], $plan["coeff_centrale_s"], $plan["coeff_centrale_f"]);
				for($i = 0; $i < 5; $i++){
					if ($this->coeff_bat[$i] > 1) $this->coeff_bat[$i] = 1;
					elseif ($this->coeff_bat[$i] < 0) $this->coeff_bat[$i] = 0;
				}

				$this->file_tech = explode(';', $plan["file_tech"]);
				foreach($casernenVAR as $cas){
					$this->casernes[] = $plan[$cas];
				}
				$this->file_cas = explode(';', $plan["file_cas"]);
				foreach($nomterrnVAR as $ter){
					$this->terrestres[] = $plan[$ter];
				}
				$this->file_ter = explode(';', $plan["file_ter"]);
				foreach($nomvaisnVAR as $vais){
					$this->vaisseaux[] = $plan[$vais];
				}
				$this->file_vais = explode(';', $plan["file_vais"]);

				$this->actualiser();
			}
		}
	}

	/**
	 * Actualise les ressources de la planète en fonction de la production et termine les files d'attentes.
     *
     * @return   void
     * @access   public
	 */
	function actualiser($actuFile = true){
		//Calcul de la capacité de stockage maximale
		$cap = pow(2, $this->batiments[10]) * 100000;

		//Calcul du temps écoulé depuis la dernière mise à jour de la planète
		$temps_ecoule = time() - $this->timestamp;
		$ressources = $this->production($temps_ecoule);
		if ($this->metal + $ressources[0] < $cap) $this->metal += $ressources[0];
		else {
			$this->alert_ressources[0] = true;
			$this->metal = $cap;
		}
		if ($this->cristal + $ressources[1] < $cap) $this->cristal += $ressources[1];
		else {
			$this->alert_ressources[1] = true;
			$this->cristal = $cap;
		}
		if ($this->hydrogene + $ressources[2] < $cap) $this->hydrogene += $ressources[2];
		else {
			$this->alert_ressources[2] = true;
			$this->hydrogene = $cap;
		}
		$this->timestamp = time();

		//Actualisation des files d'attentes
		if ($actuFile) {
			$this->file_pret("batiments");
			$this->file_pret("technologies");
			$this->file_pret("casernes");
			$this->file_pret("terrestres");
			$this->file_pret("vaisseaux");
		}

		//Calcul du nombre de cases restantes
		$this->casesRest = $this->cases;
		foreach($this->batiments as $bat){
			$this->casesRest -= $bat;
		}
	}

	/**
	 * Vérifie si la planète est isolée ou non
     *
     * @return   boolean
     * @access   public
	 */
	function isolement(){
		$isolement = explode(' ', $this->isolement);
		$return = false;

		if (time() > $isolement[0]) {
			if (!isset($isolement[1]) || (time() > $isolement[1] && date('dmY') != date('dmY', $isolement[0]))) {
				$nbPlan = count($queryPlanetes);
				$numP = 0;
				for ($i=0 ; $i<$nbPlan ; $i++) {
					if ($queryPlanetes[$i]['id'] == $queryPlanete['id']) $numP = $i;
				}
				if ($numP > 10) {
					switch($numP){
						case 11: $tps = 2; break;
						case 12: $tps = 4; break;
						case 13: $tps = 6; break;
						case 14: $tps = 8; break;
						case 15: $tps = 12; break;
						case 16: $tps = 16; break;
						case 17: $tps = 20; break;
						default: $tps = 24;
					}
					$debut = mktime(rand(0, 24-$tps), 0, 0, date('n'), date('j'), date('Y'));
					$fin = $debut + $tps * 3600;

					$bdd->connexion();
					$bdd->query("UPDATE $table_planete SET isolement = '$debut $fin' WHERE id = '$idPlan';");
					$bdd->deconnexion();
					$isolement[0] = $debut;
					if (time() > $isolement[0]) $isolement[1] = $fin;
				}
			}
			$p = gpc('p');
			if (isset($isolement[1]) && time() < $isolement[1]) {
				$return = true;
			}
		}

		$this->isolement = implode(' ', $isolement);
		if (!in_array('isolement', $this->modif)) $this->modif[] = 'isolement';
		return $return;
	}

	/**
	 * Calcul les ressources produites en fonction de $temps_ecoule
	 * @param    int	$temps_ecoule	Temps écoulé depuis la dernière actualisation
     *
     * @return   array
     * @access   public
	 */
	function production($temps_ecoule, $retarray = false){
		//Accélération de la production
		$temps_ecoule *= 10;

		//Calcul de la consomation d'énergie
		if ($this->batiments[0] > 0) $energie_m = ceil(exp(0.28*$this->batiments[0])*10); else $energie_m = 0;
		if ($this->batiments[1] > 0) $energie_c = ceil(exp(0.28*$this->batiments[1])*10); else $energie_c = 0;
		if ($this->batiments[2] > 0) $energie_h = ceil(exp(0.2849*$this->batiments[2])*13); else $energie_h = 0;
		if ($this->batiments[3] > 0) $energie_s = ceil(exp(0.28*$this->batiments[3])*22); else $energie_s = 0;
		if ($this->batiments[4] > 0) $energie_f = ceil(exp(0.297*$this->batiments[4])*25); else $energie_f = 0;

		//Calcul de la consomation d'énergie
		$this->energieConso = $energie_m * $this->coeff_bat[0]  + $energie_c * $this->coeff_bat[1] + $energie_h * $this->coeff_bat[2];
		$nrjmx = $energie_m  + $energie_c + $energie_h;

		//Calcul de la production d'énergie
		$this->energie = $energie_s * $this->coeff_bat[3] + $energie_f * $this->coeff_bat[4];

		if ($this->energieConso == 0) $coeff = 0;
		else $coeff = $this->energie / $this->energieConso;

		if ($coeff < 0) $coeff = 0;
		elseif ($coeff > 1) $coeff = 1;

		$Ncoeff = array();
		for($i = 0; $i < 3; $i++){
			$Ncoeff[$i] = $coeff * $this->coeff_bat[$i];
			if ($Ncoeff[$i] > 1) $Ncoeff[$i] = 1;
			if ($Ncoeff[$i] < $this->coeff_bat[$i]) {
				$this->coeff_bat[$i] = $Ncoeff[$i];
				if (!in_array('coeff_bat', $this->modif)) $this->modif[] = 'coeff_bat';
			}
		}

		//Calcul de la consomation d'hydrogène
		if ($this->batiments[4] > 0) $conso_h = ((ceil(pow(1.34,($this->batiments[4]-1))*9)/3600)*$temps_ecoule) * $this->coeff_bat[4];
		else $conso_h = 0;

		//Calcul des production de ressources
		if ($this->batiments[0] <= 0 || $this->batiments[3] <= 0) $prod_met = 0.011 * $temps_ecoule;
		else $prod_met = ((ceil(pow(1.1, $this->batiments[0]) * 35 * $this->batiments[0]) / 3600) * $temps_ecoule) * $this->coeff_bat[0] * 1.5;

		if ($this->batiments[1] <= 0 || $this->batiments[3] <= 0) $prod_cri = 0.0055 * $temps_ecoule;
		else $prod_cri = ((ceil(pow(1.1, $this->batiments[1]) * 23 * $this->batiments[1]) / 3600) * $temps_ecoule) * $this->coeff_bat[1] * 1.5;

		if ($this->batiments[2] <= 0) $prod_hy = 0;
		else $prod_hy = ((ceil(pow(1.1, $this->batiments[2]) * 14 * ($this->batiments[2] + 0.7)) / 3600) * $temps_ecoule) * $this->coeff_bat[2] * 1.5 - $conso_h;

		if ($retarray) return array(array(ceil($this->coeff_bat[0]*100), ceil($this->coeff_bat[1]*100), ceil($this->coeff_bat[2]*100), ceil($this->coeff_bat[3]*100), ceil($this->coeff_bat[4]*100)), array($prod_met, $prod_cri, $prod_hy + $conso_h, $energie_s*$this->coeff_bat[3], $energie_f*$this->coeff_bat[4]), array($energie_m*$this->coeff_bat[0], $energie_c*$this->coeff_bat[1], $energie_h*$this->coeff_bat[2], $conso_h, ($energie_s*$this->coeff_bat[3] + $energie_f*$this->coeff_bat[4])-($energie_m*$this->coeff_bat[0] + $energie_c*$this->coeff_bat[1] + $energie_h*$this->coeff_bat[2])));
		else return array($prod_met, $prod_cri, $prod_hy);
	}

	/**
	 * Calcul les ressources produites en fonction de $temps_ecoule
	 * @param    int	$file	Nom de la file d'attente
	 * @param    int	$objet	Id de l'objet à ajouter
	 * @param    int	$nombre = 1	Nombre d'objet $objet à ajouter à la file
     *
     * @return   int	Numéro de l'erreur
     * @access   public
	 */
	function file_addObjet($file, $objet, $nombre = 1){
		$planete = $this;
		switch($file){
			case "batiments": $court = "bat"; $calc = "batiment"; $exist = $this->file_exist($objet, "file_".$court); break;
			case "technologies": $court = "tech"; $calc = "technolo"; $exist = $this->file_exist($objet, "file_".$court); break;
			case "casernes": $court = "cas"; $calc = "casernen"; $exist = false; break;
			case "terrestres": $court = "ter"; $calc = "nomterrn"; $exist = false; break;
			case "vaisseaux": $court = "vais"; $calc = "nomvaisn"; $exist = false; break;
			default: return 1;
		}
		global ${$calc}, ${$calc.'CALC'}, ${$calc.'TECH'};

		//Vérification des conditions de construction
		if (empty(${$calc}[$objet]) || !requestDeblok(${$calc.'TECH'}[$objet], $this)) return 1;
		//Vérification qu'il n'y ait pas déjà une instance de l'objet déjà en construction
		if ($exist) return 2;

		//Actualisation du temps s'il n'y a pas d'objet en file
		if (count($this->{"file_".$court}) < 2) $this->{"file_".$court}[0] = time();

		//Calcul du prochain niveau de l'objet
		$n = $this->{$file}[$objet] + 1;

		if ($file == "batiments" || $file == "technologies") {
			eval(${$calc.'CALC'}[$objet][0]);
			eval(${$calc.'CALC'}[$objet][1]);
			eval(${$calc.'CALC'}[$objet][2]);
		}
		else {
			$a = ${$calc.'CALC'}[$objet][0];
			$b = ${$calc.'CALC'}[$objet][1];
			$c = ${$calc.'CALC'}[$objet][2];
		}

		//Vérification des ressources de la planète
		if ($this->metal < $a * $nombre) return 3;
		elseif ($this->cristal < $b * $nombre) return 3;
		elseif ($this->hydrogene < $c * $nombre) return 3;
		else {
			//Mise à jour des ressources de la planète en conséquence à la construction
			$this->metal -= $a * $nombre;
			$this->cristal -= $b * $nombre;
			$this->hydrogene -= $c * $nombre;

			//Génération de la file d'attente
			$nb = count($this->{"file_".$court});

			//Si le dernier objet est identique à celui que l'on veut construire
			if (ereg($objet.',', $this->{"file_".$court}[$nb-1])) {
				$last = explode(',', $this->{"file_".$court}[$nb-1]);
				$last[1] += $nombre;
				$this->{"file_".$court}[$nb-1] = implode(',', $last);
			}
			else $this->{"file_".$court}[] = $objet.','.$nombre;
			if (!in_array("file_".$court, $this->modif)) $this->modif[] = "file_".$court;
			return 0;
		}
	}

	function file_delObjet($file, $objet, $nombre = 1, $w = 99) {
		$planete = $this;
		switch($file){
			case "batiments": $court = "bat"; $calc = "batiment"; $exist = $this->file_exist($objet, "file_".$court); break;
			case "technologies": $court = "tech"; $calc = "technolo"; $exist = $this->file_exist($objet, "file_".$court); break;
			case "casernes": $court = "cas"; $calc = "casernen"; $exist = $this->file_exist($objet, "file_".$court); break;
			case "terrestres": $court = "ter"; $calc = "nomterrn"; $exist = $this->file_exist($objet, "file_".$court); break;
			case "vaisseaux": $court = "vais"; $calc = "nomvaisn"; $exist = $this->file_exist($objet, "file_".$court); break;
			default: return false;
		}
		global ${$calc}, ${$calc.'CALC'};

		//Si l'objet n'est pas dans la file d'attente, on annule la suite
		if (!$exist) return 0;

		if ($w == 99) $w = count($this->{"file_".$court})-1;

		for($i = $w; $i > 0; $i--) {
			$last = explode(',', $this->{"file_".$court}[$i]);
			if($last[0] == $objet){
				$nombre = min($nombre, $last[1]);

				if($last[1] <= $nombre) {
					unset($this->{"file_".$court}[$i]);
					$this->{"file_".$court} = array_merge($this->{"file_".$court});
				}
				else $this->{"file_".$court}[$i] = $objet.','.($last[1]-$nombre);

				if ($i == 1) $this->{"file_".$court}[0] = time();
				break;
			}
		}
		if (!in_array("file_".$court, $this->modif)) $this->modif[] = "file_".$court;

		//Calcul du prochain niveau de l'objet
		$n = $this->{$file}[$objet] + 1;

		if ($file == "batiments" || $file == "technologies") {
			eval(${$calc.'CALC'}[$objet][0]);
			eval(${$calc.'CALC'}[$objet][1]);
			eval(${$calc.'CALC'}[$objet][2]);
		}
		else {
			$a = ${$calc.'CALC'}[$objet][0];
			$b = ${$calc.'CALC'}[$objet][1];
			$c = ${$calc.'CALC'}[$objet][2];
		}

		//Mise à jour des ressources de la planète en conséquence à la construction
		$this->metal += $a * $nombre;
		$this->cristal += $b * $nombre;
		$this->hydrogene += $c * $nombre;

		return $nombre;
	}

	/**
	 * Vérifie l'existance dans la file $file d'attente de $i
	 * @param    int	$i	ID à vérifier
	 * @param    string	$file	Nom de la file d'attente
	 *
	 * @return   boolean
	 * @access   public
	 */
	function file_exist($objet, $file){
		if (count($this->$file) <= 1) return false;
		foreach($this->$file as $bout){
			$bout = explode(',', $bout);
			if($objet == $bout[0]) return true;
		}
		return false;
	}

	/**
	 * Actualise la file $file en terminant les constructions/entraînements.
	 * @param    string	$file	Nom de la file d'attente
     *
     * @return   boolean
     * @access   public
	 */
	function file_pret($file){
		$nanite = 0;
		$planete = $this;
		switch($file){
			case "batiments": $court = "bat"; $calc = "batiment"; break;
			case "technologies": $court = "tech"; $calc = "technolo"; break;
			case "casernes": $court = "cas"; $calc = "casernen"; break;
			case "terrestres": $court = "ter"; $calc = "nomterrn"; break;
			case "vaisseaux": $court = "vais"; $calc = "nomvaisn"; break;
			default: return false;
		}
		global ${$calc}, ${$calc.'CALC'};

		$nb = count($this->{"file_".$court});
		for($i = 1; $i < $nb; $i++){
			$obj = explode(',', $this->{"file_".$court}[$i]);
			$n = $this->{$file}[$obj[0]] + 1;
			eval(${$calc.'CALC'}[$obj[0]][3]);
			$tps = time() - $this->{"file_".$court}[0];

			//Accélération du temps de construction
			$sec /= 10;

			if ($sec * $obj[1] < $tps) {
				$this->{$file}[$obj[0]] += $obj[1];
				unset($this->{"file_".$court}[$i]);
				$this->{"file_".$court} = array_merge($this->{"file_".$court});
				$this->{"file_".$court}[0] += $obj[1] * $sec;

				if (!in_array($file, $this->modif)) $this->modif[] = $file;
				if (!in_array("file_".$court, $this->modif)) $this->modif[] = "file_".$court;
			}
			elseif ($sec < time() - $this->{"file_".$court}[0]) {
				for($j=0 ; $j * $sec < $tps ; $j++) {}
				$j--;
				$this->{"file_".$court}[$i] = $obj[0].','.($obj[1]-$j);
				$this->{$file}[$obj[0]] += $j;
				$this->{"file_".$court}[0] += $j * $sec;

				if (!in_array($file, $this->modif)) $this->modif[] = $file;
				if (!in_array("file_".$court, $this->modif)) $this->modif[] = "file_".$court;
			}
			else {
				$this->actualiser(false);
				return true;
			}
		}
	}

	/**
	 * Destructeur
     *
     * @return   void
     * @access   public
	 */
	function __destruct(){
		global $var___db, $config, $table_planete;
		$nb = count($this->modif);
		$out = array();
		$bdd = new bdd();
		$bdd->connexion();
		for($i = 0; $i < $nb; $i++){
			if ($this->modif[$i] == 'technologies') $this->modifUser[] = $this->modif[$i];
			elseif (!is_array($this->{$this->modif[$i]})) {
				$bdd->escape($this->{$this->modif[$i]});
				if (is_int($this->{$this->modif[$i]}) || is_float($this->{$this->modif[$i]})) $out[] .= $this->modif[$i]." = ".$this->{$this->modif[$i]};
				else $out[] .= $this->modif[$i]." = '".$this->{$this->modif[$i]}."'";
			}
			else {
				if (ereg('file', $this->modif[$i])) {
					$prep = implode(';', $this->{$this->modif[$i]});
					$bdd->escape($prep);
					$out[] .= $this->modif[$i]." = '$prep'";
				}
				else {
					if ($this->modif[$i] == "batiments") $calc = "batiment";
					elseif ($this->modif[$i] == "technologies") $calc = "technolo";
					elseif ($this->modif[$i] == "casernes")$calc = "casernen";
					elseif ($this->modif[$i] == "terrestres") $calc = "nomterrn";
					elseif ($this->modif[$i] == "vaisseaux") $calc = "nomvaisn";
					elseif ($this->modif[$i] == "coeff_bat") $calc = "coeff";

					if (!isset(${$calc.'VAR'})) global ${$calc.'VAR'};

					$nombr = count(${$calc.'VAR'});
					for($j = 0; $j < $nombr; $j++){
						$bdd->escape($this->{$this->modif[$i]}[$j]);
						$out[] .= ${$calc.'VAR'}[$j]." = ".$this->{$this->modif[$i]}[$j]."";
					}
				}
			}
		}
		if (!empty($out)) $plan = $bdd->unique_query("UPDATE $table_planete SET ".implode(', ', $out)." WHERE id = ".$this->id.";");
		$bdd->deconnexion();
		parent::__destruct();
	}
}
?>