  /************************************************************************/
  // Variables
  XactikaHand.LOST               = 1;
	XactikaHand.WON                = 1;
	XactikaHand.WAITING_FOR_REPLAY = 2;
	XactikaHand.WAITING_FOR_CARD   = 3;
	XactikaHand.WAITING_FOR_SHAPE  = 4;
	XactikaHand.GAME_OVER	         = 5;

	// Methods
	XactikaHand.prototype.setZeroPoint = XactikaHand_setZeroPoint;
  XactikaHand.prototype.setPlaySpace = XactikaHand_setPlaySpace;
  XactikaHand.prototype.paint        = XactikaHand_paint;
  XactikaHand.prototype.isState      = XactikaHand_isState;
  XactikaHand.prototype.playCard     = XactikaHand_playCard;
  XactikaHand.prototype.playShape    = XactikaHand_playShape;
  XactikaHand.prototype.addCard      = XactikaHand_addCard;
  XactikaHand.prototype.getCard      = XactikaHand_getCard;
  XactikaHand.prototype.leadCard     = XactikaHand_leadCard;
  XactikaHand.prototype.getHandSize  = XactikaHand_getHandSize;
  XactikaHand.prototype.playShape    = XactikaHand_playShape;
  XactikaHand.prototype.nextRound    = XactikaHand_nextRound;
  XactikaHand.prototype.lose         = XactikaHand_lose;
  XactikaHand.prototype.win          = XactikaHand_win;
  XactikaHand.prototype.undo         = XactikaHand_undo;
  XactikaHand.prototype.undoToRound  = XactikaHand_undoToRound;
  XactikaHand.prototype.getRound     = XactikaHand_getRound;

  /************************************************************************/
  function XactikaHand(emptyCard, board)
  {
  	this.emptyCard = emptyCard;
    this.state = XactikaHand.WAITING_FOR_CARD;
    this.cards = new Array();
    this.cardsPlayed = new Array();
    this.cardPlayed = -1;
    this.round = 0;
		this.board = board;
  }
  
  /************************************************************************/
  function XactikaHand_setZeroPoint(zeroPoint)
  {
    this.zeroPoint = zeroPoint;
  }
  /************************************************************************/
  function XactikaHand_lose()
  {
    this.state = XactikaHand.LOST;
  }
  /************************************************************************/
  function XactikaHand_win()
  {
    this.state = XactikaHand.WON;
  }
  /************************************************************************/
  function XactikaHand_setPlaySpace(playSpace)
  {
    this.playSpace = playSpace;
  }  
  /************************************************************************/
  function XactikaHand_addCard(card)
  {
    this.cards[this.cards.length] = card;
//    alert(" Added Card "  + card.toMyString());
  }  
  /************************************************************************/
  function XactikaHand_getCard(place)
  {
    return this.cards[place];
  }  
  /************************************************************************/
  function XactikaHand_playCard(cardPlayed, combo)
  {
    // This is a computer move
    // Can You Beat it?
    var card = null;
    for (var i = 0; i < this.cards.length && card == null; i++)
    {
    	if ((!this.cards[i].isPlayed()) && 
    	    (this.cards[i].getPoints() >= cardPlayed.getPoints()) &&
    	    (combo.isCardValid(this.cards[i])))
      {
      	//We have a winner!
      	card = this.cards[i];
        this.cardPlayed = i;
      }
    }
    // Can you Follow? Play Lowest Card
    if ( card == null)
    {
      for (var i = 0; i < this.cards.length; i++)
      {
        if ((!this.cards[i].isPlayed()) && 
            (combo.isCardValid(this.cards[i])))
        {
          //We have a loser!
          if ((card == null) || (this.cards[i].getPoints() < card.getPoints()))
          {
            card = this.cards[i];
            this.cardPlayed = i;
          }
        }
      }
    }
    // Sluff
    if ( card == null)
    {
      for (var i = 0; i < this.cards.length; i++)
      {
        if (!this.cards[i].isPlayed())
        {
          //We have a Sluff!
          if ((card == null) || (this.cards[i].getPoints() < card.getPoints()))
          {
            card = this.cards[i];
            this.cardPlayed = i;
          }
        }
      }
    }
    //Play The Card
    this.cardsPlayed[this.round] = this.cardPlayed;
    card.setPlayed(true);
    return card;
  }
  /************************************************************************/
  function XactikaHand_leadCard(place)
  {
    if ((this.state == XactikaHand.WAITING_FOR_CARD) && (!this.cards[place].isPlayed()))
    {
    
      this.cardPlayed = place;
      this.cards[place].setPlayed(true);
      this.state =  XactikaHand.WAITING_FOR_SHAPE;
      this.cardsPlayed[this.round] = place;
			this.board.setCommentary("Pick a shape");
      return this.cards[place];
    }
    else if (this.state == XactikaHand.WAITING_FOR_SHAPE)
    {
      alert("You must choose a shape");
    }
    else if (this.state == XactikaHand.GAME_OVER)
    {
      alert("You Won Already");
    }
    else if (this.state == XactikaHand.LOST)
    {
      alert("You Have Lost.");
    }
    else
    {
      alert("You already played that card");  
    }
    return null;
  }  
  /************************************************************************/
  function XactikaHand_playShape(shape)
  {
  	if(XactikaHand.WAITING_FOR_SHAPE == this.state)
    {
      this.combo = new XactikaCombination(shape, this.cards[this.cardPlayed].getShape(shape));
      this.state = XactikaHand.WAITING_FOR_REPLY;
      return this.combo;
    }
    else
    {
    	alert("You can not choose a shape until you have led a card.");
    	return null;
    }
  }  
  /************************************************************************/
  function XactikaHand_nextRound()
  {
    if (this.state != XactikaHand.LOST)
    {
      this.round++;
      this.cardPlayed = -1;
      this.state = (this.cards.length == this.round) ? XactikaHand.GAME_OVER : XactikaHand.WAITING_FOR_CARD;   
    }
  } 
  /************************************************************************/
  function XactikaHand_getHandSize()
  {
    return this.cards.length;
  } 
  /************************************************************************/
  function XactikaHand_getRound()
  {
    return this.round;
  } 
  /************************************************************************/
  function XactikaHand_undo()
  {
    if (this.isState(XactikaHand.WAITING_FOR_SHAPE))
    {
      this.undoToRound(this.round);
    }
    else if (this.isState(XactikaHand.WAITING_FOR_CARD))
    {
      this.undoToRound(this.round - 1);
    }
  } 
  /************************************************************************/
  function XactikaHand_undoToRound(number)
  {
    this.cardPlayed = -1;
    this.state = XactikaHand.WAITING_FOR_CARD;
    this.round = number;
    for(var i = 0; i < this.cards.length; i++)
    {
    	this.cards[i].setPlayed(false);
    }
    this.cardsPlayed.length = this.round;
    for(var i = 0; i < this.round; i++)
    {
      this.cards[this.cardsPlayed[i]].setPlayed(true);
    }
  } 
  /************************************************************************/
  function XactikaHand_paint(number)
  {
//    alert("ZeroPoint ->" + this.zeroPoint);
//    alert("PlaySpace ->" + this.playSpace);
//    alert("HandSize ->" + this.getHandSize());
    for(var i = 0; i < this.cards.length; i++)
    {
      if (this.cards[i].isPlayed())
      {
        document.images[i + this.zeroPoint].src = this.emptyCard;
      }
      else      
      {
        document.images[i + this.zeroPoint].src = this.cards[i].getImageURL();
      }
    }
    
    if (this.cardPlayed != -1)
    {
      document.images[this.playSpace].src = this.cards[this.cardPlayed].getImageURL();
    }
    else
    {
      document.images[this.playSpace].src = this.emptyCard;
    }
  }  
  /************************************************************************/
  function XactikaHand_isState(state)
  {
    return (this.state == state);
  }  
  /************************************************************************/
  function XactikaHand_toMyString()
  {
  	return  "[Shading = " + this.shading + ",Symbol = " + this.symbol +
  		      ",Color = " + this.color + ",Number = " + this.number + "]";
  }
  

  /************************************************************************/
  /************************************************************************/
  XactikaCombination.prototype.toString    = XactikaCombination_toString;
  XactikaCombination.prototype.isCardValid = XactikaCombination_isCardValid;
  /**
    * Small class for the shape and Number Combination
    *
    **/
  function XactikaCombination(shape,number)
  {
    this.shape = shape;
    this.number = number;
  }
  /************************************************************************/
  function XactikaCombination_toString()
  {
    var text = "[" + this.number + " " + XactikaCard.getShapeText(this.shape) + "]";
    return text;
  }
  /************************************************************************/
  function XactikaCombination_isCardValid(card)
  {
    return (card.getShape(this.shape) == this.number);
  }
  
  /************************************************************************/
  /************************************************************************/