(function() {
    function Command() {
	this.init = function() {
	    this.defs = this.get_defs();
	};

	this.res_json = null;
	this.say_left_timer = null;
	this.say_right_timer = null;
	this.is_now_eval = false;
	this.defs = {};
//	this.cgi_url = "http://colinux/Ruby_de_Lisp/cgi/lispeval.cgi";
	this.cgi_url = "http://www.narihiro.info/putarou/cgi/lispeval.cgi";
	this.eval = function(sexp) {
            var url = this.cgi_url;
	    if(!sexp || sexp.trim == "") return;
	    var param = "input_word=" + lsh.util.sexp_escape(sexp);
		//$('input_word').value = sexp;
	    lsh.command.is_now_eval = true;
	    new Ajax.Request(url, {method : "post", parameters : param, onComplete : this.controll_eval
	    });
	};

	this.controll_eval = function(req) {
	    lsh.command.is_now_eval = false;
	    var lisp = eval(req.responseText);
	    if(lsh.command.execute_command(lisp)) {
		lsh.command.show_eval(lisp.res_eval);
	    }
	    lsh.command.res_json = lisp;
	};

	this.show_eval = function(res) {
	    scrolltop = $("lsh").scrollTop + 100;
		$("lsh").value += "\n" + lsh.res_lisp + res;
		$("lsh").value += "\n" + lsh.input_lisp;
		$("lsh").selectionStart = $("lsh").value.length;
		$("lsh").selectionEnd = $("lsh").value.length;
		lsh.shell.set_info();
		$("lsh").scrollTop = scrolltop;
	}

	this.delete_defs = function() {
	    delete_def = $("lsh").value.split("\n");
	    len = delete_def.length-1;
	    while(true) {
		if(delete_def[len].match(/^Lisp >/)) {
		    break;
		}
		delete_def[len] = null;
		len--;
	    }
	    text = "";
	    delete_def = delete_def.compact();
	    for(var i=0,len=delete_def.length;i<len;i++) {
		kaigyou = "\n";
		if(i == (len-1)) kaigyou = "";
		text += delete_def[i] + kaigyou;
	    }
	    $("lsh").value = text;
	}

	this.execute_command = function(lisp) {
	    if(!lsh.util.isNullOrEmpty(lisp.say_left_putarou)) {
		this.say_left_putarou(lisp.say_left_putarou);
		return true;
	    }
	    if(!lsh.util.isNullOrEmpty(lisp.say_right_putarou)) {
		this.say_right_putarou(lisp.say_right_putarou);
		return true;
	    }
	    if(!lsh.util.isNullOrEmpty(lisp.struct)) {
		this.show_struct(lisp.struct);
		return false;
	    }
	    if(!lsh.util.isNullOrEmpty(lisp.completion)) {
		this.show_defs(lisp.completion);
		return false;
	    }
	    return true;

	};

	this.show_defs = function(defs) {
	    scrolltop = $("lsh").scrollTop + 100;
	    this.delete_defs();
	    cursor_num = lsh.shell.info.cursor_num -1;
	    res = defs;
	    if(defs.length == 1) {
		before_lsh = $("lsh").value.substr(0, lsh.shell.info.cursor) + defs[0];
		cursor = before_lsh.length;
		$("lsh").value = before_lsh + $("lsh").value.substr(lsh.shell.info.cursor, $('lsh').value.length);
		$("lsh").selectionStart = cursor;
		$("lsh").selectionEnd =  cursor;
		$("lsh").scrollTop = scrolltop;
		return;
	    }

	    if(typeof(defs) != "string") {
		res = "";
		var max = 100;
		var now_cnt = 0;
		for(var i=0,len=defs.length;i<len;i++) {
		    res += (defs[i] + "　");
		    now_cnt += defs[i].length
		    if(now_cnt > max) {
			res += "\n"
			now_cnt = 0
		    }
		}
	    }
		$("lsh").value += "\n" + res;
		$("lsh").selectionStart = cursor_num;
		$("lsh").selectionEnd = cursor_num;
		$("lsh").scrollTop = scrolltop;
	};

	this.say_left_putarou = function(say_word) {
	    var escape_say = lsh.util.sexp_say_escape(say_word);
	    $('putarou_say_left').innerHTML = escape_say;
	    new Effect.Appear($('putarou_fukidashi_left') );
	    if(!lsh.command.say_left_timer) {
		lsh.command.say_left_timer = setInterval(function() {
		    new Effect.Fade($('putarou_fukidashi_left'));
		    clearInterval(lsh.command.say_left_timer);
		    lsh.command.say_left_timer = null
		}, 40000);
	    }
	};

	this.say_right_putarou = function(say_word) {
	    var escape_say = lsh.util.sexp_say_escape(say_word);
	    $('putarou_say_right').innerHTML = escape_say;
	    new Effect.Appear($('putarou_fukidashi_right') );
	    if(!lsh.command.say_right_timer) {
		lsh.command.say_right_timer = setInterval(function() {
		    new Effect.Fade($('putarou_fukidashi_right'));
		    clearInterval(lsh.command.say_right_timer);
		    lsh.command.say_right_timer = null
		}, 40000);
	    }
	};

	this.show_struct = function(struct) {
	    this.remove_struct(1);
	    if(typeof(struct) == "string") {
		var car_value = struct;
		struct = { car: car_value , cdr: "NIL" }
	    }

	    this.create_struct(struct, 1, "lsh.command.res_json.struct", 20, false);
	};

	this.create_struct = function(struct, cnt, position_str, width, is_car) {
	    var div = document.createElement("div");
	    var struct_id = "struct_" + cnt;
	    div.setAttribute("id", struct_id);
	    div.setAttribute("style", "display: none;");
	    var car = null;
	    var cdr = null;
	    var ele = null;
	    var is_first_create = false;
	    var left_style = "";
	    var car_posi = "";
	    var car_point = "";
	    while(true) {
		car_point = "";
		if(is_first_create) {
		    left_style = "";
		} else {
		    left_style = "margin-left: " + width + "px;"
		}
		cdr = struct.cdr;
		if(typeof(struct.car) == "string") {
		    car = struct.car;
		    list_func = "";
		    car_posi = "";
		} else {
		    car = "LIST";
		    list_func = "lsh.command.remove_struct("+(cnt+1)+");";
		    list_func +=  "lsh.command.create_struct("+ position_str +".car, "+ (cnt + 1) +", '" + position_str + ".car', " + width + ", true);";
		    car_point = "cursor:pointer;";
		    car_posi = position_str + ".car";
		}
		if(cdr == "NIL") {
		    ele = this.create_node("", car, cdr, is_car, false, left_style, car_posi, list_func, car_point);
		    is_first_create = true;
		    div.appendChild(ele);
		    break;
		}
		ele = this.create_node("", car, "　", is_car, true, left_style, car_posi, list_func, car_point);
		is_first_create = true;
		struct = struct.cdr;
		position_str += ".cdr";
		div.appendChild(ele);
		width += 200;
		var is_car = false;
	    }
	    this.next_node(div);
	    $('list_tree_block').appendChild(div);
	    new Effect.Appear($(struct_id));
	};

	this.create_node = function(div_id, car, cdr, is_car, is_cdr, left_style, car_position, list_func, car_point) {
	    var ele = document.createElement("div");
	    ele.setAttribute("id", div_id);
	    ele.setAttribute("style", "height:130px; float:left;" + left_style);
	    
	    var table = document.createElement("table");
	    table.setAttribute("class", "element");

	    var tr1 = document.createElement("tr");

	    var td1_data1 = document.createElement("td");
	    var node_car = document.createElement("img");
	    if(is_car) {
		node_car.setAttribute("src", "img/car.gif");
	    } else {
		node_car.setAttribute("src", "img/null.gif");
	    }
	    node_car.setAttribute("id", car_position);
	    td1_data1.appendChild(node_car);
	    tr1.appendChild(td1_data1);
	    table.appendChild(tr1);

	    var tr2 = document.createElement("tr");

	    var td2_data1 = document.createElement("td");
	    td2_data1.setAttribute("class", "data");
	    td2_data1.appendChild(document.createTextNode(car));
	    tr2.appendChild(td2_data1);
	    
	    var td2_data2 = document.createElement("td");
	    td2_data2.setAttribute("class", "data");
	    td2_data2.appendChild(document.createTextNode(cdr));
	    tr2.appendChild(td2_data2);

	    var td_data3 = document.createElement("td");
	    var node_cdr = document.createElement("img");
	    if(is_cdr) {
		node_cdr.setAttribute("src", "img/cdr.gif");
	    } else {
		node_cdr.setAttribute("src", "img/null.gif");
	    }
	    if(!lsh.util.isNullOrEmpty(list_func)) {
		td2_data1.setAttribute("onclick", list_func);
		td2_data1.setAttribute("style", car_point);
	    }
	    td_data3.appendChild(node_cdr);
	    tr2.appendChild(td_data3);

	    table.appendChild(tr2);
	    ele.appendChild(table);
	    return ele;
	};

	this.next_node = function(div) {
	    var br = document.createElement("br");
	    br.setAttribute("style", "clear:both;");
	    div.appendChild(br);
	}

	this.remove_struct = function(cnt) {
	    var struct_id = "";
	    var parent = $('list_tree_block');
	    while(true) {
		struct_id = "struct_" + cnt;
		re_tar = $(struct_id);
		if(!re_tar) break;
		parent.removeChild(re_tar);
		cnt++;
	    }
	};


    };
    var C = new Command();
//    C.init();
    lsh["command"] = C;

})();

