<?php
class G {
	static $now;
	static $one_second;
	static $one_minute;
	static $one_hour;
	static $one_day;
}
G::$one_second = 1;
G::$one_minute = G::$one_second * 60;
G::$one_hour = G::$one_minute * 60;
G::$one_day = G::$one_hour * 24;
G::$now = time();

function h($src) {
	return htmlspecialchars($src);
}
function countdown($time, $to=NULL) {
	if (! $from)
		$from = G::$now;
	if (is_string($time))
		$time = strtotime($time);

	$diff = $to - $time;
	if ($diff > G::$one_day) {
		return ((int)($diff / G::$one_day)) . '日後';
	} else if ($diff > G::$one_hour) {
		return ((int)($diff / G::$one_hour)) . '時間後';
	} else if ($diff > G::$one_minute) {
		return ((int)($diff / G::$one_minute)) . '分後';
	} else {
		return ((int)($diff / G::$one_second)) . '秒後';
	}
}
function countdown_by($time, $from=NULL) {
	if (! $from)
		$from = G::$now;
	if (is_string($time))
		$time = strtotime($time);

	$diff = $from - $time;
	if ($diff > (G::$one_day*7)) {
		return date('Y-m-d H:i:s', $time);
	} else if ($diff > G::$one_day) {
		return date('Y-m-d H:i:s', $time);
	} else if ($diff > G::$one_hour) {
		return ((int)($diff / G::$one_hour)) . '時間前';
	} else if ($diff > G::$one_minute) {
		return ((int)($diff / G::$one_minute)) . '分前';
	} else {
		return ((int)($diff / G::$one_second)) . '秒前';
	}
}

function display_content($src) {
	return nl2br($src);
}
function u($page) {
	return BASE_URL.$page;
}
function mb_truncate($src, $len=128, $etc='...') {
	if (mb_strlen($src) < $len)
		return $src;
	return mb_substr($src, 0, $len).$etc;
}
function get_daily_secret() {
	$m = @filemtime(DATA.'secret');
	if ($m === FALSE || date('d') != date('d', $m))
		update_daily_secret();

	return file_get_contents(DATA.'secret');
}
function update_daily_secret() {
	return file_put_contents(DATA.'secret', mt_rand(0,1000000));
}
function generate_id($host=NULL) {
	if (! $host) {
		$host = @$_SERVER['REMOTE_ADDR'];
		if (empty($host))
			$host = microtime(true);
	}

	$tmp = explode('.', $host);
	$plus = (date('d')+$tmp[0]-$tmp[count($tmp)-1]) % strlen($host);
	$host = substr($host, $plus+1).substr($host, $plus, 1).substr($host, 0, $plus);
	$pos = strpos($host, '.');
	if ($pos !== FALSE)
		$host = substr($host, 0, $pos).substr($host, $pos+1);

	return hash_visualization(md5(
		BULLET_SECRET_KEY
		.get_daily_secret()
		.$host
	, true));
}
function hash_visualization($ary, $plus_salt=0, $len=8) {
	$cnt = 16;//count($ary);
	$seed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_';
	$seed_len = 64;//strlen($seed);
	$ret = array();
	$bytes = unpack('C*', $ary);
	$plus = ($bytes[1]+$plus_salt) % $cnt;
	for ($i=0; $i<$len; $i++) {
		$ret[] = substr($seed, $bytes[($i * $len + $i + $plus) % $cnt+1] % $seed_len, 1);
	}
	return implode('', $ret);
}

function print_paging($base_url, $page, $show, $cnt) {
	if ($cnt <= $show)
		return;
	if ($page < 1)
		$page = 1;
	echo '<div class="paging">';
	echo '<div class="paging_info">';
	echo $cnt.'件中'.(($page-1)*$show+1).'～'.min(($page-1)*$show+$show, $cnt).'件を表示しています。';
	echo '</div>';
	echo '<div class="paging_action">';
	$pages = array();
	$p = $page;
	$m = $page;
	$p_max = ceil($cnt / $show);
	$pages[] = $page;
	$has_plus = FALSE;
	$has_minus = FALSE;
	for ($i=0; $i<8; $i++) {
		if ($i % 2 == 0) {
			$p++;
			if ($p > $p_max)
				continue;
			$has_plus = TRUE;
			$pages[] = $p;
		} else {
			$m--;
			if ($m < 1)
				continue;
			$has_minus = TRUE;
			$pages[] = $m;
		}
	}
	sort($pages);
	if ($has_minus) {
		//echo '<a href="'.$base_url.'" class="name">&lt;&lt;</a> ';
		echo '<a rel="prev" href="'.$base_url.'/'.($page-1).'" class="name">前へ</a> ';
	}
	foreach ($pages as $p) {
		if ($p == $page) {
			echo '<span class="current_page">'.$p.'</span> ';
		} else {
			echo '<a href="'.$base_url.'/'.$p.'" class="name">'.$p.'</a> ';
		}
	}
	if ($has_plus) {
		echo '<a rel="next" href="'.$base_url.'/'.($page+1).'" class="name">次へ</a> ';
		//echo '<a href="'.$base_url.'/'.$p_max.'" class="name">&gt;&gt;</a> ';
	}
	echo '</div>';
	echo '</div>';
}

function print_paging_q($base_url, $page, $show, $cnt, $p_name='p') {
	if ($cnt <= $show)
		return;
	if ($page < 1)
		$page = 1;
	echo '<div class="paging">';
	echo '<div class="paging_info">';
	echo $cnt.'件中'.(($page-1)*$show+1).'～'.min(($page-1)*$show+$show, $cnt).'件を表示しています。';
	echo '</div>';
	echo '<div class="paging_action">';
	$pages = array();
	$p = $page;
	$m = $page;
	$p_max = ceil($cnt / $show);
	$pages[] = $page;
	$has_plus = FALSE;
	$has_minus = FALSE;
	for ($i=0; $i<8; $i++) {
		if ($i % 2 == 0) {
			$p++;
			if ($p > $p_max)
				continue;
			$has_plus = TRUE;
			$pages[] = $p;
		} else {
			$m--;
			if ($m < 1)
				continue;
			$has_minus = TRUE;
			$pages[] = $m;
		}
	}
	sort($pages);
	$and = strpos($base_url, '?') !== FALSE ? '&' : '?';
	if ($has_minus) {
		//echo '<a href="'.$base_url.'" class="name">&lt;&lt;</a> ';
		echo '<a rel="prev" href="'.$base_url.$and.$p_name.'='.($page-1).'" class="name">前へ</a> ';
	}
	foreach ($pages as $p) {
		if ($p == $page) {
			echo '<span class="current_page">'.$p.'</span> ';
		} else {
			echo '<a href="'.$base_url.$and.$p_name.'='.$p.'" class="name">'.$p.'</a> ';
		}
	}
	if ($has_plus) {
		echo '<a rel="next" href="'.$base_url.$and.$p_name.'='.($page+1).'" class="name">次へ</a> ';
		//echo '<a href="'.$base_url.$and.$p_name.'='.$p_max.'" class="name">&gt;&gt;</a> ';
	}
	echo '</div>';
	echo '</div>';
}

function get_show_boxes($f) {
	return @unserialize(@file_get_contents(LAYOUTS.basename($f,'.php')));
}

function load_auth() {
	$user_type_id = empty($_SESSION['user']) ? '0' : $_SESSION['user']['user_type_id'];
	$GLOBALS['auth'] = unserialize(file_get_contents(DATA.'auth'.$user_type_id));
}
function can_action($action) {
	if (! @array_key_exists($action, @$GLOBALS['auth']))
		return FALSE;

	return $GLOBALS['auth'][$action];
}
function redirect($page='') {
	header('Location: '.BASE_URL.$page);
	die;
}
function _a_log($target, $action, $options=array()) {
	if (! ENABLE_ACTION_LOG)
		return TRUE;

	require_once(LIB.'Action.class.php');
	$obj = new Action(@$_SESSION['user']['id']);
	$ret = $obj->prepare($target, $action, $options);
	if ($ret === FALSE)
		return FALSE;

	return $obj;
}
function _a_log2($target, $action, $options=array()) {
	if (! ENABLE_ACTION_LOG)
		return TRUE;

	require_once(LIB.'Action.class.php');
	$obj = new Action(@$_SESSION['user']['id']);
	$ret = $obj->prepare($target, $action, $options);
	if ($ret === FALSE) {
		_a_log_write_fail_security($obj);
		return FALSE;
	}

	return $obj;
}
function _a_log_write($obj, $options=array()) {
	if (! ENABLE_ACTION_LOG)
		return TRUE;

	return $obj->write($options);
}
function _a_log_write_fail($obj, $detail, $options=array()) {
	if (! ENABLE_ACTION_LOG)
		return TRUE;

	return $obj->write(array_merge(array(
		'detail' => $detail,
		'success' => 0
	), $options));
}
function _a_log_write_fail_security($obj, $options=array()) {
	if (! ENABLE_ACTION_LOG)
		return TRUE;

	return $obj->write(array_merge(array(
		'detail' => $obj->reason ? $obj->reason : 'Security check',
		'success' => 0
	), $options));
}
function _a_log_fail($target, $action, $detail, $options=array()) {
	if (! ENABLE_ACTION_LOG)
		return TRUE;

	require_once(LIB.'Action.class.php');
	$obj = new Action(@$_SESSION['user']['id']);
	$obj->prepareOnly($target, $action, $options);
	return $obj->write(array_merge(array(
		'detail' => $detail,
		'success' => 0
	), $options));
}

function is_login() {
	return ! empty($_SESSION['user']);
}
function try_update_session() {
	if (@$_SESSION['expire'] < time()) {
		if (is_login()) {
			require_once(LIB.'Action.class.php');
			$action = new Action($_SESSION['user']['id']);
			if (! $action->refreshSession()) {
				//TODO: どうしようもない
				return FALSE;
			}
			return TRUE;
		} else {
			return session_regenerate_id(TRUE);
		}
	}
	return 0;
}
function get_favorite_item_caption($item) {
	switch($item['target_type']) {
	case 'post':
		return $item['info'];
	case 'url':
		return "URL: ". $item['info'];
	case 'theme':
		return "テーマ: ". $item['target_key'];
	case 'user':
		return "ユーザ: ". $item['info'];
	case 'name':
		return "ID: ". $item['target_key'];
	case 'trip':
		return "トリップ: ". $item['target_key'];
	case 'my':
		return "[自分の書き込み]";
	}
	return $item.target_type.': '.$item.target_key;
}
function get_favorite_item_link($item) {
	switch($item['target_type']) {
	case 'post':
		return u('read/'.$item['target_key']);
	case 'url':
		return u('read/'.$url['target_key']);
	case 'theme':
		return u('theme/'.$item['target_key']);
	case 'user':
		return u('user/'.$item['target_key']);
	case 'name':
		return u('name/'.$item['target_key']);
	case 'trip':
		return u('trip/'.$item['target_key']);
	case 'my':
		return u('my');
	}
	return NULL;
}