#!/usr/local/php/bin/php
<?php
/**
 *	Project:	Quicty: Quick application build environment depends on PEAR and Smarty
 *	File:		qt_data
 *
 *	@copyright	Tomoyuki Negishi and ZubaPitaTech, Inc.
 *	@author		Tomoyuki Negishi <tomoyu-n@zubapita.jp>
 *	@license	http://www.opensource.org/licenses/bsd-license.php The BSD License
 *	@package	Quicty
 *	@version	$Id:$
 */

require_once 'myQuicty.php';

// {{{ qt_data
/**
 *	qt_data class
 *
 *	@author		Tomoyuki Negishi <tomoyu-n@zubapita.jp>
 *	@access		public
 *	@package	Quicty
 */
class qt_data extends myQuicty {
	public $update_flag = false;

	function dispatch_index() {
		$this->init();
		$this->init_array();
		do {
			switch($cmd) {
				case 'a':
					$this->add_column();
					break;
				case 'A':
					$this->add_rule();
					break;
				case 'c':
					$this->change_column_position();
					break;
				case 'd':
					$this->delete_column();
					break;
				case 'D':
					$this->delete_rule();
					break;
				case 'e':
					$this->edit_column();
					break;
				case 'E':
					$this->edit_dsn();
					break;
				case 'I':
					$this->init_data();
					break;
				case 'l':
					$this->list_data();
					break;
				case 'm':
					$this->make_view();
					break;
				case 'r':
					$this->read_data();
					break;
				case 'R':
					$this->read_data(false);
					break;
				case 's':
					$this->save_data();
					break;
				case 'S':
					$this->save_data(false);
					break;
				case 'w':
					$this->write_conf();
					break;
				case 'v':
					$this->virtual_column(true);
					break;
				case 'V':
					$this->virtual_column(false);
					break;
			}
			echo "\na)dd column A)dd rule c)hange column position d)elete column D)elete rule e)dit column \n";
			echo "E)dit dsn I)nit data l)ist data m)ake view q)uit r)ead data s)ave data w)rite conf \n";
			echo "v)irtual column set V)irtual column unset\n";
			//echo "\nSelect command :";
			//$cmd = trim(fgets(STDIN));
			$cmd = freadline("\nSelect command :");
			if($cmd=='q' and $this->update_flag) {
				echo "\nData is not saved.\n";
				$cmd = '';
			}
		} while(!preg_match('/^[Qq]$/',$cmd));


		echo "\ndone.\n";
	}
	
	function add_column() {
		foreach($this->column_kind as $key=>$column) {
			switch($column['kind']) {
				case 'basic':
					$prefix = '';
					break;
				case 'hqf':
					$prefix = '*';
					break;
				case 'quicty':
					$prefix = '+';
					break;
				case 'variation':
					$prefix = '- ';
					break;
			}
			echo $key." : ".$prefix.$column['name']."\t\ttype:".$column['type']."\n";
		}
		$cmd = input_tty('Select column type :',false);
		if(array_key_exists($cmd,$this->column_kind)) {
			$this->data_set[] = $this->column_propety($cmd);
			$this->update_flag = true;
			$this->list_data();
		}
	}

	function add_rule() {
		$this->list_data();echo "\n";
		$cno = (int) input_tty('Select add rule column No. :',false);
		if(array_key_exists($cno,$this->data_set) and $cno > 1) {
			$column = $this->data_set[$cno];
			$rules = $this->rule_kind;
			foreach($rules as $key=>$rule) {
				echo $key." : ".$rule['name']."\t\tparam:".$rule['param']."\n";
			}
			$rno = input_tty('Select rule No. :',false);
			if(array_key_exists($rno,$rules)) {
				$name = $rules[$rno]['name'];
				$param = $rules[$rno]['param'];
				echo "Add rule $name on column '".$column['name']."'.\n\n";
				if($param=='yes' or $param=='only_1st') {
					$column['rule'][$name] = $param;
				} else {
					switch($param) {
						case 'int':
							do { $new_param = input_tty("Input integer for rule '$name' :",false,false);}
								while(!is_numeric($new_param));
							break;
						case 'text':
							do { $new_param = input_tty("Input text for rule '$name' :",false,false);}
								while($new_param==NULL);
							break;
						case 'column':
							$this->list_data();echo "\n";
							do { $tno = input_tty("Select column No. for rule '$name' :",false,false);}
								while(!is_numeric($tno) and !array_key_exists($tno,$this->data_set));
							$new_param = $this->data_set[$tno]['name'];
							break;
					}
					$column['rule'][$name] = $new_param;
				}
				if(confirm_tty()) {
					$this->data_set[$cno] = $column;
					$this->update_flag = true;
					$this->list_data();
				}
			}
		}
	}

	function change_column_position() {
		$this->list_data();echo "\n";
		$now = (int) input_tty('Select change column No. :',false);
		if(array_key_exists($now,$this->data_set) and $now > 1) {
			$new = (int) input_tty('Input new position No.(must be 2 or over ) :',false);
			echo "now=$now => new=$new\n";
			if(is_int($new) and $new > 1) {
				$new_set = array(1=>array('name'=>'id','type'=>'id'));
				$new_set[$new] = $this->data_set[$now];
				$i = 2;
				foreach($this->data_set as $key=>$value) {
					if($key==1 or $key==$now) continue;
					if($i==$new) $i++;
					$new_set[$i] = $value;
					$i++;
				}
				if(confirm_tty()) {
					$this->data_set = $new_set;
					ksort($this->data_set);
					$this->update_flag = true;
					$this->list_data();
				}
			}
		} elseif($now==1) {
			echo "You can't move id column position.\n";
		}
	}

	function delete_column() {
		$this->list_data();
		$cmd = input_tty('Select delete column No. :',false);
		if(array_key_exists($cmd,$this->data_set)) {
			$name = $this->data_set[$cmd]['name'];
			if(confirm_tty("Delete column '$name'\n")) {
				unset($this->data_set[$cmd]);
				$this->update_flag = true;
				$this->list_data();
			}
		}
	}

	function delete_rule() {
		$this->list_data();echo "\n";
		$cno = (int) input_tty('Select delete rule column No. :',false);
		if(array_key_exists($cno,$this->data_set) and $cno > 1) {
			$column = $this->data_set[$cno];
			if(is_array($column['rule']) and count($column['rule'])>0) {
				foreach($column['rule'] as $key=>$rule) {
					echo $key." : ".$rule['name']."\t\tparam:".$rule['param']."\n";
				}
				$rno = input_tty('Select rule No. :',false);
				if(array_key_exists($rno,$column['rule'])) {
					echo 'Delete rule '.$column['rule'][$rno]['name'].'(No.'.$rno.") on column '".$column['name']."' \n";
					if(confirm_tty()) {
						unset($column['rule'][$rno]);
						$this->data_set[$cno] = $column;
						$this->update_flag = true;
						$this->list_data();
					}
				}
			} else {
				echo "Nothing rule on column '".$column['name']."'.\n";
			}
		}
	}

	function edit_column() {
		$this->list_data();echo "\n";
		$cmd = input_tty('Select edit column No. :',false);
		if(array_key_exists($cmd,$this->data_set)) {
			$column = $this->data_set[$cmd];
			foreach($column as $property=>$attribute) {
				if($property=='type') continue;
				if($property=='label') {
					$readline = false;
				} else {
					$readline = true;
				}
				if(!is_array($attribute)) {
					if(!$column[$property] = input_tty("Input $property [$attribute]:",false,false,$readline))
						$column[$property] = $attribute;
				} else {
					foreach($attribute as $key=>$value) {
						if(!$column[$property][$key] = input_tty("Input $property:$key [$value]:",false,false,$readline))
							$column[$property][$key] = $value;
					}
				}
			}
			echo "\nnow:"; $this->list_column($column);echo "\n\n";
			if(confirm_tty()) {
				$this->data_set[$cmd] = $column;
				$this->list_data();
			}
		}
	}

	function edit_dsn() {
		echo "Edit data source...\n\n";
		if($_ENV['windir']) {
			$user = $_ENV['USERNAME'];
		} else {
			$user = $_ENV['USER'];
		}
		$system_kind = array(1=>
			array('name'=>'sqlite','param'=>array('path'=>'var/sqlite')),
			array('name'=>'pgsql','param'=>array('host'=>'localhost','port'=>'5432','user'=>$user,'password'=>'','persistent'=>'0')),
			array('name'=>'mysql','param'=>array('host'=>'localhost','port'=>'3306','user'=>'root','password'=>'','persistent'=>'0'))
		);
		foreach($system_kind as $key=>$sys_spec) {
			printf("%3s: %s\n",$key,$sys_spec['name']);
		}
		$cmd = input_tty("\nSelect DB System No. :",false);
		if(array_key_exists($cmd,$system_kind)) {
			$sys_spec = $system_kind[$cmd];
			$new_dsn['system'] = $sys_spec['name'];
			if(!$new_dsn['dbname'] = input_tty("Input 'db name' [".$this->dsn['dbname']."]:",false,false)) {
				$new_dsn['dbname'] = $this->dsn['dbname'];
			}
			if(!$new_dsn['dataname'] = input_tty("Input 'data name' [".$this->dsn['dataname']."]:",false,false)) {
				$new_dsn['dataname'] = $this->dsn['dataname'];
			}
			if(!$new_dsn['title'] = input_tty("Input 'title' [".$this->dsn['title']."]:",false,false)) {
				$new_dsn['title'] = $this->dsn['title'];
			}
			foreach($sys_spec['param'] as $property=>$value) {
				if($this->dsn[$property]) $value = $this->dsn[$property];
				if(!$new_dsn[$property] = input_tty("Input '$property' [$value] :",false,false))
					$new_dsn[$property] = $value;
			}
			echo "\n";
			if(confirm_tty()) {
				if($this->dsn['name']!=$new_dsn['name'])
					$this->new_db_system = true;
				$this->dsn = $new_dsn;
				$this->update_flag = true;
			}
		}
		$this->list_data();
	}

	function init_data() {
		if(confirm_tty("All data will lost\n")) {
			$this->init_array();
			$this->update_flag = false;
			$this->list_data();
		}
	}
	
	function list_column($column) {
		foreach($column as $property=>$attribute) {
			echo $property.'=';
			if(is_array($attribute)) {
				echo "(";
				foreach($attribute as $k=>$v) {
					echo "$k=$v ";
				}
				echo ") ";
			} else {
				echo $attribute.' ';
			}
		}
	}
	
	function list_data() {
		echo "-----------------------------------------------------------------------\n";
		echo "[dsn]\n";
		foreach($this->dsn as $key=>$name) {
			printf("%-10s:%s\n",$key,$name);
		}
		echo "\n[data set]\n";
		foreach($this->data_set as $key=>$column) {
			printf("%3s: ",$key);
			$this->list_column($column);
			echo "\n";
		}
		echo "-----------------------------------------------------------------------\n";
	}

	function make_view() {
		$cmd_kind = array(1=>
						'input_form',
						'table_view',
						'list_view',
						'all'
						);
		echo "make custom view for '".$this->dsn['dataname']."'.\n\n";
		foreach($cmd_kind as $key=>$name) {
			printf("%3s: %s\n",$key,$name);
		}
		$cmd = input_tty("Select view type :",false);
		if(array_key_exists($cmd,$cmd_kind)) {
			switch($cmd_kind[$cmd]) {
				case 'input_form':
					$this->make_input_form();
					break;
				case 'table_view':
					$this->make_table_view();
					break;
				case 'list_view':
					$this->make_list_view();
					break;
				case 'all':
					$this->make_input_form();
					$this->make_table_view();
					$this->make_list_view();
					break;
			}
		}
	}
	
	function make_input_form() {
		$dataname = $this->dsn['dataname'];
		$dataname_form = $dataname.'_form';
		$filename = $dataname.'_input_form.inc';
		echo "write 'view/includes/$filename' ..\n\n";
		
		// head parts
		$head_parts = <<<END_OF_TEMPLATE
	<!-- includes/$filename -->
	{if !\$$dataname_form}{assign var="$dataname_form" value=\$input_form}{/if}
	<form {\$$dataname_form.attributes}>
		{\$$dataname_form.hidden}
		{if \$$dataname_form.information }
		<div id="form-information">
			{\$$dataname_form.information}
		</div>
		{/if}
		<table cellspacing="0" cellpadding="0" valign="top" id="cms-input-form">
END_OF_TEMPLATE;

		// body parts
		foreach($this->data_set as $key=>$column) {
			if($column['label'] and $column['type']!='hidden') {
				$name = $column['name'];
				$body_parts .= "\n".<<<END_OF_TEMPLATE
			<tr>
				<th>{\$$dataname_form.$name.label}</th>
				<td>{\$$dataname_form.$name.html}{if \$$dataname_form.$name.error}<br>{\$$dataname_form.$name.error}{/if}</td>
			</tr>
END_OF_TEMPLATE;
			}
		}
		
		// foot parts
		$foot_parts = <<<END_OF_TEMPLATE
			<tr>
				<td colspan="2">{\$$dataname_form.submit.html}</td>
			</tr>
		</table>
	</form>
	<!-- end of includes/$filename -->
END_OF_TEMPLATE;

		$contents = $head_parts.$body_parts."\n".$foot_parts."\n";
		if(file_write_contents_with_confirm('view/includes/'.$filename,$contents))
			echo "\ndone.\n";
	}
	
	function make_table_view() {
		$dataname = $this->dsn['dataname'];
		$dataname_view = $dataname.'_view';
		$filename = $dataname.'_table_view.inc';
		echo "write 'view/includes/$filename' ..\n\n";

		// head parts
		$head_parts = <<<END_OF_TEMPLATE
	<!-- includes/$filename -->
	{if !\$display_cmd}{assign var="display_cmd" value="edit"}{/if}
	{if !\$$dataname_view}{assign var="$dataname_view" value=\$table_view}{/if}
	<table cellspacing="0" cellpadding="0" valign="top" id="cms-list-view">
END_OF_TEMPLATE;

		// middle parts
		$columns = '';
		foreach($this->data_set as $column) {
			if(isset($column['label'])) {
				$name = $column['name'];
				$headers .= "\n\t\t\t<th>{\$row.$name.label}</th>";
				$columns .= "\n\t\t\t<td>{\$row.$name.body}</td>";
			}
		}
		$body_parts .= "\n".<<<END_OF_TEMPLATE
{foreach from=\$$dataname_view item="row" key="key" name="$dataname_view"}
{if \$smarty.foreach.$dataname_view.first}
		<tr>
			<th>&nbsp;</th>$headers
		</tr>
{/if}
		<tr>
			<td style="text-align:center;">
				<a href="{\$display_cmd}?id={\$row.id.body}">{\$row.sequence.value}</a>
			</td>$columns
		</tr>
{foreachelse}
		<tr>
			<td>ǡޤ</td>
		</tr>
{/foreach}
END_OF_TEMPLATE;

		$foot_parts = <<<END_OF_TEMPLATE
	</table>
	<!-- end of includes/$filename -->
END_OF_TEMPLATE;

		$contents = $head_parts.$body_parts."\n".$foot_parts."\n";
		if(file_write_contents_with_confirm('view/includes/'.$filename,$contents))
			echo "\ndone.\n";
	}

	function make_list_view() {
		$dataname = $this->dsn['dataname'];
		$dataname_list = $dataname.'_list';
		$filename = $dataname.'_list_view.inc';
		echo "write 'view/includes/$filename' ..\n\n";

		// head parts
		$head_parts = <<<END_OF_TEMPLATE
	<!-- includes/$filename -->
	{if !\$display_cmd}{assign var="display_cmd" value="edit"}{/if}
	{if !\$$dataname_list}{assign var="$dataname_list" value=\$list_view}{/if}
	{if !\$$dataname_list}{assign var="$dataname_list" value=\$table_view}{/if}
	<table cellspacing="0" cellpadding="0" valign="top" id="cms-list-view">
END_OF_TEMPLATE;

		// middle parts
		$columns = '';
		foreach($this->data_set as $column) {
			if(isset($column['label'])) {
				$name = $column['name'];
				if($column['type']=='textarea') {
					$column_body = 'body|nl2br';
				} else {
					$column_body = 'body';
				}
				$columns .= "\n".<<<END_OF_TEMPLATE
		<tr>
			<th>{\$row.$name.label}</th>
			<td>{\$row.$name.$column_body}</td>
		</tr>
END_OF_TEMPLATE;
			}
		}
		$body_parts .= "\n".<<<END_OF_TEMPLATE
{foreach from=\$$dataname_list item="row" key="key" name="$dataname_list"}
	{if \$display_cmd!='none'}
		<tr>
			<td colspan="2">No.<a href="{\$display_cmd}?id={\$row.id.body}">{\$row.sequence.value}</a></td>
		</tr>
	{/if}
$columns
		<tr><td colspan="2" style="border:none;">&nbsp;</td></tr>
{foreachelse}
		<tr>
			<td>ǡޤ</td>
		</tr>
{/foreach}
END_OF_TEMPLATE;

		$foot_parts = <<<END_OF_TEMPLATE
	</table>
	<!-- end of includes/$filename -->
END_OF_TEMPLATE;

		$contents = $head_parts.$body_parts."\n".$foot_parts."\n";
		if(file_write_contents_with_confirm('view/includes/'.$filename,$contents))
			echo "\ndone.\n";
	}
	
	function read_data($use_data_dir=true) {
		if($use_data_dir) {
			echo "Read data from ".$this->data_dir."/.\n\n";
			$dir = $this->data_dir.'/';
			$files = list_dir($dir);
			//echo $dir." files..\n\n";
		} else {
			echo "Read data from any directory.\n\n";
			$dir = '';
			$files = list_dir($_ENV['PWD']);
			echo $_ENV['PWD']." files..\n\n";
		}
		if($this->update_flag and !confirm_tty("Current data will lost.\n"))
			return;
		
		if(is_array($files) and count($files)>0) {
			$i = 1;
			foreach($files as $file) {
				if(filetype($dir.$file)!='dir') {
					if($use_data_dir) {
						$candidate_files[$i] = $file;
						printf("%3s: %s\n",$i,$file);
						$i++;
					} else {
						echo $file."\n";
					}
				}
			}
			echo "\n";
		}
		if($use_data_dir) {
			$fno = input_tty('Select File No :');
			if(array_key_exists($fno,$candidate_files)) 
				$name = $candidate_files[$fno];
		} else {
			$name = input_tty('Input Read File Name :');
		}
		if($name and file_exists($dir.$name)) {
			$read_data = unserialize(file_get_contents($dir.$name));
			$this->dsn = $read_data['dsn'];
			$this->data_set = $read_data['data_set'];
			$this->update_flag = false;
			$this->file_name = $name;
			$this->list_data();
		} else {
			echo "File '$name' not found.\n";
		}
	}

	function save_data($use_data_dir=true) {
		if($use_data_dir) {
			echo "Save data to ".$this->data_dir."/.\n\n";
			$dir = $this->data_dir.'/';
			$files = list_dir($dir);
			//echo $dir." files..\n\n";
		} else {
			echo "Save data to any directory.\n\n";
			$dir = '';
			$files = list_dir($_ENV['PWD']);
			echo $_ENV['PWD']." files..\n\n";
		}
		$save_data = serialize(array('dsn'=>$this->dsn,'data_set'=>$this->data_set));
		if(is_array($files) and count($files)>0) {
			foreach($files as $file)
				if(filetype($dir.$file)!='dir') echo $file."\n";
		}
		if($this->new_db_system) {
			$filename = $this->dsn['name'].'_'.$this->dsn['system'];
		} else {
			if($this->file_name) {
				$filename = $this->file_name;
			} else {
				$filename = $this->dsn['name'].'_'.$this->dsn['system'];
			}
		}
		if(!$name = input_tty('Input Save File Name ['.$filename.']:',false,false))
			$name = $filename;
		if(confirm_tty()) {
			echo "\n";
			file_write_contents_with_confirm($dir.$name,$save_data);
			$this->file_name = $name;
			$this->update_flag = false;
			$this->new_db_system = false;
		}
	}
	
	function set_attribute($tag,$attributes) {
		//var_check($attributes,'attributes');
		if(is_array($attributes) and count($attributes)>0) {
			$data_view = $tag."=start\n";
			foreach($attributes as $key=>$value) {
				$data_view .= "$key=$value\n";
			}
			$data_view .= "end_".$tag."=true\n";
		}
		return $data_view;
	}

	function write_conf() {
		global $quicksmart_datatype;
		if(!confirm_tty("Write config files of '".$this->dsn['dataname']."'.\n"))
			return;
			
		$system = $this->dsn['system'];
		$db_name = $this->dsn['dbname'];
		if($this->dsn['path']) {
			$db_path = $this->dsn['path'];
			//if(substr($db_path,0,1)!='/') $db_path = $_ENV['PWD'].'/'.$db_path;
			if(!file_exists($db_path)) {
				umask(0);
				make_dir($db_path,0777);
			}
			$db_set = $db_path.'/'.$db_name;
		} else {
			$db_set = $db_name;
		}
		$data_name = $this->dsn['dataname'];
		
		// data_view
		foreach($this->data_set as $column) {
			foreach($column as $property=>$attribute) {
				switch($property) {
					case 'name':
						$data_view .= '['.$attribute.']'."\n";
						break;
					case 'type':
					case 'label':
						$data_view .= $property.'='.$attribute."\n";
						break;
					case 'attr':
					case 'list':
					case 'opt':
					case 'rule':
					case 'values':
						$data_view .= $this->set_attribute($property,$attribute);
						break;
					case 'value':
						if(is_array($attribute)) {
							$data_view .= $this->set_attribute($property,$attribute);
						} else {
							$data_view .= $property.'='.$attribute."\n";
						}
						break;
					case 'default':
					case 'force_value':
						if(is_array($attribute)) {
							$data_view .= $this->set_attribute($property.'_list',$attribute);
						} else {
							$data_view .= $property.'='.$attribute."\n";
						}
						break;
				}
			}
			//$data_view .= '['.$column['name'].']'."\n";
			//$data_view .= 'type='.$column['type']."\n";
			//$data_view .= call_user_func(array('set_'.$column['type'].'_option',$column['name']));
			$data_view .= "\n";
		}
		$data_view_file_name = 'etc/data_view/'.$this->dsn['dataname'].'.view.conf';
		if(file_write_contents_with_confirm($data_view_file_name,$data_view))
			echo "wrote '".$data_view_file_name."'.\n";
		
		// data_set
		$data_set = "[dsn]\n";
		$data_set .= "system=".$this->dsn['system']."\n";
		$data_set .= "dbname=".$this->dsn['dbname']."\n";
		if(isset($this->dsn['path'])) $data_set .= "path=".$db_path."\n";
		if(isset($this->dsn['host'])) $data_set .= "host=".$this->dsn['host']."\n";
		if(isset($this->dsn['port'])) $data_set .= "port=".$this->dsn['port']."\n";
		if(isset($this->dsn['user'])) $data_set .= "user=".$this->dsn['user']."\n";
		if(isset($this->dsn['password'])) $data_set .= "password=".$this->dsn['password']."\n";
		if(isset($this->dsn['persistent'])) $data_set .= "persistent=".$this->dsn['persistent']."\n";
		$data_set .= "\n";
		$data_set .= "[bind]\n";
		foreach($this->data_set as $column) {
			if($column['type']=='id') continue;
			if($column['virtual']=='yes') continue;
			$sql_type = $quicksmart_datatype[$column['type']][$this->dsn['system']];
			$data_set .= $column['name'].':'.$column['type'].'='
				.$data_name.'.'.$column['name'].':'.$sql_type."\n";
		}
		$data_set_file_name = 'etc/data_set/'.$this->dsn['dataname'].'.set.conf';
		file_write_contents_with_confirm($data_set_file_name,$data_set);
		echo "wrote '".$data_set_file_name."'.\n";

		// sql
		if($system=='mysql') {
			$sql = "drop table if exists $data_name;\n";
		} else {
			$sql = "drop table $data_name;\n";
		}
		$sql .= "create table $data_name(\n";
		foreach($this->data_set as $column) {
			if($column['virtual']=='yes') continue;
			$sql_type = $quicksmart_datatype[$column['type']][$system];
			$sql_array[] = $column['name'].' '.$sql_type;
		}
		$sql .= "\t".implode(",\n\t",$sql_array);
		$sql .= "\n);\n";
		$sql_file_name = 'etc/sql/'.$system.'/'.$this->dsn['dataname'].'.sql';
		if(!file_exists('etc/sql/'.$system)) make_dir('etc/sql/'.$system);
		if(file_write_contents_with_confirm($sql_file_name,$sql))
			echo "wrote '".$sql_file_name."'.\n";

		// init.sh
		switch($system) {
			case 'sqlite':
				if($_ENV['windir']) {
					$db_set = str_replace('/','\\',$db_set);
					$statements = "sqlite $db_set < .\\etc\\sql\\sqlite\\$data_name.sql\n";
				} else {
					$statements = "sqlite $db_set < etc/sql/sqlite/$data_name.sql\n";
					$statements .= "chmod o+w $db_set\n";
				}
				break;
			case 'pgsql':
				$statements = "createdb $db_name\n";
				if($_ENV['windir']) {
					$statements .= "psql $db_name < .\\etc\\sql\\pgsql\\$data_name.sql\n";
				} else {
					$statements .= "psql $db_name < etc/sql/pgsql/$data_name.sql\n";
				}
				break;
			case 'mysql':
				$statements = "mysqladmin -u root create $db_name\n";
				if($_ENV['windir']) {
					$statements .= "mysql -u root -D $db_name < .\\etc\\sql\mysql\\$data_name.sql\n";
				} else {
					$statements .= "mysql -u root -D $db_name < etc/sql/mysql/$data_name.sql\n";
				}
				break;
		}
		if($_ENV['windir']) {
			$init_file_name = 'bin/init_'.$this->dsn['dataname'].'.bat';
			$init = "\n".<<<EOS
@echo off
echo "#----------------------------------------------#"
echo "# initialize $system $db_set  "
echo "#----------------------------------------------#"
$statements
echo done.
EOS;
		} else {
			$init_file_name = 'bin/init_'.$this->dsn['dataname'].'.sh';
			$init = "\n".<<<EOS
#!/bin/sh
echo "#----------------------------------------------#"
echo "# initialize $system $db_set  "
echo "#----------------------------------------------#"
$statements
echo done.
EOS;
		}
		if(file_write_contents_with_confirm($init_file_name,$init)) {
			if($_ENV['windir']) chmod($init_file_name,0744);
			echo "wrote '".$init_file_name."'.\n";
		}
		
	}


	function virtual_column($set=true) {
		$this->list_data();
		if($set) {
			$mode = 'Set';
		} else {
			$mode = 'UnSet';
		}
		echo "$mode virtual column.\n\n";
		$cmd = input_tty('Select column No. :',false);
		if(array_key_exists($cmd,$this->data_set)) {
			$name = $this->data_set[$cmd]['name'];
			if(confirm_tty("$mode virtual column '$name'\n")) {
				if($set) {
					$this->data_set[$cmd]['virtual'] = 'yes';
				} else {
					unset($this->data_set[$cmd]['virtual']);
				}
				$this->update_flag = true;
				$this->list_data();
			}
		}
	}




//--------- Utils

	function init_array() {
		if($_ENV['PWD']) {
			$tmp_dir = explode('/',$_ENV['PWD']);
			$current_dir = array_pop($tmp_dir);
			$data_name = $db_name = $current_dir;
		} else {
			$data_name = $db_name = 'temp';
		}
		$this->dsn = array('system'=>'sqlite','dbname'=>$db_name,'dataname'=>$data_name,'title'=>'ǡå','path'=>'var/sqlite');
		$this->data_set = array(1=>array('name'=>'id','type'=>'id'));	
	}

	function column_propety($no) {
		$property = $this->column_kind[$no];
		//print_r($property);
		$column['name'] = '';
		$temp_name = $property['name'];
		if(!$column['name'] = input_tty("Input Alphabet Name(for internal) [$temp_name]:",false,false)) 
			$column['name'] = $temp_name;
		$temp_label = $property['label'];
		if(!$column['label'] = input_tty("Input Column Lable(for display title) [$temp_label]:",false,false,false)) 
			$column['label'] = $temp_label;
		$column['type'] = $property['type'];
		if(is_array($property['values'])) {
			echo "You must input 2 option.\n";
			if(!$column['values'][0] = input_tty("Input 1st option :",false,true,false)) return;
			if(!$column['values'][1] = input_tty("Input 2nd option :",false,true,false)) return;
			echo "1:".$column['values'][0]."\n";
			echo "2:".$column['values'][1]."\n";
			echo "0:no option.\n";
			if($option = input_tty("\nSelect Default option\n",false)) {
				$option--;
				$column['default'] = array($option=>$column['values'][$option]);
			}
		}
		if( $column['type']=='hidden' and !$column['value'] = input_tty("Input Column value :",false,false,false) ) {
			unset($column['value']);
		} elseif($property['value']) {
			$column['value'] = $this->set_list($property['value'],'list');
		}
		if(isset($property['attr'])) $column['attr'] = $this->set_option($property['attr'],'attr',$column['name']);
		if(isset($property['opt'])) $column['opt'] = $this->set_option($property['opt'],'opt',$column['name']);
		if(isset($property['default'])) $column['default'] = $this->set_option($property['default'],'default',$column['name']);
		if(isset($property['list'])) $column['list'] = $this->set_list($property['list'],'list');
		if($property['force_value']) $column['force_value'] = $property['force_value'];
		if($property['rule']) $column['rule'] = $property['rule'];
		if($property['virtual']) $column['virtual'] = $property['virtual'];
		return $column;
	}

	function set_option($options,$option_name,$column_name) {
		if(is_array($options) and count($options)>0) {
			echo "Set $option_name option.\n";
			foreach($options as $key=>$value) {
				if($key=='name') $key = $column_name;
				$option[$key] = input_tty("Input '$key' [$value] :",false,false);
				if($option[$key]==NULL) $option[$key] = $value;
			}
		} else {
			$option = $options;
		}
		return $option;
	}

	function set_list($options,$option_name) {
		if(is_array($options) and count($options)>0) {
			if($options['key']=='text') {
				echo "* You can stop by '.' and Enter.\n";
				$i = 1;
				do {
					$key = input_tty("Input option's key(No. or value) [$i]:",false,false);
					if($key=='.') break;
					if($key==NULL) $key = $i;
					$i++;
					do {
						$option = input_tty("Input Option(Name) for key($key) :",false,true,false);
					} while(!$option);
					if($option=='.') break;
					$value[$key] = $option;
					$option = $key = NULL;
				} while(true);
			} else {
				$value = $options;
			}
		} else {
			$value = $options;
		}
		return $value;
	}
	
	public $column_kind = array();
	public $rule_kind = array();
	
	function init() {
		echo "\n";
		if(!$_ENV['QUICTY_MOD']) die("Did not define enviroment var 'QUICTY_MOD'.\n");
		if($_ENV['windir']) $_ENV['PWD'] = `cd %CD%`;
		echo "Your current dir is "; print_r($_ENV['PWD']); echo "\n";
		if(!file_exists('lib/myQuicty.php')) 
			echo "You don't have file 'lib/myQuicty.php'.";
		if(!file_exists('htdocs/index.php'))
			echo "You don't have file 'htdocs/index.php'.";
		if(!file_exists('lib/Pages'))
			echo "You don't have dir 'lib/Pages'.";
		if(!file_exists('view')) 
			echo "You don't have dir 'view'.";
		if(!file_exists('bin')) 
			echo "You don't have dir 'bin'.";
		if(!file_exists('etc')) 
			echo "You don't have dir 'etc'.";
		if(!file_exists('etc/data_def')) 
			echo "You don't have dir 'etc/data_def'.";
		if(!file_exists('etc/data_view')) 
			echo "You don't have dir 'etc/data_view'.";
		if(!file_exists('etc/data_set')) 
			echo "You don't have dir 'etc/data_set'.";
		if(!file_exists('etc/sql')) 
			echo "You don't have dir 'etc/sql'.";
		if(!file_exists('var')) 
			echo "You don't have dir 'var'.";

		$this->data_dir = 'etc/data_def';

		list($year,$month,$day) = explode('-',date("Y-m-d"));
		$maxYear = $year + 5;
		$this->column_kind = array(1=>
			array('name'=>'advcheckbox','kind'=>'hqf','type'=>'advcheckbox','label'=>'checkbox','values'=>array('key'=>'text')),
			array('name'=>'captcha_image','label'=>'ǧڲ','kind'=>'hqf','type'=>'captcha_image'),
			array('name'=>'captcha','kind'=>'variation','type'=>'captcha','label'=>'ʸ','attr'=>array('size'=>10,'maxlength'=>30),'rule'=>array('required'=>'yes')),
			array('name'=>'date','kind'=>'hqf','type'=>'date','label'=>'date',opt=>array('language'=>'ja','minYear'=>'1970','maxYear'=>$maxYear,'format'=>'Yǯmd'),'default'=>array('date'=>'now')),
			array('name'=>'date_time','kind'=>'variation','type'=>'date','label'=>'',opt=>array('language'=>'ja','minYear'=>'1970','maxYear'=>$maxYear,'format'=>'Yǯmd Hiʬ'),'default'=>array('date'=>'now')),
			array('name'=>'entry_datetime','kind'=>'variation','type'=>'date','label'=>'Ͽ',opt=>array('language'=>'ja','minYear'=>'2006','maxYear'=>'2050','format'=>'Yǯmd Hiʬ')
				,'force_value'=>array('date'=>'now','auto_only_1st'=>'yes')),
			array('name'=>'update_datetime','kind'=>'variation','type'=>'date','label'=>'',opt=>array('language'=>'ja','minYear'=>'2006','maxYear'=>'2050','format'=>'Yǯmd Hiʬ')
				,'force_value'=>array('date'=>'now')),
			array('name'=>'birthday','kind'=>'variation','type'=>'date','label'=>'',opt=>array('language'=>'ja','minYear'=>'1930','maxYear'=>$maxYear,'format'=>'Yǯmd')
				,'default'=>array('Y'=>'1970','m'=>'1','d'=>'1')),
				
			array('name'=>'file','kind'=>'basic','type'=>'file','virtual'=>'yes','label'=>'file','attr'=>array('size'=>'50')),
			
			array('name'=>'hidden','kind'=>'basic','type'=>'hidden','label'=>'hidden','value'=>''),
			array('name'=>'hidden_int','kind'=>'variation','type'=>'hidden_int','label'=>'hidden_int','value'=>'','default'=>0),
			array('name'=>'ip_address','kind'=>'variation','type'=>'hidden','label'=>'ip_address','force_value'=>array('_SERVER'=>'REMOTE_ADDR')),
			array('name'=>'embed_value','kind'=>'variation','type'=>'hidden','label'=>'embed_value','force_value'=>array('_THIS_VALUE'=>'array_name.key_name')),
			array('name'=>'embed_int_value','kind'=>'variation','type'=>'hidden_int','label'=>'embed_value','force_value'=>array('_THIS_VALUE'=>'array_name.key_name')),
			
			array('name'=>'password','kind'=>'basic','type'=>'password','label'=>'password','attr'=>array('size'=>'30','maxlength'=>'50'),'rule'=>array('alphanumeric'=>'yes')),
			
			array('name'=>'radio','kind'=>'basic','type'=>'radio','label'=>'radio','list'=>array('key1'=>'text1'),'default'=>array('name'=>'key1')),
			array('name'=>'gender','kind'=>'variation','type'=>'radio','label'=>'','list'=>array('1'=>'','2'=>''),'default'=>array('gender'=>'1')),
			
			array('name'=>'select','kind'=>'basic','type'=>'select','label'=>'select','value'=>array('key'=>'text'),'default'=>array('name'=>'key')),
			array('name'=>'select_text','kind'=>'variation','type'=>'select_text','label'=>'select_text','value'=>array('key'=>'text'),'default'=>array('name'=>'key')),
			array('name'=>'select_from_table','kind'=>'variation','type'=>'select','label'=>'select_from_table','value'=>array('_TABLE'=>'table_name','_ORDER_BY'=>'id','_VALUE'=>'id','_LABEL'=>'name','_START'=>'no_value')),
			array('name'=>'select_from_table_by_condition','kind'=>'variation','type'=>'select','label'=>'select_from_table_by_condition','value'=>array('_TABLE'=>'table_name','_WHERE_COLUMN'=>'where_column_name','_WHERE_THIS_VALUE'=>'where_value_name','_ORDER_BY'=>'id','_VALUE'=>'id','_LABEL'=>'name','_START'=>'no_value')),
			
			array('name'=>'text','kind'=>'basic','type'=>'text','label'=>'text','attr'=>array('size'=>'50','maxlength'=>'50')),
			array('name'=>'email','kind'=>'variation','type'=>'text','label'=>'email','attr'=>array('size'=>'50','maxlength'=>'50'),'rule'=>array('email'=>'yes')),
			array('name'=>'zipcode','kind'=>'variation','type'=>'text','label'=>'͹ֹ','attr'=>array('size'=>'8','maxlength'=>'8'),'rule'=>array('zipcode'=>'yes')),
			
			array('name'=>'textarea','kind'=>'basic','type'=>'textarea','label'=>'textarea','attr'=>array('rows'=>'10','cols'=>'50')),
			array('name'=>'int','kind'=>'quicty','type'=>'int','label'=>'int','attr'=>array('size'=>'50','maxlength'=>'50'),'rule'=>array('numeric'=>'yes','maxlength'=>'int','minlength'=>'int')),
			array('name'=>'id_reference','kind'=>'variation','type'=>'int','label'=>'id_reference','reference'=>array('_TABLE'=>'table_name','_GET_COLUMN'=>'get_column_name','_WHERE_COLUMN'=>'where_column_name')),
			array('name'=>'url','kind'=>'quicty','type'=>'url','label'=>'url','attr'=>array('size'=>'50','maxlength'=>'128')),
		);

		$this->rule_kind = array(1=>
			array('name'=>'alphanumeric','param'=>'yes'),
			array('name'=>'alphanumsymbol','param'=>'yes'),
			array('name'=>'checkemaildomain','param'=>'column'),
			array('name'=>'checkmd5key','param'=>'column'),
			array('name'=>'checkmd5pass','param'=>'column'),
			array('name'=>'checkuniq','param'=>'yes'),
			array('name'=>'compare','param'=>'column'),
			array('name'=>'email','param'=>'yes'),
			array('name'=>'entry_only_1st','param'=>'yes'),
			array('name'=>'lettersonly','param'=>'yes'),
			array('name'=>'maxlength','param'=>'int'),
			array('name'=>'minlength','param'=>'int'),
			array('name'=>'numeric','param'=>'yes'),
			array('name'=>'nonzero','param'=>'yes'),
			array('name'=>'regex','param'=>'text'),
			array('name'=>'required','param'=>'yes'),
			array('name'=>'required','param'=>'only_1st'),
			array('name'=>'zipcode','param'=>'yes'),
			
		);
	}
} // end of class qt_data
// }}}

$quicty = new qt_data();
$quicty->dispatch_index();

?>
