<?php

/**
 * @see http://pl2.php.net/manual/en/book.var.php
 * 
 * Define Your own convert function: var func_type_convert_{$type}( $var );
 */
class V {

	/**
	 * Get variable from array or object.
	 */
	public static function get( $name, $default, &$from, $type = '' ) {
		$ret = null;
		if (is_array($from)) {
			if (array_key_exists($name, $from)) {
				$ret = $from[ $name ];
			}
		}
		else if (is_object($from)) {
			if (isset($from->$name)) {
				$ret = $from->$name;
			}
		}

		if (isset($ret) && $type != '') {
			$ret = V::convert( $ret, $type );
		}

		return (isset($ret))? $ret : $default;
	}

	/**
	 * Convert variable type.
	 */
	public static function convert( &$from, $type = 'string' ) {
		$type = strtolower( $type );

		// is_scalar( $from ) - return TRUE if int,float,string,bool, FALSE if array,object,resource, ...

		$ret = null;
		switch ($type) {
			case 'string':
				if (is_scalar($from)) {
					$ret = $from;
					settype($ret, $type);
				}
				break;
			case 'word':
				if (is_scalar($from)) {
					$ret = $from;
					settype($ret, $type);
					$ret = trim($ret);
					if (false !== ($pos = strpos($ret, ' '))) {
						$ret = substr($ret, 0, $pos);
					}
				}
				break;
			case 'int':
			case 'integer':
				if (is_scalar($from)) {
					$ret = $from;
					settype($ret, $type);
				}
				break;
			case 'float':
			case 'double':
				if (is_scalar($from)) {
					$ret = str_replace(',','.',$from);
					settype($ret, $type);
				}
				break;
			case 'object':
			case 'array':
				if (is_scalar($from) || is_array($from) || is_object($from)) {
					$ret = $from;
					settype($ret, $type);
				}
				break;
			case 'int_array':
				if (is_scalar($from) || is_array($from) || is_object($from)) {
					$ret = array();
					$arr = $from;
					settype($arr, $type);
					foreach ($arr as $v) {
						$v = V::convert($v,'int');
						$ret []= $v;
					}
				}
				break;
			case 'uint_array':// uncigned int array
				if (is_scalar($from) || is_array($from) || is_object($from)) {
					$ret = array();
					$arr = $from;
					settype($arr, $type);
					foreach ($arr as $v) {
						$v = V::convert($v,'int');
						if ($v <= 0) continue;
						$ret []= $v;
					}
				}
				break;
			case 'float_array':// uncigned int array
				if (is_scalar($from) || is_array($from) || is_object($from)) {
					$ret = array();
					$arr = $from;
					settype($arr, $type);
					foreach ($arr as $v) {
						$v = V::convert($v,'float');
						$ret []= $v;
					}
				}
				break;
			default:
				$fun = 'func_type_convert_'.$type;
				if ( function_exists($fun) ) {
					$ret = $fun( $from );
				}
				break;
		}
		return $ret;
	}

	/**
	 * Merge the contents of two objects/array.
	 * 
	 * array V::extend( mixed $defaults, mixed $params );
	 * @see http://api.jquery.com/jQuery.extend/
	 * is_scalar( $from ) - return TRUE if int,float,string,bool, FALSE if array,object,resource, ...
	 */
	public static function extend( $defaults, $params ) {
		$ret = array();
		$d = (is_array($defaults))? $defaults : (array)$defaults;
		$p = (is_array($params))? $params : (array)$params;
		foreach ($d as $k => $v) {
			$ret [$k] = $v;
		}
		foreach ($p as $k => $v) {
			if (array_key_exists($k, $ret) && (is_array($ret[$k]) || is_object($ret[$k])) && (is_array($v) || is_object($v))) {
				$ret [$k] = V::extend( $ret[$k], $v );
			} else {
				$ret [$k] = $v;
			}
		}
		return $ret;
	}

	public static function json_encode_latin2( $o, $force_object = false ) {
		if ($o === '') {
			return '""';
		}
		else if (!$o) {
			return 'null';
		}
		else if (is_array($o)) {
			$arr = '';
			if ($force_object) {
				foreach ($o as $k => $v) {
					$arr []= '"'.$k.'":'.V::json_encode_latin2($v, $force_object);
				}
				return '{'.implode(',',$arr).'}';
			}
			else {
				foreach ($o as $k => $v) {
					if (is_string($k)) $arr []= '"'.$k.'":'.V::json_encode_latin2($v, $force_object);
					else $arr []= V::json_encode_latin2($v);
				}
				return '['.implode(',',$arr).']';
			}
		}
		else if (is_object($o)) {
			$arr = '';
			foreach (get_object_vars($o) as $k => $v) {
				$arr []= '"'.$k.'":'.V::json_encode_latin2($v, $force_object);
			}
			return '{'.implode(',',$arr).'}';
		}
		else if (is_string($o)) {
			return '"'.addslashes(str_replace(array("\n","\r"), array('\n',''), $o)).'"';
		}
		else if (is_numeric($o)) {
			return ''.$o.'';
		}
		else if (is_bool($o)) {
			return ''.(($o)? 'true' : 'false').'';
		}
	}

	public static function copy( $o ) {
		$null = null;
		if (!$o) {
			return $null;
		}
		else if (is_array($o)) {
			$ret = array();
			foreach ($o as $k => $v) {
				$ret [$k] = $v;
			}
			return $ret;
		}
		else if (is_object($o)) {
			$ret = new stdClass();
			foreach (get_object_vars($o) as $k => $v) {
				$ret->$k = $v;
			}
			return $ret;
		}
		else {
			$ret = $o;
			return $ret;
		}
	}

	public static function make_link( $prefix = '', $params = array() ) {
		$ret = '';
		if ($prefix) {
			$ret = $prefix;
		}
		if (!empty($params)) {
			$ret_arr = array();
			foreach ($params as $k => $v) {
				$ret_arr []= $k . "=" . $v;
			}
			$ret .= "?" . implode("&", $ret_arr);
		}
		return $ret;
	}

	public static function strShort($label, $maxLength = 10, $suffix = ' ...') {
		if (strlen($label) > $maxLength) {
			$pos = strpos($label, ' - ');
			if ($pos > $maxLength || $pos < 5) {
				$label = substr($label, 0, $pos) . $suffix;
			} else {
				$label = substr($label, 0, $pos);
			}
		}
		return $label;
	}

	public static function strShortUtf8($label, $maxLength = 10, $suffix = ' ...') {
		if (mb_strlen($label, 'utf-8') > $maxLength) {
			$pos = mb_strpos($label, ' - ', 0, 'utf-8');
			if ($pos > $maxLength || $pos < 5) {
				$label = mb_substr($label, 0, $maxLength, 'utf-8') . $suffix;
			} else {
				$label = mb_substr($label, 0, $pos, 'utf-8');
			}
		}
		return $label;
	}

}
