// Player.m
// Project: Cribbage
// Stephan Wacker
// 93-09-16

#import "Player.h"

#import "ScoreBoard.h"
#import "Table.h"
#import "Deck.h"
#import "Cribbage.h"
#import "LocalizableStrings.h"

#import "cribbage.h"


@implementation Player

- changePegColor
{
    [scoreBoard changePegColor];
    return self;
    
}

- (char *) pronoun
{
    [self subclassResponsibility: _cmd];
    return NULL;
}

- (char *) possessivePronoun
{
    [self subclassResponsibility: _cmd];
    return NULL;
}

- (char *) reflexivePronoun
{
    [self subclassResponsibility: _cmd];
    return NULL;
}


- cardInCrib
{
    return cardInCrib;
}


- (int) score
{
    return [scoreBoard score];
}


- startGame
{
    [scoreBoard clear];
    [self emptyHand];
    
    return self;
}


- emptyHand
{
    [super emptyHand];
    [table hideCards: cardsInHand];
    [table hideCard: cardInCrib];
    
    return self;
}


- sortHand
{
    [super sortHand];
    [self displayHand];
    
    return self;
}


- (CARD) firstCut
{
    CARD result	= [deck getCard];
    
    [table upCard: cardInCrib card: result];
    
    return result;
}


- (BOOL) faceUp
//
// Return YES iff cards are displayed face up.
// The computer player should override this method.
//
{
    return YES;
}


- displayCardAt: (int) i
{
    switch( face[i] ) {
      case FACE_NONE :
	[table hideCard: [cardsInHand findCellWithTag: i]];
	break;
      case FACE_UP :
	[table upCard: [cardsInHand findCellWithTag: i] card: hand[i]];
	break;
	break;
      case FACE_DOWN :
	[table downCard: [cardsInHand findCellWithTag: i]];
	break;
    }
    
    return self;
}


- displayHand
{
    int		i;
    
    for( i = 0; i < FULLHAND; i++ )
    {
	[self displayCardAt: i];
    }
    
    return self;
}


- dealCard: (CARD) aCard
//
// Add aCard to the hand.
//
{
    [self addCard: aCard faceUp: [self faceUp]];
    [self displayCardAt: nHand-1];
    
    return self;
}


- discard
{
    return [self subclassResponsibility: _cmd];
}


- prepareForPegging
//
// Count the cards in the hand that have not been played, yet.
//
{
    didGo = NO;
    
    return self;
}


- playOneCard
{
    return [self subclassResponsibility: _cmd];
}


- go
{
    didGo = YES;
    [cribbage didGo: self];
    return self;
}


- (BOOL) validCardAt: (int) i
//
// Return YES iff card number i can be played.
//
{
    return (   face[i] != FACE_NONE
	    && [table sumPlayed] + VAL( hand[i].rank ) <= 31);
}


- (BOOL) canPlay
//
// Return YES iff there is a card in the hand that can be played
// without exceeding 31.
//
{
    int		i;

    for( i = 0; i < FULLHAND; i++ ) {
	if( [self validCardAt: i] ) return YES;
    }
    
    return NO;
}


- (BOOL) anyCards
//
// Return YES iff there are any cards in the hand.
//
{
    int		i;

    for( i = 0; i < FULLHAND; i++ ) {
	if( face[i] != FACE_NONE ) return YES;
    }
    
    return NO;
}


- (BOOL) didGo
{
    return didGo;
}


- playCardAt: (int) i
//
// Play and score the card in position i of the hand.
//
{
    int		points;
    
    face[i] = FACE_NONE;
    
    [table hideCard: [cardsInHand findCellWithTag: i]];
    points = [table playCard: hand[i]];
    
    if( points > 0 ) {
	strcpy( local_buf, [self pronoun] );
	strcat( local_buf, quiet ? " get %d playing " :
			     " get %d points playing " );
	addmsg( LOCAL_BUF, points );
	msgcard( hand[i], FALSE );
	addmsg( PLAY_POINTS_POSTFIX );
	endmsg();
    } else if( !quiet ) {
	strcpy( local_buf, [self pronoun] );
	strcat( local_buf, " play the " );
	addmsg( LOCAL_BUF );
	msgcard( hand[i], FALSE );
	endmsg();
    }
    
    [self peg: points];
    [cribbage didPlay: self card: hand[i]];
    
    return self;
}


- showHand: (CARD *) cards
{
    int		i;
    
    for( i = 0; i < CINHAND; i++ ) {
	[table upCard: [cardsInHand findCellWithTag: i] card: cards[i]];
    }
    
    return self;
}


- scoreHand
{
    int		points;
    
    [self showHand: hand];
    points = scorehand( hand, [deck turnover], CINHAND, NO, YES );
    [self doScoring: "hand" points: points];
    
    return self;
}


- scoreCrib: (CARD *) crib
{
    int		points;
    
    sorthand( crib, CINHAND );
    [self showHand: crib];
    points = scorehand( crib, [deck turnover], CINHAND, YES, YES );
    [self doScoring: "crib" points: points];
    
    return self;
}


- doScoring: (char *) what points: (int) points
{
    sprintf( local_buf, "%s %s scores %%d", [self possessivePronoun], what );
    msg( LOCAL_BUF, (points == 0 ? 19 : points) );
    strcpy( prev_expl, expl ); *expl = '\0';
    [self peg: points];
    [cribbage continueScoring];
    
    return self;
}


- peg: (int) points
//
// Add points to score.
//
{
    if( [scoreBoard peg: points] ) {
	[cribbage winner: self];
    }
    
    return self;
}


- win: (int) gameValue
{
    [scoreBoard win: gameValue];
    return self;
}


@end
