<?php
class Box {
	var $db;
	function __construct() {
		include 'db.inc.php';
		$this->db = $db;
	}

	function getBoxes() {
		return $this->db->select('boxes');
	}

	function readBox($name) {
		$ret = $this->db->selectRow('boxes', NULL, array('filename' => $name));
		$test = file_get_contents(PAGES.'box/'.$name.'.php');
		if ($ret['script'] != $test) {
			$ret['error'] = $test;
		}
		return $ret;
	}

	function listBoxes() {
		return $this->db->selectList('boxes', 'filename');
	}

	function getPages() {
		$black_list = array(
			'clear',
			'refresh',
			'image',
		);

		$all = glob(PAGES.'*.php');
		$target = array();
		foreach ($all as $page) {
			$p = basename($page, '.php');
			if (! in_array($p, $black_list)) {
				$target[] = $p;
			}
		}
		return $target;
	}

	function getLayouts() {
		return $this->db->select('layouts', NULL, array('order' => 'sort'));
	}

	function updateLayoutCache() {
		$pages = $this->getPages();
		$layouts = $this->db->select('layouts', NULL, array('order' => 'sort'));
		$d = array();
		foreach ($pages as $p) {
			$d[$p] = array();
		}
		foreach ($layouts as $layout) {
			$d[$layout['page']][$layout['filename']] = TRUE;
		}
		foreach ($pages as $p) {
			file_put_contents(LAYOUTS.$p, serialize($d[$p]));
		}
		return TRUE;
	}

	function copyLayouts($src, $dist) {
		$pages = $this->getPages();
		if (! in_array($src, $pages))
			return FALSE;

		foreach ($dist as $d) {
			if (! in_array($d, $pages))
				return FALSE;
			if ($src == $d) {
				var_dump($src, $d);
				return FALSE;
			}
		}

		$this->db->begin();
		foreach ($dist as $d) {
			$ret = $this->db->pureDelete('layouts', 'page=?', array($d));
			if ($ret === FALSE) {
				var_dump('b');
				$this->db->rollback();
				return FALSE;
			}
			$sql = 'insert into `'.$this->db->getTableName('layouts').'`'
				.' (page, filename, sort, modified)'
				.' select ?, filename, sort, CURRENT_TIMESTAMP'
				.' from `'.$this->db->getTableName('layouts').'`'
				.' where page=?'
			;
			$ret = $this->db->execute(
				$sql,
				array($d, $src)
			);
			if ($ret === FALSE) {
				var_dump('a');
				$this->db->rollback();
				return FALSE;
			}
		}
		$this->db->commit();

		return TRUE;
	}

	function updateLayout($page_name, $box_name, $has, $sort=NULL) {
		if (! $this->db->selectRow('boxes', NULL, array('filename' => $box_name)))
			return FALSE;
	
		$pages = $this->getPages();
		if (! in_array($page_name, $pages))
			return FALSE;
	
		if ($has) {
			if (is_null($sort)) {
				$sort = $this->db->selectOne(
					'layouts',
					array('^max(`sort`)'),
					array('page' => $page_name)
				);
				if ($sort === FALSE || is_null($sort))
					$sort = 0;
				else
					$sort++;
			} else {
				$sort = (int)$sort;
				$this->db->pureUpdate(
					'layouts',
					array('sort' => '^`sort`+1', 'modified' => '^CURRENT_TIMESTAMP'),
					'page=? and `sort`>=?',
					array($page_name, $sort)
				);
			}
			$ret = $this->db->insert(
				'layouts',
				array(
					'page' => $page_name,
					'filename' => $box_name,
					'sort' => $sort,
					'modified' => '^CURRENT_TIMESTAMP'
				)
			);
			return $ret !== FALSE;
		} else {
			return $this->db->delete(
				'layouts',
				array(
					'page' => $page_name,
					'filename' => $box_name
				)
			);
		}
	}

	function getShortestName($target, $names) {
		$parts = explode('_', $target);
		$index = 0;
		$j = strlen($target);
		$p_count = count($parts);
		for ($i=0; $i<$j; $i++) {
			$test = '';
			$cnt = 0;
			$k=0;
			while ($cnt <= $i) {
				foreach ($parts as $l => $p) {
					if ($k >= strlen($p))
						continue;
					$test .= substr($p, $k, 1);
				}
				$cnt++;
				$k++;
			}
			$t_len = strlen($test);
			$is_ng = FALSE;
			foreach ($names as $n) {
				if ($n == $target)
					continue;
				if (substr($n,0,$t_len) == $test) {
					$is_ng = TRUE;
					break;
				}
			}
			if ($is_ng === FALSE)
				return $test;
		}
		return $target;
	}

	//danger method
	function deleteBox($old_name) {
		$cnt = $this->db->count('layouts', 'filename=?', $old_name);
		if ($cnt > 0)
			return FALSE;
		$ret = $this->db->delete('boxes', array('filename' => $old_name));
		if ($ret === FALSE)
			return FALSE;
		return unlink(PAGES.'box/'.$old_name.'.php');
	}

	// danger method
	function updateBox($old_name, $name, $description, $script) {
		if (empty($old_name)) {
			$ret = $this->db->insert(
				'boxes',
				array(
					'filename' => $name,
					'description' => $description,
					'script' => $script,
					'created' => '^CURRENT_TIMESTAMP',
					'modified' => '^CURRENT_TIMESTAMP'
				)
			);
			if ($ret === FALSE)
				return FALSE;
		} else {
			$ret = unlink(PAGES.'box/'.$old_name.'.php');
			if ($ret === FALSE)
				return FALSE;
			$ret = $this->db->update(
				'boxes',
				array(
					'filename' => $name,
					'description' => $description,
					'script' => $script,
					'modified' => '^CURRENT_TIMESTAMP'
				),
				array('filename' => $old_name)
			);
			if ($ret === FALSE)
				return FALSE;

			$this->db->pureUpdate(
				'layouts',
				array('filename' => $name),
				'filename=?',
				array($old_name)
			);
		}
		return file_put_contents(PAGES.'box/'.$name.'.php', $script);
	}
}
?>