<?php
	
	function decodeSTRING($val){
		// #, &, +  < > などが URI 送信で化けるため encode して送られたものを decode
		$array = explode("%x0;", $val);
		$val = implode("#", $array);
		$array = explode("%x1;", $val);
		$val = implode("&", $array);
		$array = explode("%x2;", $val);
		$val = implode("+", $array);
		$array = explode("%x3;", $val);
		$val = implode("<", $array);
		$array = explode("%x4;", $val);
		$val = implode(">", $array);
		$array = explode("%x5;", $val);
		$val = implode(" ", $array);
		$array = explode("%x6;", $val);
		$val = implode("\n", $array);
		$array = explode("%x7;", $val);
		$val = implode("\"", $array);
		$array = explode("%x8;", $val);
		$val = implode("$", $array);
		$array = explode("%x9;", $val);
		$val = implode("'", $array);
		return $val;
	}

	function leftBrackets(){
		// $leftBrackets = "\^\[\^" では誤作動
		//	return "\^\[\^"; // encode 中で使う '(' -- クライアント側との約束 lib.js
		return "^[^"; // encode 中で使う '(' -- クライアント側との約束 lib.js
	}
	function rightBrackets(){
		return "^]^"; // encode 中で使う '(' -- クライアント側との約束 lib.js
		//	return "\^\]\^"; // encode 中で使う '(' -- クライアント側との約束 lib.js
	}
	function decodeObject($buff){
		// "key(value)" 形式の文字列を OBJECT に decode して返す
		$obj = array();
		//	echo "decodeObject ===\n$buff\n"; //##
		for ($p=$begin=$nest=0, $len=strlen($buff); $p < $len; $p++){
			$ch = substr($buff, $p, 1);
			if (strcmp($ch, "(") == 0){
				if ($nest == 0){
					$key = trim(substr($buff, $begin, $p - $begin)); // key 終端
					$begin = $p + 1; // value 開始位置
				}
				$nest++;
			} else if (strcmp($ch, ")") == 0){
				if (--$nest == 0){
					if ($nest == 0){
						// value 終端 ( trim しない )
						$value = substr($buff,$begin,$p-$begin);
						$begin = $p + 1; // key 開始位置
					}
					if (ereg(")", $value)){ // まだ入れ子になっているなら
						$obj[$key] = decodeObject($value);
					} else {
						// 特定文字を "(", ")" へ戻す
						$array = explode(leftBrackets(), $value);
						$value = join("(", $array);
						$array = explode(rightBrackets(), $value);
						$value = join(")", $array);
						
						$obj[$key] = $value;
					}
					//echo "$key{".$obj[$key]."}\n"; //##
				}
			}
		}
		return $obj;
	}
	
	function replace($buff, $from, $to){
		// $buff 中の $from を $to へ置換
		$array = explode($from, $buff);
		return implode($to, $array);
	}
	
	function unique($ln, $word, $newWord){
		// $ln に $word が含まれていた場合は $newWord のみを返す
		if (strpos($ln, $word) === 0)
			return $newWord;
		else if (strpos($ln, $word) > 0)
			return $newWord;
		else
			return $ln;
	}
	
	function skip($patientId, $pid){
		// 特定のカルテIDをスキップ
		return (strcmp($patientId, $pid) == 0) ? true : false;
	}
		
	function lastDescription($from, $to, $pid){
		// $patientId の $to 直近の実データ
		$sql = "SELECT * FROM `ProgressSection`
		WHERE `patientId`='$pid' AND `entryDate`<='$to'		
		ORDER BY `entryDate` DESC";
		echo "--- $sql \n";
		$result=mysql_query($sql);
		while ($row=mysql_fetch_array($result)){
			// 削除済みレコードはスキップ
			if (strpos($row['pageHeader'], "EMOVED") > 0) continue;
			$st = $row['subject'];
			if (strlen($st) > 0){
				// 当日修正され、実体のある Subject 欄
				$lines = explode("\n", $st);
				return $lines[0];
			}
		}
		return "$patientId $to ... has no value";
	}
	
    function regulateString($ln, $dictionary){
        // $dictionary を元に $ln を正規化して返す
        // 対象文字列から夾雑物を取り除く処理
        for ($i=0,$ct=count($dictionary); $i < $ct; $i++){
            $st = $dictionary[$i];
            if (strlen($st) == 0) continue;
            
            $ary = explode("','", $st);
            $st1 = substr($ary[0], 1);
            if (count($ary) > 2){ // ['foo','bar','*'] 形式
                $st2 = $ary[1];
                // 特定の単語があった場合はそれだけを取り出す
                // $ln に $st1 が含まれていた場合は $st2 のみを返す
                $ln = unique($ln, $st1, $st2);
            } else { // ['foo','bar'] 形式
                $st2 = substr($ary[1], 0, strlen($ary[1]) - 1);
                // 統計結果に関係ない常用語を削除あるいは訂正
                // $buff 中の $st1 を $st2 へ置換
                $ln = replace($ln, $st1, $st2);
            }
        }
        
        return trim($ln);
    }
    
	function getSubjects($fromDate, $toDate){
		// ProgressSection.subject をスキャンする
		// 変換テーブルを読み込む
		$buff = getFile("subjectTable.txt");
		$subjectList = explode("\n", $buff);
		if ($subjectList[0] == "高精度"){
			$highPrecision = TRUE;
			array_splice($subjectList, 0, 1);
		} else
			$highPrecision = FALSE;

		$rec = array();
		$sql = "SELECT * FROM `ProgressSection`
		WHERE `entryDate`>'$fromDate' AND `entryDate`<='$toDate' 
		ORDER BY `entryDate` DESC";
		echo "=====\n $sql \n";
		$result=mysql_query($sql);
		while ($row=mysql_fetch_array($result)){
			// 削除済みレコードはスキップ
			if (strpos($row['pageHeader'], "EMOVED") > 0) continue;

			// subject の１行目を取り出す
			$st = $row['subject'];
			if ($st && strlen($st) > 0){
				// 当日修正され、実体のある Subject 欄
				$lines = explode("\n", $st);
				$subject = $lines[0];
			} else {
				// 当日修正のなかった、過去履歴と同じ Subject 欄
				if ($highPrecision){
					// ここで過去の実レコードを探すためにかなり検索負荷がかかる
					$patientId = $row['patientId'];
					$tdate = $row['entryDate'];
					$subject = lastDescription($fromDate, $tdate, $patientId);
				} else {
					// 過去欄をスキップするので処理が速く結果は大きくは変わらない。
					continue;
				}
			}
			// Subject 欄から行頭の "#num " 部分を取り除く
			if (strcmp(substr($subject,0,1),"#") == 0){
				$subject = substr($subject, strpos($subject, " ") + 1);
			} 
			// 主訴特有の重複をなるべく収束させる
			$ln = "";
			$len = strlen($subject);
			for ($i=$indent=0; $i < $len; $i++){
				$ch = substr($subject, $i, 1);
				// 空白以外の数値や記号を削除
				if (($ch != ' ') && ($ch < 'A')) continue;
				// "(..)" 形式の記述部分を削除
				if ($ch == '('){
					$indent++;
				} else if ($ch == ')'){
					$indent--;
				} else
					$ln = $ln.$ch;
			}

			// 対象文字列から夾雑物を取り除く処理
            $ln = regulateString($ln, $subjectList);
			
			if (strlen($ln) == 0) continue;
			
			$obj = array();
			$obj['date'] = $row['entryDate'];
			$obj['id'] = $row['patientId'];
			$rec[$ln][] = $obj;
		}
		return $rec;
	}
    
    function getDisease($fromDate, $toDate){
        // 指定期間の病名統計
        
		// 変換テーブルを読み込む
		$buff = getFile("diseaseTable.txt");
		$dict = explode("\n", $buff);
		if ($dict[0] == "高精度"){
			$highPrecision = TRUE;
			array_splice($dict, 0, 1);
		} else
			$highPrecision = FALSE;
        
		$rec = array();
		$sql = "SELECT * FROM `ProgressSection` WHERE `entryDate`>'$fromDate' AND `entryDate`<='$toDate' ORDER BY `entryDate` DESC";
		echo "=====\n $sql \n";
		$result=mysql_query($sql);
		while ($row=mysql_fetch_array($result)){
			// 削除済みレコードはスキップ
			if (strpos($row['pageHeader'], "EMOVED") > 0) continue;
            
			// subject の１行目を取り出す
			$st = $row['disease'];
            if ($st && strlen($st) > 0){
                if (strlen(trim($st)) == 0){
                    // $row['disease'] が空白、すなわちデータは無かった
                    continue;
                } else {
                    // 当日修正され、実体のある disease 欄
                    $disease = $row['disease'];
                    $diseaseArray = array();
                    $ary = explode("\n", $disease);
                    for ($i=0,$ct=count($ary); $i < $ct; $i++){
                        $ln = $ary[$i];
                        $name = substr($ln, 7); // 日付部分をスキップ
                        $diseaseArray[] = $name;
                    }
                }
            } else {
                // 前回と同じ内容の病名欄: $disease は前レコードで記憶されたもの
            }

            for ($i=0,$ct=count($diseaseArray); $i < $ct; $i++){
                $name = $diseaseArray[$i];
                
                // 対象文字列から夾雑物を取り除く処理
                $name = regulateString($name, $dict);
                
                if (strlen($name) == 0) continue;
                
                $obj = array();
                $obj['date'] = $row['entryDate'];
                $obj['id'] = $row['patientId'];
                $rec[$name][] = $obj;
            }
            
		}
		return $rec;
    }
	
	function getFile($filename){
		if (file_exists("../Users/STATISTICS/$filename")){
			$filename = "../Users/STATISTICS/$filename";
			if ($handle = fopen($filename, 'r')) {
				// オープンしたファイルを読込む
				if ($handle) {
					$array = array();
					while (!feof($handle)) {
						$ln = fgets($handle);
						$ln = mb_convert_encoding($ln, "UTF-8", "UTF-8,SJIS,EUC-JP");
						$array[] = $ln;
					}
					fclose($handle);
					return implode("", $array);
				}
			} else
				echo "$filename *** が開けませんでした\n";
		} else {
			// ../Users/STATISTICS/filename がなかったので
			// Statistics 組み込みの ./filename を探す
			if (file_exists($filename)){
				if ($handle = fopen($filename, 'r')) {
					// オープンしたファイルを読込む
					if ($handle) {
						$array = array();
						while (!feof($handle)) {
							$ln = fgets($handle);
							$ln = mb_convert_encoding($ln, "UTF-8", "UTF-8,SJIS,EUC-JP");
							$array[] = $ln;
						}
						fclose($handle);
						return implode("", $array);
					}
				} else
					echo "$filename *** が開けませんでした\n";
			}
		}
		return "";
	}
	
	function getTreatment($changeList, $ln){
		// 処置として適当なもののみを取り出す
		$array = explode("]", $ln);
		$buff = $array[0]."]";
		
		// $buff 文字列の中で "(..)" で括られた部分を取り除く
		$len = strlen($buff);
		$ln = "";
		for ($i=$indent=0; $i < $len; $i++){
			$ch = substr($buff, $i, 1);
			if ($ch == '('){
				$indent++;
				continue;
			} else if ($ch == ')'){
				$indent--;
				continue;
			}
			if ($indent == 0)
				$ln = $ln.$ch;
		}

		// 対象文字列から夾雑物を取り除く処理
		for ($i=0,$ct=count($changeList); $i < $ct; $i++){
			$st = $changeList[$i];
			if (strlen($st) == 0) continue;
			$ary = explode("','", $st);
			$st1 = substr($ary[0], 1);
			$st2 = substr($ary[1], 0, strlen($ary[1]) - 1);
			if (count($ary) > 2){ // ['foo','bar','*'] 形式
				// 特定の単語があった場合はそれだけを取り出す
				$ln = unique($ln, $st1, $st2);
			} else { // ['foo','bar'] 形式
				// 統計結果に関係ない常用語を削除あるいは訂正
				$ln = replace($ln, $st1, $st2);
			}
		}
		return trim($ln);
	}
	
	function getTreatments($fromDate, $toDate){
		// ProgressSection.treatment をスキャンする
		
		// 変換テーブルを読み込む
		$buff = getFile("treatmentTable.txt");
		$changeList = explode("\n", $buff);

		$rec = array();
		$sql = "SELECT * FROM `ProgressSection`
		WHERE `entryDate`>'$fromDate' AND `entryDate`<='$toDate' 
		ORDER BY `entryDate`";
		echo "=====\n $sql \n";
		$result=mysql_query($sql);
		while ($row=mysql_fetch_array($result)){
			// 削除済みレコードはスキップ
			if (strpos($row['pageHeader'], "EMOVED") > 0) continue;
			// subject の１行目を取り出す
			$st = trim($row['treatment']);
			if (strlen($st) == 0) continue;
			
			$lines = explode("\n", $st);
			for ($i=0,$ct=count($lines); $i < $ct; $i++){
				$ln = $lines[$i];
				// 処置として適当なもののみを取り出す
				if (strlen($ln) == 0) continue;
				if (strpos($ln, "合計[") === 0) continue;
				if (strpos($ln, "判断[") === 0) continue;
				if (strpos($ln, "診他[") === 0) continue;
				if (strpos($ln, "薬加[") === 0) continue;
				$ln = trim(getTreatment($changeList, $ln));
				
				$obj = array();
				$obj['date'] = $row['entryDate'];
				$obj['id'] = $row['patientId'];
				$rec[$ln][] = $obj;
			}
		}
		return $rec;
	}

	function getYoubi($date){
		$sday = strtotime($date);
		$res = date("w", $sday);
		$day = array("日", "月", "火", "水", "木", "金", "土");
		return $day[$res];
	}
	
	function getWeek($fromDate, $toDate){
		// ProgressSection.treatment をスキャンする
		$rec = array();
		$sql = "SELECT * FROM `FrontTable`
		WHERE `entryDate`>'$fromDate' AND `entryDate`<='$toDate' 
		ORDER BY `entryDate`";
		echo "=====\n $sql \n";
		$result=mysql_query($sql);
		while ($row=mysql_fetch_array($result)){
			$obj = array();
			$obj['date'] = $row['entryDate'];
			$obj['id'] = $row['patientId'];
			$week = getYoubi($row['entryDate']);
			
			$rec[$week][] = $obj;
		}
		return $rec;
	}

	function nameWithPatientId($patientId){
		$sql = "SELECT * FROM `NameSection`
		WHERE `patientId`='$patientId'
		ORDER BY `entryDate` DESC";
		$result=mysql_query($sql);
		
		while ($row=mysql_fetch_array($result)){
			if (strlen($row['patientKanjiName']) > 0)
				return $row['patientKanjiName'];
			else
				return $row['patientRomajiName'];
		}
		return "???";
	}
	
	
	
	
$command = $_GET['command']; $command=htmlspecialchars($command);
$value = $_GET['value']; $value=htmlspecialchars($value);
$value = decodeSTRING($value); // lib.php

// DB を開いて該当レコードを読み込む

// ### セキュリティーを保つには、以下のファイルを外からアクセスできない 
// ### directory に置き、以下の cfg.php の pass をそこへ変更
require_once('../XNOA/cfg.php');

$dbc = mysql_connect($db['host'], $db['user'], $db['pwd']);
$db_select=mysql_select_db($db['dbname']);
mysql_query("set names utf8");

if (strcmp($command,"GET_STATISTICS") == 0){
	// IN: loginName passwd
	// OUT: $row(ユーザ・レコード) no-password error-message
	$args = decodeObject($value);
	// client 側との約束ごと
	$fromDate = $args['fromDate']." 00:00:00";
	$toDate = $args['toDate']." 23:59:59";
	$target = $args['target'];
	
	if (strcmp($target, "ProgressSection.subject") == 0)
		$rec = getSubjects($fromDate, $toDate);
	else if (strcmp($target, "ProgressSection.disease") == 0)
		$rec = getDisease($fromDate, $toDate);
	else if (strcmp($target, "ProgressSection.treatment") == 0)
		$rec = getTreatments($fromDate, $toDate);
	else if (strcmp($target, "week") == 0)
		$rec = getWeek($fromDate, $toDate);
	else
		$rec = array();
	
	echo "<SEPARATOR>";
	echo json_encode($rec);
} else if (strcmp($command,"GET_PATIENT") == 0){
	$args = decodeObject($value);
	// client 側との約束ごと
	$patientId = $args['patientId'];
	$entryDate = $args['entryDate'];
	$target = $args['target'];
	
	$sql = "SELECT * FROM `ProgressSection`
	WHERE `patientId`='$patientId' AND `entryDate`='$entryDate'";
	echo "=====\n $sql \n";
	
	$rec = array();
	$result=mysql_query($sql);
	if (strcmp($target, "ProgressSection.subject") == 0){
		while ($row=mysql_fetch_array($result)){
			if (strpos($row['pageHeader'], "EMOVED") > 0) continue;
			$rec['patientId'] = $row['patientId'];
			$rec['patientName'] = nameWithPatientId($patientId);
			$rec['entryDate'] = $row['entryDate'];
			$rec['subject'] = $row['subject'];
		}
	} else if (strcmp($target, "ProgressSection.treatment") == 0){
		while ($row=mysql_fetch_array($result)){
			if (strpos($row['pageHeader'], "EMOVED") > 0) continue;
			$rec['patientId'] = $row['patientId'];
			$rec['patientName'] = nameWithPatientId($patientId);
			$rec['entryDate'] = $row['entryDate'];
			$rec['subject'] = $row['treatment'];
		}
	} else {
		while ($row=mysql_fetch_array($result)){
			if (strpos($row['pageHeader'], "EMOVED") > 0) continue;
			$rec['patientId'] = $row['patientId'];
			$rec['patientName'] = nameWithPatientId($patientId);
			$rec['entryDate'] = $row['entryDate'];
			$rec['subject'] = $row['subject'];
		}
	}
	echo "<SEPARATOR>";
	echo json_encode($rec);
} else if (strcmp($command,"GET_TABLE_CONTENTS") == 0){
	$args = decodeObject($value);
	// client 側との約束ごと
	$tableName = $args['tableName'];
	
	$buff = getFile($tableName);
	$array = explode("\n", $buff);
	
	echo "<SEPARATOR>";
	echo json_encode($array);
} else if (strcmp($command,"PUT_TABLE_CONTENTS") == 0){
	$args = decodeObject($value);
	// client 側との約束ごと
	$tableName = $args['tableName'];
	$precision = $args['precision']; // 精度
	$value = $args['value'];
	$array = decodeObject($value);
	$buff = implode("\n", $array);
	
	$homeDir = "../Users";
	if (! file_exists($homeDir)) mkdir($homeDir);
	$dir = $homeDir."/STATISTICS";
	if (! file_exists($dir)) mkdir($dir);
	$path = "$dir/$tableName";

	echo "<SEPARATOR>";
	if ($handle = fopen($path, 'w')) {
		// オープンしたファイルに $value を書き込む
		if (fwrite($handle, $buff) === FALSE) {
			echo "ERROR *** cannot write to ($path)";
		}
		fclose($handle);
	} else
		echo "ERROR *** cannot open ($path)";
	
} else
	echo "*** unknown command: $command ***";

?>
