/*
 * Same Game - desktop - third approach to the problem
 * 29-III-2024
 * code: Przemyslaw R. Pietraszczyk
 * licence: GPL v3
 * IDE: Geany
 */
package pietraszczyk.samegame;

import java.awt.*;  // Toolkit
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
//import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.Box;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Timer;
import java.util.*; //Timer
import java.lang.*;

public class SameGame extends JPanel
        implements ActionListener {
    static JMenuBar menuBar;
    JMenu menu, info;
    JMenuItem menuItem, menuExit, menuInfo, l1, l2, l3, l4;
    static final int NW = 6, NH = 9; //NW=9, NH=6; // weight - height
    static JFrame frame;
    static Timer timer;
    static Field [][]field = new Field[NH][NW];
    static int []tmpi = new int[2];
    static int []tmpj = new int[2];
    static boolean showColor=false;
    static boolean press=false;
    static boolean lockClick=false;
    static int nmove=0;
    static int nFields; // ilosc pozostalych pol do odkrycia
    static JLabel label = new JLabel("Witaj w Same Game - poziom 1");
    static int score;
    static int level; 

    public SameGame() {
        super(new GridBagLayout());
        GridBagLayout gridbag = (GridBagLayout)getLayout();
        GridBagConstraints c = new GridBagConstraints();
        int i;
        int j;
       // int x, y;
        int k=0;
		level = 1;
		
        menuBar = new JMenuBar();
        menu = new JMenu("Plik");
        menuBar.add(menu);
        // przenosi INFO na prawa strone
        menuBar.add(Box.createHorizontalGlue());
        info = new JMenu("Info");
        info.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        menuBar.add(info);
        menuItem = new JMenuItem("Nowa Gra", null);
        menuItem.setActionCommand("NewGame");
        menuItem.addActionListener(this);
        menuItem.setToolTipText("Rozpoczyna nowa gre");
        menu.add(menuItem);
        
        JMenu med = new JMenu("Poziom");
		l1 = new JMenuItem("Dwa kolory");
		l1.setActionCommand("L1");
		l1.addActionListener(this);
		med.add(l1);
        l2 = new JMenuItem("Trzy kolory");
        l2.setActionCommand("L2");
        l2.addActionListener(this);
		med.add(l2);
		l3 = new JMenuItem("Cztery kolory");
        l3.setActionCommand("L3");
        l3.addActionListener(this);
		med.add(l3);
		l4 = new JMenuItem("Piec kolorow");
        l4.setActionCommand("L4");
        l4.addActionListener(this);
		med.add(l4);
		
		menu.add(med);
        
        menu.addSeparator();
        menuItem = new JMenuItem("Zakoncz", null);
        menuItem.setActionCommand("Exit");
        menuItem.addActionListener(this);
        menuItem.setToolTipText("Wyjscie z programu");
        menu.add(menuItem);
        menuItem = new JMenuItem("O Programie", null);
        menuItem.setActionCommand("About");
        menuItem.addActionListener(this);
        menuItem.setToolTipText("Informacje o programie");
        info.add(menuItem);

        for (i=0; i<NH;i++) {
            for (j = 0; j < NW; j++, k++) {
                field[i][j] = new Field(i, j);
                field[i][j].button.setActionCommand("colorButton"+k);
                field[i][j].button.addActionListener(this);
            }
        }
        init();

        for (i=0;i<NH;i++) {
            for (j=0;j<NW;j++,k++) {
                field[i][j].button.setPreferredSize(new Dimension(60, 60));
                c.fill = GridBagConstraints.HORIZONTAL;
                c.gridx = j;
                c.gridy = i;
                gridbag.setConstraints(field[i][j].button, c);
                field[i][j].button.setBackground(field[i][j].getColor());
                add(field[i][j].button);
                field[i][j].button.setFont(new Font("Arial", Font.PLAIN, 40));
            }
        }
        label.setPreferredSize(new Dimension(100, 20));
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridwidth = 6; //9;
        c.gridx = 0;
        c.gridy = 9; //6;
        gridbag.setConstraints(label, c);
        add(label);
    }
    private void init(){
        int i,j,x,y,k=0;
        Random rand = new Random();
        int cc=-1;
        score = 0;
        final int []r={64,96,128,0,178,196,255};
        final int []g={64,0,0,32,16,128,255,128};
        final int []b={0,45,128,128,64,32,0,255};

        for (i=0;i<NH;i++) {
            for (j = 0; j < NW; j++, k++) {

				cc = rand.nextInt(level+1); // max 7

				field[i][j].setColorName(new Color(r[cc], g[cc], b[cc])); // 9
                field[i][j].setGroupIndex(k);
          }
        }
        nFields=k;
        
        for (k=0, i=0;i<NH;i++) {
            for (j = 0; j < NW; j++, k++) {
				field[i][j].like(field[i][j].getColor(), field, i, j, i, j);
                
                field[i][j].clearVisit();

                field[i][j].removeDuplicates();
                field[i][j].sort();  // also reverse

                field[i][j].removeDuplicatesIndex();
                field[i][j].sortReverseIndex();
            }
		}
	}

    public void actionPerformed(ActionEvent e){
        int k=0;
        int _x[] = {0,1,2,3,4,5};
        int _y[] = {0,1,2,3,4,5,6,7,8};
        ///if (!lockClick) {
            for (int i = 0; i < NH; i++) {
                for (int j = 0; j < NW; j++, k++) {
                    if (e.getActionCommand().equals("colorButton"+k)) {
						if (field[i][j].groupList.size() > 1) {
				
							int c = 0;
							for (int l : field[i][j].listIndex) {
								int y = l / 6;
								int x = l % 6;
								field[y][x].blank();
							}
							// Przesuniecie w lerwo
							for (int l :field[i][j].listIndex) {
								int y = l / 6;
								int x = l % 6;
								field[y][x].toLeft(field, y, x);
							}

							int s = 0;
							s = field[i][j].listIndex.size();
							s = (s * (s -1)) * level * level;
							score += s;
							// Usuwanie elementow
							for  (int y : _y) {
								for (int x : _x) {
									field[y][x].groupList.clear();
									field[y][x].listIndex.clear();
								}
							}

							
							for (int y=0;y<NH;y++) {
								for (int x = 0; x < NW; x++) {
									field[y][x].like(field[y][x].getColor(), field, y, x, y, x);
				
									field[y][x].clearVisit();

									field[y][x].removeDuplicates();
									field[y][x].sort();  // also reverse

									field[y][x].removeDuplicatesIndex();
									field[y][x].sortReverseIndex();
									field[y][x].button.setBackground(field[y][x].getColor());

								}
							}

							
							/* Do gory */
							for (int y=0;y<NH;y++) 
								for (int x = 0; x < NW; x++) 
									field[y][x].toUp(field, y, x);
						
									
							for  (int y : _y) {
								for (int x : _x) {
									field[y][x].groupList.clear();
									field[y][x].listIndex.clear();
								}
							}

							for (int y=0;y<NH;y++) {
								for (int x = 0; x < NW; x++, k++) {
									field[y][x].like(field[y][x].getColor(), field, y, x, y, x);
				
									field[y][x].clearVisit();

									field[y][x].removeDuplicates();
									field[y][x].sort();  // also reverse

									field[y][x].removeDuplicatesIndex();
									field[y][x].sortReverseIndex();
									field[y][x].button.setBackground(field[y][x].getColor());

								}
							}
					
							boolean game_in_progress = false;
							int path_to_win = 0;
							for (int y=0;y<NH;y++) {
								for (int x = 0; x < NW; x++, k++) {
									if (field[y][x].groupList.size() >= 2) game_in_progress = true;
									if (field[y][x].groupList.size() == 0) ++path_to_win;
								}
							}
							if (!game_in_progress){
								String l = new String("Nieskonczona gra, wynik: ");
								l += String.valueOf(score * level);
								label.setText(l);
							}
							if (path_to_win == 54) {
								String l = new String("Wygrana ! wynik: ");
								l += String.valueOf(2 * (score * level));
								label.setText(l);
							}
							return;
                    }
                }
            }
        }
        if(e.getActionCommand().equals("NewGame")) {
            int i,j;
            for (i=0; i<NH;i++) {
				for (j = 0; j < NW; j++, k++) {
					field[i][j].reset();
				}
			}
            
			for  (int y : _y) {
				for (int x : _x) {
					field[y][x].groupList.clear();
					field[y][x].listIndex.clear();
				}
			}
            init();
            for (int y=0;y<NH;y++) 
				for (int x = 0; x < NW; x++) 
					field[y][x].button.setBackground(field[y][x].getColor());
            nmove=0;
            score = 0;
            String g = new String ("Nowa gra - poziom: ");
            g += String.valueOf(level);
            label.setText(g);
        }
        else if(e.getActionCommand().equals("Exit")) {
            System.exit(0);
        }
        else if(e.getActionCommand().equals("About")) {

            JOptionPane.showMessageDialog(frame,
                    "Moja implementacja gry Same Game\nPrzemyslaw R. Pietraszczyk\nStworzono w oparciu o OpenJDK/ANT\nLicencja: GPL v3\nWiosna 2024",
                    "Same Game 0.240417-2",
                    JOptionPane.PLAIN_MESSAGE);

        }
        else if(e.getActionCommand().equals("L1")) {
            level = 1;
        }
        else if(e.getActionCommand().equals("L2")) {
            level = 2;
        }
        else if(e.getActionCommand().equals("L3")) {
            level = 3;
        }
        else if(e.getActionCommand().equals("L4")) {
            level = 4;
        }
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("Same Game");
        timer = new Timer();
        int frameWidth = 300;
        int frameHeight = 400;
        // ustawia okno po prawe na dole
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        //frame.setBounds((int) screenSize.getWidth()/2 - frameWidth/2,
        //        (int) screenSize.getHeight() - frameHeight, frameWidth, frameHeight);
        frame.setBounds((int) screenSize.getWidth() - frameWidth,
                (int) screenSize.getHeight()/2 - frameHeight/2, frameWidth, frameHeight);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        JComponent newContentPane = new SameGame();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setJMenuBar(menuBar);
        frame.setContentPane(newContentPane);


        //Display the window.
        frame.pack();
        frame.setVisible(true);

        //timer.schedule(new ClearField(), 2000, 3000);

    }
    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
/*
    static class ClearField extends TimerTask {
        public void run() {
            if (nFields!=0) {
                if (showColor) {
                    System.out.println("show color");
                    press = false;
                    field[tmpi[0]][tmpj[0]].button.setBackground(field[tmpi[0]][tmpj[0]].getColor());
                    field[tmpi[1]][tmpj[1]].button.setBackground(field[tmpi[1]][tmpj[1]].getColor());
                    showColor = false;
                    lockClick = false;
                    //nmove++;
                    //System.out.println("Color 0: "+field[tmpi[0]][tmpj[0]].getColorHide().toString()+" Color 1:"+field[tmpi[1]][tmpj[1]].getColorHide().toString());
                    // zapobiega zanikaniu pojedynczego kafla
                    if (tmpi[0] != tmpi[1] || tmpj[0] != tmpj[1]) {
                        //label.setText(" Odnaleziono !");
                        // jesli te same kolory
                        if (field[tmpi[0]][tmpj[0]].getColorHide().toString().equals(field[tmpi[1]][tmpj[1]].getColorHide().toString())) {

                            //field[tmpi[0]][tmpj[0]].setFound(true);
                            //field[tmpi[1]][tmpj[1]].setFound(true);
                            field[tmpi[0]][tmpj[0]].button.setText(" ");
                            field[tmpi[1]][tmpj[1]].button.setText(" ");
                            //Toolkit.getDefaultToolkit().beep();

                            label.setText("");
                            nFields -= 2;
                            System.out.println("nFields: " + nFields);
                        } else label.setText("");
                    }


                }
            }
            else {
                JOptionPane.showMessageDialog(frame,
                        "Wykonales "+nmove+" posuniec",
                        "Podsumowanie",
                        JOptionPane.PLAIN_MESSAGE);
                nFields=1; // aby nie wyswietlalo drugi raz

            }


        }

    }
    */
}
//}
