flash/src/com/caucho/games/sudoku/Sudoku.mxml

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
                xmlns:sudoku="com.caucho.games.sudoku.*"
                addedToStage="onAddedToStage()">

  <mx:Panel title="Caucho Sudoku" id="panel" width="500" 
    paddingTop="20" paddingBottom="20" paddingLeft="20" paddingRight="20"
    horizontalAlign="center">
    <mx:VBox id="layoutBox" horizontalAlign="center">
      <sudoku:BoardComponent id="boardComponent" 
                             scoreBoard="{scoreBoard}"
                             infoLabel="{info}"/>
      <mx:Label id="info"/>
      <sudoku:ScoreBoard id="scoreBoard"/>
    </mx:VBox>
  </mx:Panel>

  <mx:Script>
  <![CDATA[
  import flash.utils.*;
  import flash.events.*;
  import com.caucho.bam.BamError;
  import com.caucho.hmtp.*;

  import mx.core.*;
  import mx.containers.*;
  import mx.controls.*;
  import mx.managers.*;

  private var _playerId:String;
  private var _loginName:String;
  private var _client:HmtpClient;
  private var _popup:TitleWindow;

  /**
   * Called when the game is added to the stage and the loader information
   * is available.  Establishes connection to the server and starts the login
   * process.
   **/
  private function onAddedToStage() : void
  {
    var server:String = this.root.loaderInfo.parameters.sudokuServer;
    var policyUrl:String = this.root.loaderInfo.parameters.policyUrl;

    trace("server = " + server);
    trace("policyUrl = " + policyUrl);

    _client = new HmtpClient("http://" + server + "/sudoku");
    _client.policyUrl = policyUrl;

    _client.addMessageListener(GameFinishMessage, handleGameFinishMessage);

    var login:LoginComponent = new LoginComponent();
    login.client = _client;
    login.sudoku = this;
    _popup = login;

    PopUpManager.addPopUp(login, this, true);
    PopUpManager.centerPopUp(login);
  }

  public function onLogin(event:Event, loginName:String):void
  {
    _loginName = loginName;

    if (event is LoginSuccessEvent) {
      if (_popup != null) {
        PopUpManager.removePopUp(_popup);
        _popup = null;
      }

      var difficulty:String = loaderInfo.parameters.difficulty;

      if (difficulty != null) {
        startGame(difficulty);
      }
      else {
        var select:SelectDifficultyComponent = new SelectDifficultyComponent();
        select.sudoku = this;
        _popup = select;

        PopUpManager.addPopUp(select, this, true);
        PopUpManager.centerPopUp(select);
      }
    }
    else {
      trace("login failure!");
    }
  }

  /**
   * Sends a request to the server to start a new game.
   **/
  public function startGame(difficulty:String = "EASY"):void
  {
    if (_popup != null) {
      PopUpManager.removePopUp(_popup);
      _popup = null;
    }

    var query:GameStartQuery = new GameStartQuery(_loginName, difficulty);

    _client.querySet("sudoku@localhost", query, 
                     onGameStartResult, onQueryError);

    _popup = new TitleWindow();
    _popup.setStyle("borderAlpha", 1.0);
    _popup.title = "Waiting for game to begin";
    PopUpManager.addPopUp(_popup, this, /*modal=*/true);
    PopUpManager.centerPopUp(_popup);

    panel.status = "Waiting...";
  }

  public function onGameStartResult(to:String, from:String, 
                                    start:GameStartResult):void
  {
    if (_popup != null) {
      PopUpManager.removePopUp(_popup);
      _popup = null;
    }

    _playerId = start.playerId;
    scoreBoard.yourScore = 0;
    scoreBoard.opponentScore = 0;

    boardComponent.board = start.board;
    boardComponent.client = _client;
    boardComponent.playerId = start.playerId;
    boardComponent.gameJid = start.gameJid;

    if (_playerId == start.players[0].id)
      panel.status = "Playing against " + start.players[1].name;
    else
      panel.status = "Playing against " + start.players[0].name;
  }

  private function onQueryError(to:String, from:String, 
                                value:Object, error:BamError):void
  {
    trace("onQueryError(" + to + ", " + from + ", " + 
                        value + ", " + error + ")");
  }

  private function handleGameFinishMessage(to:String, 
                                           from:String, 
                                           finish:GameFinishMessage):void
  {
    trace("handleGameFinishMessage(" + finish + ")");

    if (_popup != null) {
      PopUpManager.removePopUp(_popup);
      _popup = null;
    }

    _popup = new TitleWindow();
    _popup.setStyle("borderAlpha", 1.0);

    var text:Text = new Text();
    text.text = "Your Score: " + finish.yourScore(_playerId) + 
                "\nOpponent's Score: " + finish.opponentScore(_playerId);

    if (finish.reason == "Game Over") {

      if (finish.yourScore(_playerId) > finish.opponentScore(_playerId))
        _popup.title = "You Won!";
      else if (finish.opponentScore(_playerId) > finish.yourScore(_playerId))
        _popup.title = "You Lost";
      else
        _popup.title = "Tie game";
    }
    else if (finish.reason == "Disconnect") {
      _popup.title = "Opponent disconnected";
    }

    _popup.addChild(text);

    var button:Button = new Button();
    button.label = "Play again";
    button.addEventListener(MouseEvent.CLICK, playAgain);
    _popup.addChild(button);

    PopUpManager.addPopUp(_popup, this, /*modal=*/true);
    PopUpManager.centerPopUp(_popup);
  }

  private function playAgain(event:Event):void
  {
    if (_popup != null) {
      PopUpManager.removePopUp(_popup);
      _popup = null;
    }

    var difficulty:String = loaderInfo.parameters.difficulty;

    if (difficulty != null) {
      startGame(difficulty);
    }
    else {
      var select:SelectDifficultyComponent = new SelectDifficultyComponent();
      select.sudoku = this;
      _popup = select;

      PopUpManager.addPopUp(select, this, true);
      PopUpManager.centerPopUp(select);
    }
  }
  ]]>
  </mx:Script>
  
</mx:Application>