package genericcard;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;

/**
 *
 @author Oran
 */
public class PlayingCard extends GenericCard{
    
    private int value=0,fs=20;      //fs is font point size
    private Font font;
    private static String H,D,S,C;  //one character strings with Unicode symbol for the suit, set in constructor
    /** Creates a new instance of PlayingCard */
    public PlayingCard() {super();//faceup true, sideways false
    setHeight(141);setWidth(101);setArc(12);
    char temp[]{'H'};
    H=new String(temp);
    temp[0]='D';
    D=new String(temp);
    temp[0]='S';
    S=new String(temp);
    temp[0]='C';
    C=new String(temp);
    font= new Font("Century",Font.BOLD,fs);
    }
    public int getValue(){return value;}
    public PlayingCard(int v){
        this();
        value=v%52;
    }
    public Color getColor(){
        Color r=new Color(0);
        if (value/26==0)r=Color.red;
        else r=Color.black;
        return r;
    }
    public boolean isRed(){
        if(value/26==0)return true;
        else return false;
    }
    public boolean isBlack(){
        if(value/26==1)return true;
        else return false;
    }
    public String getSuit(){
        int sn=value/13;
        String r=new String();
        switch(sn){
            case 0:r=H;break;
            case 1:r=D;break;
            case 2:r=S;break;
            case 3:r=C;break;
        }
        return r;
    }
    public int getNumber(){
        return (value%13)+1;
    }
    public String getType(){
        int v=(value%13)+1;
        String r=new String();
        
        if(v<11)r=Integer.toString(v);
        else switch(v){
            case 11:r="J";break;
            case 12:r="Q";break;
            case 13:r="K";break;
        }
        return r;
    }
    public String getTypeA(){
        String r= new String();
        r=getType();
        if(r.equals("1"))r="A";
        return r;
    }
    public String getFace(){return getTypeA();}
    public void setCard(int type,int suit){
        if(type>=&& type <=13)
            if(suit>=&& suit<=3)
                value= suit*13 + type-1;
    }
    public void setValue(int v){value=v%52;}
    public void randomize(){setValue(  (int)(Math.random()*52d)  );}
    public String toString(){return getFace()+"of"+getSuit();}
    //overwritten methods
    
    public void drawFront(Graphics g){
        int x,y,w,h;
        x=getX();
        y=getY();
        if(isSideways()){w=getHeight();h=getWidth();else {h=getHeight();w=getWidth();}
        g.setColor(Color.white);
        g.fillRoundRect(x,y,w,h,getArc(),getArc());
        g.setColor(Color.blue);
        g.drawRoundRect(x,y,w-1,h-1,getArc(),getArc());
        g.setColor(getColor());
        g.setFont(font);
        //g.drawString(getSuit(),x+w/2 -fs/2,y+h/2);
        if(getNumber()==10)
            g.drawString(getTypeA(),x+w-fs-getArc()/2,y+fs/2+getArc()/2);
        else
            if(getNumber()>=12)
                g.drawString(getTypeA(),x+w-(fs*2)/3-getArc()/2,y+fs/2+getArc()/2);
            else
                g.drawString(getTypeA(),x+w-fs/2-getArc()/2,y+fs/2+getArc()/2);
        g.drawString(getTypeA(),x+getArc()/3,y+h-getArc()/2);
        g.drawString(getSuit(),x+getArc()/3,y+fs/2+getArc()/2);
        g.drawString(getSuit(),x+w-(fs*2)/3-getArc()/2,y+h-getArc()/2);
        
        
    }
    public void drawBack(Graphics g){
        super.drawBack(g);
        g.setColor(Color.blue);
        int x,y,w,h;
        x=getX();
        y=getY();
        if(isSideways()){w=getHeight();h=getWidth();else {h=getHeight();w=getWidth();}
        g.drawRoundRect(x,y,w-1,h-1,getArc(),getArc());
    }
    
}



class SolitareDeck extends CardPile {
    public SolitareDeck(){
        super(52);
        //deck.setLocation(10,10);
        setOverlap(5);
        setOffset(1,2);
        setName("deck");
        setFacedown(true);
        for(int i=0;i<52;i++)
            addCard(new PlayingCard(i));
        setDim(101,141);
        for(int i=0;i<7;i++)
            shuffle();
        
    }
    public void mouseClicked(MouseEvent e,CardPile targetPile){
        //if the deck is empty, put the whole hand back in the deck
        if(isEmpty())
            while(!targetPile.isEmpty())
                addCard(targetPile.draw());
        //deal three cards, hopefully to the hand
        else{
            if(!isEmpty())targetPile.addCard(draw());
            if(!isEmpty())targetPile.addCard(draw());
            if(!isEmpty())targetPile.addCard(draw());
            
        }
    }
}

class SolitareHand extends CardPile {
    
    public SolitareHand(){
        super();
        //setLocation(160,10);
        setOverlap(1);
        setOffset(3,0);
        setModulo(52);
        setName("hand");
        setFaceup(true);
        setDim(170,141);//three overlapping cards wide
        standardizeAll();
    }
    
    public void mousePressed(MouseEvent e,CardPile mousePile){
        mousePile.setLocation(e.getPoint());
        if(!isEmpty())
            mousePile.addCard(draw());
    }
    
}

final class SolitareStack extends CardPile {
    private int nDown;      //number of cards facedown in the pile
    public SolitareStack(){
        super();
        //setLocation(350,20);
        setOverlap(1);
        setOffset(0,22);
        setName("stack");
        setFaceup(true);
        setDim(101,141);//13 cards overlapping cards high
        standardizeAll();
        nDown=0;
    }
    public SolitareStack(CardPile deck,int n){
        super();
        nDown=n;
        //setLocation(350,20);
        setOverlap(1);
        setOffset(0,25);
        setName("stack");
        setDim(101,141);//13 cards overlapping cards high
        for(int i=0;i<n;i++)
            if(!deck.isEmpty())
                addCard(deck.draw());
        setFaceup(true);
        standardizeAll();
    }
    public int getCardsPlayed(){return size()-nDown;}
    public void standardize(int index,GenericCard c){
        if(index<nDown)c.setFaceup(false);
        else c.setFaceup(true);
        
        c.setLocation(getLocation());
        if(index>=nDown)
            c.translate( (index-nDown)*getOffset().x , (index-nDown)*getOffset().y);
        else c.translate(0(index-nDown)*2);
    }
    public GenericCard getCard(int i){
        if(i<nDown && i>=&& i<size())
            nDown--;
        return (GenericCard)super.remove(i);
    }
    public void mouseClicked(MouseEvent e, CardPile whatever){
        if(!isEmpty() && !peekTop().isFaceup()) {
            peekTop().setFaceup(true);
            nDown--;
        }
        standardizeAll();
    }
    public void mousePressed(MouseEvent e,CardPile CardPile){
        GenericCard temp;
        int p;
        temp=cardAt(e.getPoint());
        if(temp!=null && temp.isFaceup()) {
            p=lastIndexOf(temp);        //hopefully, cards are not duplicated
            while(size()>p){
                CardPile.addCard(getCard(p));
            }
        }   
    }
    public void mouseReleased(MouseEvent e,CardPile CardPile){
        int tempSize;
        tempSize=CardPile.size();
        for(int i=0;i<tempSize;i++){
            PlayingCard m=(PlayingCard)CardPile.peekBottom();
            if(isEmpty())                                       //if the stack is empty
            {if(m.getNumber()==13)addCard(CardPile.drawBottom());}      //Put a King on the stack
            else {                              //if the stack isn't empty,
                PlayingCard b=(PlayingCard)peekTop();   //let b be the top card
                //if the solitare placement rule holds,
                if(!(b.getColor().equals(m.getColor()))
                && m.getNumber()+1==b.getNumber()  && b.isFaceup())
                    addCard(CardPile.drawBottom());      //Put it on the stack
            }//end else
        }//end if not empty
    }
}

final class SolitareScorePile extends CardPile {
    private int acceptSuit=-1;
    
    SolitareScorePile(){
        super();
        setOffset(1,2);
        setOverlap(2);
        setDim(101,141);
        setName("score");
        setFaceup(true);
    }
    public void mouseReleased(MouseEvent e,CardPile mousePile){
        if(mousePile!=null && mousePile.size()==1){
            PlayingCard m=((PlayingCard)mousePile.peekTop());
            if(isEmpty() && m.getNumber()==1){  //always put an ace on an empty score pile
                acceptSuit = m.getValue()/13;
                addCard(mousePile.draw());
            else if(m.getValue()/13==acceptSuit && !isEmpty()
            && m.getNumber()==((PlayingCard)peekTop()).getNumber()+1)     //also add the next highest card
                addCard(mousePile.draw());
        }
        
    }
    public void mousePressed(MouseEvent e,CardPile CardPile){
        CardPile.setLocation(e.getPoint());
        if(!isEmpty())
            CardPile.addCard(draw());
    }
}
Java2html