
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Patience extends JFrame {

	private Card emptyCard = new Card() ;

	private Discard pile[]  = new Discard[4] ;
	private Discard discard = new Discard() ;
	private Talon   talon   = new Talon() ;

	private Container container = getContentPane() ;
	private JButton button[]   = new JButton[4] ;
	private JButton discButton = new JButton() ;
	private JButton moveButton = new JButton() ;
	private JButton talnButton = new JButton() ;

	private Patience() {
		super( "Patience" ) ;

		container.setLayout( new GridLayout(2,4) );

		ButtonHandler handler = new ButtonHandler() ;

		for ( int i = 0 ; i < 4 ; i++) {
			pile[i]   = new Discard() ;
			button[i] = new JButton() ;
			button[i].setText( " " + pile[i].getLength() ) ;
			button[i].setIcon( new ImageIcon("cards/0.png") ) ;
			button[i].addActionListener( handler ) ;
			container.add( button[i] ) ;
		}

		discButton.setText( " " + discard.getLength() ) ;
		discButton.setIcon( new ImageIcon("cards/0.png") ) ;
		discButton.addActionListener( handler ) ;
		container.add( discButton ) ;

		moveButton.setText("next") ;
		moveButton.addActionListener( handler ) ;
		container.add( moveButton ) ;

		talnButton.setText( " " + talon.getLength() ) ;
		talnButton.setIcon( new ImageIcon("cards/deck.png") ) ;
		talnButton.addActionListener( handler ) ;
		container.add( talnButton ) ;

		setSize( 600, 400 );
		setVisible( true );
	}


	private class ButtonHandler implements ActionListener {
		public void actionPerformed ( ActionEvent e ) {

			for ( int j = 0 ; j < 4 ; j++ ) if ( e.getSource() == button[j] ) {
				String output = "" ;
				for ( int i = pile[j].getLength()-1 ; i >=0 ; i-- )
					output += pile[j].cardAt(i).getValue() + " of " + pile[j].cardAt(i).getSuit() + "\n" ;
				JScrollPane jOutput = new JScrollPane( new JTextArea(output,10,10) ) ;
				JOptionPane.showMessageDialog(null,jOutput,"Pile",JOptionPane.PLAIN_MESSAGE) ;
			}

			if ( e.getSource() == discButton ) {
				String output = "" ;
				for ( int i = discard.getLength()-1 ; i >=0 ; i-- )
					output += discard.cardAt(i).getValue() + " of " + discard.cardAt(i).getSuit() + "\n" ;
				JScrollPane jOutput = new JScrollPane( new JTextArea(output,10,10) ) ;
				JOptionPane.showMessageDialog(null,jOutput,"Discard Pile",JOptionPane.PLAIN_MESSAGE) ;
			}

			if ( e.getSource() == moveButton ) {
				if ( noThrowOffs() )
					if ( noMovesToEmpty() )
						if ( noDealFour() ) {
							boolean won = true ;
							String result ;
							for ( int i = 0 ; i < 4 ; i++ )
								won = won && ( pile[i].getLength() == 1 ) ;
							if ( won )
								result = "You won!" ;
							else
								result = "You lost!" ;
							JOptionPane.showMessageDialog(null,result,"Game over",JOptionPane.PLAIN_MESSAGE) ;
						} 
			}

			if ( e.getSource() == talnButton ) {
				String output = "" ;
				for ( int i = talon.getLength()-1 ; i >=0 ; i-- )
					output += talon.cardAt(i).getValue() + " of " + talon.cardAt(i).getSuit() + "\n" ;
				JScrollPane jOutput = new JScrollPane( new JTextArea(output,10,10) ) ;
				JOptionPane.showMessageDialog(null,jOutput,"Talon",JOptionPane.PLAIN_MESSAGE) ;
			}
		}
	}


	private boolean noThrowOffs() {
		for ( int i = 0 ; i < 4 ; i++ )
			for ( int j = 0 ; j < 4 ; j++ ) {
				if ( i == j ) continue ;
				if ( isLess( pile[i].topCard(), pile[j].topCard() ) ) {
					Card iCard = pile[i].popCard() ;
					button[i].setText( " " + pile[i].getLength() ) ;
					button[i].setIcon( new ImageIcon(pile[i].topCard().getPNG()) ) ;
					discard.pushCard( iCard ) ;
					discButton.setText( " " + discard.getLength() ) ;
					discButton.setIcon( new ImageIcon(iCard.getPNG()) ) ;
					return false ;
				}
			}
		return true ;
	}


	private boolean noMovesToEmpty() {
		for ( int i = 0 ; i < 4 ; i++ )
			for ( int j = 0 ; j < 4 ; j++ ) {
				if ( i == j ) continue ;
				if ( pile[i].isEmpty() && ( pile[j].getLength() > 1 ) ) {
					Card card = pile[j].popCard() ;
					button[j].setText( " " + pile[j].getLength() ) ;
					button[j].setIcon( new ImageIcon(pile[j].topCard().getPNG()) ) ;
					pile[i].pushCard( card ) ;
					button[i].setText( " " + pile[i].getLength() ) ;
					button[i].setIcon( new ImageIcon(card.getPNG()) ) ;
					return false ;
				}
			}
		return true ;
	}


	private boolean noDealFour() {
		for ( int i = 0 ; i < 4 ; i++ ) {
			if ( talon.isEmpty() ) {
				talnButton.setText( " " + talon.getLength() ) ;
				talnButton.setIcon( new ImageIcon(emptyCard.getPNG()) ) ;
				return true ;
			}
			Card card = talon.popCard() ;
			talnButton.setText( " " + talon.getLength() ) ;
			pile[i].pushCard( card ) ;
			button[i].setText( " " + pile[i].getLength() ) ;
			button[i].setIcon( new ImageIcon(card.getPNG()) ) ;
		}
		return false ;
	}


	private boolean isLess( Card aCard, Card bCard ) {
		String aSuit  = aCard.getSuit() ;
		String aValue = aCard.getValue() ;
		String bSuit  = bCard.getSuit() ;
		String bValue = bCard.getValue() ;
		int aNumValue = Card.validValue.length ;
		int bNumValue = -1 ;

		if ( aSuit.equals( bSuit ) ){
			for ( int i = 0 ; i < Card.validValue.length ; i++ ) {
				if ( Card.validValue[i].equals( aValue ) ) aNumValue = i ;
				if ( Card.validValue[i].equals( bValue ) ) bNumValue = i ;
			}
			if ( aNumValue == 1 ) aNumValue += 13 ; // Aces are bigger than kings so add 13
			if ( bNumValue == 1 ) bNumValue += 13 ;
			if ( aNumValue < bNumValue ) return true ; else return false ;
		} else {
			return false ;
		}
	}


	public static void main( String args[] ) {
		Patience game = new Patience();
		game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
	}

}


