//  This is -*- c++ -*- code

#include <6170.h>
#include <human_player.h>
#include <ps5/error_response.h>
#include <ps5/url_ops.h>
#include <top_node.h>

human_player::human_player(string name, long total_time, top_node *tnode, 
			   bool start_detached) :player(name,total_time) {
    top = tnode;
    attached = !start_detached;
    my_index = -1;      
}


void human_player::detach(){
    stop_clock();
    top->add_to_detached(get_game(), my_index);
    attached = false;
}

void human_player::attach(string name){
    top->remove_from_detached(get_game());
    attached=true;
    set_name(name);
}

void human_player::display(extensions *ext, ostream &body) const {
  string tpos;

  body << "<H3>" << get_name();
  if (get_position(tpos)) 
    body << "(" << tpos << ")";
  body << ": Time remaining(ms): " << get_time() << "<FORM METHOD=\"GET\" "
    << "ACTION=\"" << get_game()->uri_with_move() << "player/" << my_index
    << "/set_time\">";
  body << "<INPUT NAME=\"msecs\" VALUE=\"" << get_time() << "\">";
  body << "<INPUT TYPE=SUBMIT VALUE=\"Set Time\"></FORM></H3><P>" << endl;
  body << "<FORM METHOD=\"GET\" ACTION=\"" << get_game()->uri_with_move() 
    << "player/" << my_index << "/set_name\">" << endl;
  body << "Name: ";
  body << "<INPUT NAME=\"name\" VALUE=\"" << get_name() << "\">" << endl;
  body << "<INPUT TYPE=SUBMIT VALUE=\"Change Name\"><BR>";
  body << "</FORM>";
  if (!get_game()->get_board()->valid_move_available(my_index)) {
    body << "<A HREF=\"" << get_game()->uri() << "display?player=" 
      << my_index << "\">";
    body << "Can I move yet?" <<  "</A><BR>" << endl;
  }
  body << "<A HREF=\"" << get_game()->uri_with_move() << "player/" 
    << my_index << "/detach\">";
  body << "Detach from this Game" << "</A>" << endl;
  body << "<br>\n";
  body << "<a href=\"" << get_game()->uri_with_move() << "player/"
       << my_index << "/forfeit\">Forfeit game</a>\n";
  body << "<HR>" << endl;
}

void human_player::you_moved(move &m) {
  player::you_moved(m);
  if (attached&&get_game()->get_board()->valid_move_available(my_index)) {
    start_clock();
  } 
}

void human_player::opponent_moved (move &m, int p) {
  player::opponent_moved(m,p);
  if (attached&&get_game()->get_board()->valid_move_available(my_index)) {
    start_clock();
  } 
}

void human_player::state_changed(void) {
  player::state_changed();
  consider_forfeiting();
  if (attached&&get_game()->get_board()->valid_move_available(my_index)) {
    start_clock();
  }
}

void human_player::associate(game *g) {
    player::associate(g);
    my_index = get_game()->player_index(this);
    if (!attached)
      top->add_to_detached(get_game(), my_index);
}


http_response *human_player::get (string request, extensions *ext)
{
    if (!is_associated)
	return new error_response(http_response::INTERNAL_ERROR, "Shouldn't be able to call unassociated player.");
    string first;
    if (!unescape_uri(first_component(request), first))
	return new error_response(http_response::BAD_REQUEST, "Unable to escape decode supplied URI.");
    if ( first == "attach") {
	if (attached)
	    return new error_response(http_response::BAD_REQUEST, "Unable to attach an already attached player.");
	else {
	    map <string, string> *q = parse_query(extract_query(request));
	    if (q->contains("name")){
		attach(q->fetch("name"));
if (get_game()->get_board()->valid_move_available(my_index))
    start_clock();
		return get_game()->display(ext, my_index);
	    }
	    else return new error_response(http_response::BAD_REQUEST, "A request to attach must include a name.");
	}
    }
    else if (first == "detach") {
	if (attached) {
	    stop_clock();
	    detach();
	    return top->get("welcome", ext);
	}
	else return new error_response (http_response::BAD_REQUEST, "No, you can't detach a detached player; sorry.");
    }
    else if (first == "forfeit") {
	if ( get_game()->winner() == my_index) {
	    get_game()->message(get_name()+" tried to forfeit after winning!");
	    return get_game()->display(ext, my_index);
	} else {
	    get_game()->message(get_name() + "forfeits");
	    get_game()->forfeit(my_index);
	    return top->get("welcome", ext);
	}
    }
    
    return player::get(request,ext);
}



