/*
 * CardPile.java
 *
 */

package genericcard;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;

/**
 *
 @author Oran
 */
public class CardPile extends ArrayList{
    
    private String name;                //the name of the card pile, i.e. "deck","hand"
    private boolean faceup,facedown;    //are cards added to the pile face up? face down?
    private Point location;         //decks upper left corner location
    private Dimension dimension;        //decks height and width
    private Point offset;           //where cards added to the pile are placed relative to the deck
    private int overlap;          //how many cards get the same overlap
    private int modulo;             //when to start back at zero offset
    private boolean sloppy;         //is the offset randomized?
    /** Creates a new instance of CardPile */
    public CardPile() {super();init();}
    public CardPile(int cap){super(cap);init();}
    private void init(){
        //initialize non-ArrayList info
        name="";
        sloppy=false;
        overlap=2;
        modulo=100;
        offset= new Point(0,1);
        location=new Point();
        dimension=new Dimension(0,0);
        faceup=false;facedown=false;
        
    }
    
    //positions and orients the card to be the 'index'th card in the deck
    public void standardize(int index,GenericCard c){
        if(facedown)c.setFaceup(false);
        if(faceup)c.setFaceup(true);
        if(sloppy){
            c.setLocation(location);
            c.translate((int)(Math.random()*offset.x)(int)(Math.random()*offset.y));
        }
        else {
            c.setLocation(location);
            c.translate( ((index%modulo)/overlap)*offset.x,((index%modulo)/overlap)*offset.y);
        }
    }
    public void standardizeAll(){
        for(int i=0;i<size();i++)
            standardize(i,peekCard(i));
    }
    public void addCard(int index,GenericCard c){
        if(c!=null){
            standardize(index,c);
            super.add(index,c);}
    }
    
    //adds a card to the top of the deck
    public void addCard(GenericCard c){
        if(c!=null){
            standardize(size(),c);
            super.add(c);
        }
    }
    //adds an entire pile to the top of the deck
    public void addPile(CardPile cp){
        Iterator i=cp.iterator();
        while(i.hasNext()){
            add(i.next());
            i.remove();
        }
        standardizeAll();
    }
    //clear()
    //clone() might need to be changed.  What is a shallow copy?
    //similar returns an new empty deck with the same properties as this
    public CardPile similar(){
        CardPile r=new CardPile();
        r.setLocation(getLocation());
        r.setOffset(getOffset());
        r.setFaceup(getFaceup());
        r.setFacedown(getFacedown());
        r.setSloppy(getSloppy());
        r.setName(getName());
        r.setModulo(getModulo());
        return r;
    }
    public boolean Card(GenericCard c){return super.contains(c);}
    //ensureCapacity()
    public GenericCard peekCard(int i){return (GenericCard)super.get(i);}
    public GenericCard getCard(int i){return (GenericCard)super.remove(i);}
    //isEmpty()
    //iterator()
    public GenericCard draw(){
        if(size()>0)return getCard(size()-1);
        else return null;
    }
    public GenericCard drawBottom(){
        if(size()>0)return getCard(0);
        else return null;
    }
    public GenericCard peekTop(){
        if(size()>0)return peekCard(size()-1);
        else return null;
    }
    public GenericCard peekBottom(){
        if(size()>0)return peekCard(0);
        else return null;
    }
    //methods dealing with deck properties
    public void setDim(int x,int y){dimension.height=y;dimension.width=x;}
    public Dimension getDim(){return (Dimension)dimension.clone();}
    public void autoDim(){
        if(!isEmpty()){
            dimension=peekBottom().getSize();
        }
    }
    public String getName(){return name;}
    public boolean getFaceup(){return faceup;}
    public boolean getFacedown(){return facedown;}
    public void setFaceup(boolean f){faceup=f;if(f)facedown=false;}
    public void setFacedown(boolean f){facedown=f;if(f)faceup=false;}
    public boolean getSloppy(){return sloppy;}
    public void setName(String newname){name=newname;}
    public void setSloppy(boolean s){sloppy=s;}
    public Point getLocation(){return (Point)location.clone();}
    public void setLocation(Point p){location=(Point)p.clone();standardizeAll();}
    public void setLocation(int x,int y){location.x=x;location.y=y;standardizeAll();}
    public void setOverlap(int o){if(o>=1)overlap=o;standardizeAll();}
    public int getOverlap(){return overlap;}
    public void setModulo(int m){if(m>=1)modulo=m;standardizeAll();}
    public int getModulo(){return modulo;}
    public Point getOffset(){return (Point)offset.clone();}
    public void setOffset(Point p){offset=(Point)p.clone();standardizeAll();}
    public void setOffset(int x,int y){offset.x=x;offset.y=y;standardizeAll();}
    public void setTo(CardPile c){
        clear();
        setLocation(c.getLocation());
        setOffset(c.getOffset());
        setFaceup(c.getFaceup());
        setFacedown(c.getFacedown());
        setSloppy(c.getSloppy());
        setName(c.getName());
        setModulo(c.getModulo());
        while(!c.isEmpty())addCard(c.drawBottom());
    }
    
    public boolean contains(Point p){
        boolean r=false;
        if(p.x>=location.x && p.y>=location.y &&
                p.x<=location.x+dimension.width && p.y<=location.y+dimension.height)
            r=true;
        else if(cardAt(p)!=null)r=true;
        return r;
    }
    //returns a reference to the highest card containing p; null if no card contains p
    public GenericCard cardAt(Point p){
        GenericCard r=null,temp;
        Iterator i=iterator();
        while(i.hasNext())
        {
            temp= (GenericCard)i.next();
            if(temp.contains(p))r=temp;
        }
        return r;
    }
    //methods to output and manipulate decks
    
    public void paint(Graphics g){
        g.setColor(Color.blue);
        g.drawRoundRect(location.x+1,location.y+1,dimension.width-2,dimension.height-2,12,12);
        Iterator i=iterator();
        while(i.hasNext()){
            ( (GenericCard)i.next() ).paint(g);
        }
    }
    //toString()
    
    public CardPile cut(){
        CardPile r=similar();
        while(size()>r.size())
            r.addCard(drawBottom());
        return r;
    }
    //returns the result of shuffling this with other, similar to this.
    public CardPile shuffleWith(CardPile other){
        CardPile r=similar();
        while(!other.isEmpty() && !isEmpty()){
            if(Math.random()>.5)r.addCard(drawBottom());
            else r.addCard(other.drawBottom());
        }
        while(!other.isEmpty())
            r.addCard(other.drawBottom());
        while(!isEmpty())
            r.addCard(drawBottom());
        return r;
    }
    public void shuffle(){
        CardPile c=cut();
        CardPile r=shuffleWith(c);
        setTo(r);
    }
    //a card pile is not a mouse listener; CardPanel uses these functions to determine
    //what should happen when a particular pile is clicked,etc.  a generic cardpile
    //does nothing; extend this class to decks, hands, etc, with unique behavior
    public void mousePressed(MouseEvent e,CardPile CardPile){}
    public void mouseReleased(MouseEvent e,CardPile CardPile){}
    public void mouseClicked(MouseEvent e,CardPile targetPile){}
}
Java2html