<?php
/*
 * interop_というプレフィックスが付けられたメソッドは互換性を維持するために使用されている。(2010-12-05 enogu)
 */

/**
 * チャットルームのユーザー情報と基本的なユーザー処理を提供します。
 */
class ChatUser {
  var $db;

  var $id;
  var $room_id;
  var $player_id;
  var $user_no;
  var $uname;
  var $handle_name;
  var $sex;
  var $live;
  var $profile;
  var $last_words;
  var $icon_no;
  var $icon_filename;
  var $color;

  /**
   * データベース接続を指定して、ChatRoomクラスの新しいインスタンスを初期化します。
   * @param ChatEngine $engine 有効なデータベース接続を保持したChatEngineオブジェクト
   */
  function __construct($engine) {
    $this->db = $engine;
  }

  /**
   * 名前と値を指定して、オブジェクトに未定義のプロパティを設定します。
   * @param string $name 呼び出されたプロパティの名前
   * @param mixed $value プロパティに設定されようとした値
   */
  function __set($name, $value) {
    switch($name) {
      case 'role':
        if (is_string($value)) {
          $this->role = $value != '' ? explode(',', $value) : array();
	    }
        elseif (is_array($value)) {
          $this->role = $value;
        }
	    break;
    }
  }

  public function LoadPlayerInfoFromRequest($request) {
    $this->handle_name = $request->handle_name;
    $this->profile = $request->profile;
    $this->sex = $request->sex;
    $this->icon_no = $request->icon_no;
    $this->roles = $request->role;
  }

  /**
   *
   * @return <type>
   */
  public function UpdatePlayerInfo() {
    $sql = <<<SQL
INSERT INTO jinrou_players (user, user_no, handle_name, profile, sex, live, roles)
VALUES (:user_id, :user_no, :handle_name, :profile, :sex, :live, :roles)
SQL;
    $bindings = array(
      ':user_id' => $this->id,
      ':handle_name' => $this->handle_name,
      ':user_no' => $this->user_no,
      ':profile' => $this->profile,
      ':live' => $this->live,
      ':roles' => serialize($this->roles)
    );
    $stmt = $db->prepare($sql);
    if ($stmt->execute($bindings)) {
      return true;
    }
    return false;
  }

  /**
   * ユーザーを新しいプレイヤーとして追加します。
   * @return 追加できた場合true,失敗した場合false
   */
  public function RegisterNewPlayerInfo() {
    if ($this->VerifyHandleName()) {
      $stmt = $this->db->prepare(<<<SQL
INSERT INTO jinrou_players (user, user_no, handle_name, profile, sex, live, roles)
SELECT
  :user_id,
  MAX(ply.user_no) + 1 AS user_no,
  :handle_name,
  :profile,
  :sex,
  :live,
  :roles
FROM jinrou_players AS ply
  INNER JOIN jinrou_users AS usr
    ON ply.user = usr.id
WHERE usr.room = :room_id
  user.kicked = 0
SQL
      );
      $bindings = array(
        ':user_id' => $this->id,
        ':handle_name' => $this->handle_name,
        ':user_no' => $this->user_no,
        ':profile' => $this->profile,
        ':live' => $this->live,
        ':roles' => serialize($this->roles)
      );
      if ($stmt->execute()) {
        $this->user_no = $stmt->fetchColumn();
        $stmt->closeCursor();
        return true;
      }
    }
    return false;
  }

  /**
   * ハンドル名が登録可能かどうか検査します。
   * @return boolean ハンドル名が登録可能な場合true,それ以外の場合false
   */
  private function VerifyHandleName() {
    $sql = <<<SQL
SELECT ply.id AS conflicted
FROM jinrou_players AS ply
  INNER JOIN (
    SELECT MAX(ply.id) AS id
    FROM jinrou_players AS ply
      INNER JOIN jinrou_users AS usr
        ON ply.user = usr.id
    WHERE usr.room = :room_id
    GROUP BY ply.user
  ) AS current_players
    USING(id)
WHERE ply.handle_name = :handle_name
  AND ply.user <> :user_id
SQL;
    $bindings = array(
      ':user_id' => $this->id,
      ':room_id' => $this->room_id,
      ':handle_name' => $this->handle_name,
    );
    $stmt = $db->prepare($sql);
    if ($stmt->execute($bindings)) {
      $conflicted = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
      if (count($conflicted) == 0) {
        return true;
      }
    }
    return false;
  }
}
?>
