import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.util.*;

/**
 * Das Fenster, in dem das Freecell-Spiel dargestellt wird.
 * Hier sollte nichts verändert werden.
 *
 * @version 10.10.2020
 * @author Rainer Helfrich
 */
public class FreecellFrame extends JFrame {

    public FreecellFrame(FreecellGame g) { 
        // Frame-Initialisierung
        super();
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        int frameWidth = 8*Karte.CARD_WIDTH+150; 
        int frameHeight = 640+2*Karte.CARD_HEIGHT;
        setSize(frameWidth, frameHeight);
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (d.width - getSize().width) / 2;
        int y = (d.height - getSize().height) / 2;
        setLocation(x, y);
        setTitle("Freecell");
        setResizable(false);
        Container cp = getContentPane();
        cp.setLayout(null);
        // Anfang Komponenten

        JPanel jPanel1 = new FreecellPanel(g);
        jPanel1.setBounds(0, 0, frameWidth, frameHeight);
        jPanel1.setOpaque(true);
        cp.add(jPanel1);
        // Ende Komponenten

        setVisible(true);
    } // end of public FreecellFrame

   

    // Ende Methoden
    private class FreecellPanel extends JPanel implements MouseListener{

        FreecellGame dasSpiel;
        
        public FreecellPanel(FreecellGame g)
        {
            super( null, true);
            dasSpiel = g;
            this.addMouseListener(this);
            markiert = null;
            sourceArea = -1;
            sourceIndex = -1;
        }

        public void paint(Graphics g) {
            g.setColor(new Color(0, 100, 0));
            g.fillRect(0,0,getWidth(),getHeight());
            for (int i = 0; i < 4; i++) {
                Karte k = dasSpiel.getKarte(FreecellGame.ZELLEN, i);
                if (k == null) 
                {
                    g.setColor(new Color(0, 80, 0));
                    g.fillRoundRect(10+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
                    g.setColor(Color.BLACK);
                    g.drawRoundRect(10+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
                } // end of if
                else
                {
                    k.zeichne(g, 10+(Karte.CARD_WIDTH+10)*i, 20);
                }
            } // end of for
            for (int i = 0; i < 4; i++) 
            {
                Karte k = dasSpiel.getKarte(FreecellGame.ABLAGESTAPEL, i);
                if (k == null) 
                {
                    g.setColor(new Color(0, 80, 0));
                    g.fillRoundRect(4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
                    g.setColor(Color.BLACK);
                    g.drawRoundRect(4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20, Karte.CARD_WIDTH, Karte.CARD_HEIGHT, 8, 8);
                } // end of if
                else
                {
                    k.zeichne(g, 4*Karte.CARD_WIDTH+90+(Karte.CARD_WIDTH+10)*i, 20);
                }
            } // end of for
            for (int i = 0; i < 8; i++) {
                int hoehe = dasSpiel.getStapelHoehe(i);
                for (int j = 0; j < hoehe; j++)
                {
                    Karte k = dasSpiel.getKarteInStapel(i, hoehe-1-j);
                    k.zeichne(g, 35+(Karte.CARD_WIDTH+10)*i, Karte.CARD_HEIGHT+55+j*30);
                }
            } // end of for
        }

        Karte markiert;
        int sourceArea;
        int sourceIndex;

        public void mouseExited(MouseEvent e) {
        }

        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
            {
                int area = getArea(e.getPoint());
                if (area == FreecellGame.ABLAGESTAPEL)
                {
                    return;
                }
                int index = getIndex(e.getPoint(), area);
                if (index == FreecellGame.KEINER)
                {
                    return;
                }
                
                if (dasSpiel.schnellerZug(area, index))
                {
                    if (markiert != null)
                    {
                        markiert.setMarkiert(false);
                        markiert = null;
                    }
                    finishMove();
                }
            }
        }

        public void mouseEntered(MouseEvent e){
        }

        public void mousePressed(MouseEvent e){
        }


        private int getArea(Point p)
        {
            if (p.getY() >= 20 && p.getY() <= Karte.CARD_HEIGHT+20) 
            {
                if (p.getX() >= 10 && p.getX() <= Karte.CARD_WIDTH*4+40) 
                {
                    return FreecellGame.ZELLEN;
                } // end of if
                if (p.getX() >= Karte.CARD_WIDTH*4+90 && p.getY() <= Karte.CARD_WIDTH*8+120) 
                {
                    return FreecellGame.ABLAGESTAPEL;
                } // end of if
            } // end of if
            if (p.getY() >= Karte.CARD_HEIGHT+55 && p.getX() >= 35 && p.getX() <= Karte.CARD_WIDTH*8+105) 
            {
                return FreecellGame.KASKADEN;
            }
            return FreecellGame.KEINER;
        }

        private int getIndex(Point p, int area)
        {
            if (area < 0)
            {
                return FreecellGame.KEINER;
            }
            int x = (int)p.getX();
            if (area == FreecellGame.ZELLEN) 
            {
                x -= 10;
            } // end of if
            if (area == FreecellGame.ABLAGESTAPEL) 
            {
                x -= 4*Karte.CARD_WIDTH+90;
            } // end of if
            if (area == FreecellGame.KASKADEN) 
            {
                x -= 35;
            } // end of if
            if (x % (Karte.CARD_WIDTH+10) < Karte.CARD_WIDTH) 
            {
                return x / (Karte.CARD_WIDTH+10);
            } // end of if
            return FreecellGame.KEINER;
        }

        public void mouseReleased(MouseEvent e)
        {
            int area = getArea(e.getPoint());
            int index = getIndex(e.getPoint(), area);
            if (area == FreecellGame.KEINER || index == FreecellGame.KEINER) {
                if (markiert != null)
                    markiert.setMarkiert(false);
                markiert = null;
            } // end of if
            else if (markiert == null) 
            {
                if (area == FreecellGame.ZELLEN || area == FreecellGame.KASKADEN)
                {
                    markiert = dasSpiel.getKarte(area, index);
                }
                if (markiert != null) 
                {
                    markiert.setMarkiert(true);
                    sourceArea = area;
                    sourceIndex = index;
                } // end of if
            }
            else
            {
                if (sourceArea == area && sourceIndex == index || 
                    dasSpiel.verschiebe(sourceArea, sourceIndex, area, index))
                {
                    markiert.setMarkiert(false);
                    markiert = null;
                }
            }
            finishMove();
        }
        
        private void finishMove()
        {
            if (markiert != null)
            {
                repaint();
                return;
            }
            while(true)
            {
                paintImmediately(0, 0, getWidth(), getHeight());
                if (dasSpiel.automatischerZug())
                {
                    try
                    {
                        Thread.sleep(300);
                    }
                    catch(Exception x)
                    {
                    }  
                }
                else
                {
                    break;
                }
            }
            if (dasSpiel.istGewonnen())
            {
                JOptionPane.showMessageDialog(null,"Gewonnen!","Spiel beendet", JOptionPane.INFORMATION_MESSAGE);
            }
        }
        
    }
} // end of class FreecellFrame
