from tkinter import *
from tkinter import messagebox
import random
from tkinter import PhotoImage


class Advanced:

    def __init__(self, master):

        #flīžu ikonu importēšana
        self.tile_clicked = PhotoImage(file="tile_clicked.gif")
        self.tile_mine = PhotoImage(file="tile_mine.gif")
        self.tile_flag = PhotoImage(file="tile_flag.gif")
        self.tile_wrong = PhotoImage(file="tile_wrong.gif")
        self.tile_plain = PhotoImage(file = "tile_plain.gif")


        #numuru ikonu importēšana
        self.tile_number = [] #saraksts no 1-8
        for x in range(0, 8):
            self.tile_number.append(PhotoImage(file="tile_" + str(x+1) + ".gif"))

       #rāmja izveide
        statusBar = Frame(master) #statusa bars
        statusBar.pack(side = BOTTOM)

        frame = Frame(master)
        frame.pack(side = TOP)

        #augšas teksts
        welcomeLabel = Label(frame, text = "Advancētais līmenis", fg = "blue")
        welcomeLabel.grid(row = 0, column = 0, columnspan = 30)

        self.totalMine = 99
        self.flags = 0 #salikto karogu skaits
        self.correct_flags = 0 #pareizi salikto karogu skaits
        self.clicked = 0 #atklātās flīzes, kas nav mīnas
        self.MineLabel = Label(statusBar, text = "Mīnu skaits: " + str(self.totalMine))
        self.MineLabel.pack(side = LEFT)
        self.flagLabel = Label(statusBar, text = "\t\tKarogi: " + str(self.flags))
        self.flagLabel.pack(side = RIGHT)

       #mīnu ievietošana
       #x = flīzes ID

        mines = 99
        mineStatus = []
        for x in range(0,380):
            if random.randrange(479) <= 98 and mines>0:
                mineStatus.append(True)
                mines = mines - 1
            else:
                mineStatus.append(False)
        for x in range(380,480): #pārējās mīnas novietotas apakšgalā gadījumā, ja ir palicis kāds atlikums
            if mines > 0:
                mineStatus.append(True)
                mines=mines-1
            else:
                mineStatus.append(False)


        #pogas
        self.buttons = dict({}) #savienota saraksta izveide
        self.mines = 0

        cordX = 0
        cordY = 1 #nulto rindu okupē augšējais teksts


        for TileID in range(0,480): # 30x16 flīzes ar pogām
            # 0 = pogu un to īpašību izveide
            # 1 = mīnas statusa pārbaude - true = mīna, false = nav mīna
            # 2 = stāvoklis (0 = neatvērts, 1 = atvērts, 2 = novietots karogs
            # 3 = pogu ID
            # 4 = (cordX, cordY) režģa koordinātas
            # 5 = tuvējās mīnas, 0 pēc noklusējuma

            if (TileID-30) % 30 == 0: #jaunas rindas izveide, izmērs būtu 9x9
                cordY = cordY + 1
                cordX = 0

            self.buttons[TileID] = [Button(frame, image = self.tile_plain), mineStatus[TileID], 0, TileID, [cordX, cordY], 0] #x un y virziens iet pa labi un kreisi no ziemeļrietumiem
            self.buttons[TileID][0].bind('<Button-1>', self.left_click_dummy(TileID)) #kreisais klikšķis
            self.buttons[TileID][0].bind('<Button-3>', self.right_click_dummy(TileID)) #labais klikšķis
            cordX += 1


        #pogu ievietošana ekrānā
        for TileID in self.buttons:
            self.buttons[TileID][0].grid(row=self.buttons[TileID][4][1], column=self.buttons[TileID][4][0])

        #mīnu pārbaude
        for a in range(0,480): #a ir ekvivalents pogas ID
            closeByMine = 0 #mainīgo inicializēšana
            dummylist = self.getAdjacentCells(a) #glabā tuvo indeksu sarakstu
            for b in dummylist:
                closeByMine += self.mineCheck(b) #pievieno atlikušās mīnas

            self.buttons[a][5] = closeByMine #saglabā vērtību pogā

    def left_click_dummy(self, x):
        return lambda Button: self.left_click(self.buttons[x])

    def right_click_dummy(self, x):
        return lambda Button: self.right_click(self.buttons[x])

    def mineCheck(self,TileID):
        if self.buttons[TileID][1] == True:
            return 1 #atgriež 1 ja pastāv mīna
        else:
            return 0 #nav mīna, tad atgriež 0

    def left_click(self,button_data): #kad noklikšķina ar kreiso pogu

        if button_data[1] == True:
            for a in self.buttons: #iet cauri katrai flīzei un atklāj nepārbaudītās mīnas un flīzes, kuras tika nepareizi karogotas
                if self.buttons[a][1] != True and self.buttons[a][2] == 2: #nav mīna, bet bija karogota
                    self.buttons[a][0].config(image = self.tile_wrong) #flīžu bildes maiņa
                elif self.buttons[a][1] == True and self.buttons[a][2] == 0: #nekarogota mīna
                    self.buttons[a][0].config(image = self.tile_mine) #parāda mīnas
            self.lostGame() #zaudē spēli

        elif button_data[5] != 0 and button_data[2] != 1:
            num = button_data[5] #glabā tuvo mīnu skaitu
            button_data[0].config(image = self.tile_number[num-1]) #secīgi parāda flīzes ikonu
            button_data[2] = 1 #flīzes status parmainās uz atvērtu
            self.clicked += 1
            button_data[0].unbind('<Button-1>')
            button_data[0].unbind('<Button-2>')
        else:
            quene = [button_data[3]]
            queneChecker = [button_data[3]] #duplikātu pārbaude, novērš bezgalīgu lūpošanos
            button_data[2] = 1
            button_data[0].config(image = self.tile_clicked)
            button_data[0].unbind('<Button-1>')
            button_data[0].unbind('<Button-2>')
            self.clicked+=1
            while len(quene) != 0:
                surroundList = self.getAdjacentCells(quene[0])
                for item in surroundList:
                    if self.buttons[item][5] == 0:
                        if item in queneChecker:
                            pass
                        else:
                            queneChecker.append(item)
                            quene.append(item)
                            self.buttons[item][0].config(image=self.tile_clicked) #parāda tukšos elementus
                            self.buttons[item][0].unbind('<Button-1>')
                            self.buttons[item][0].unbind('<Button-2>')
                    else:
                        num = self.buttons[item][5]
                        self.buttons[item][0].config(image=self.tile_number[num-1])  #secīgi parāda laiku
                        self.buttons[item][0].unbind('<Button-1>')
                        self.buttons[item][0].unbind('<Button-2>')
                        self.clicked += 1
                quene.pop(0)
            self.clicked += len(queneChecker)
        self.checkStatus()

    def right_click(self,button_data): #labās pogas sekcija
        if button_data[2] == 0: #ja flīze nav marķēta
            button_data[0].config(image=self.tile_flag)
            button_data[2] = 2
            button_data[0].unbind('<Button-1>') #padara klikšķus disfunkcionālus
            self.flags += 1
            self.update_flaglabel()
            if button_data[1] == 1:
                self.correct_flags += 1
                self.checkStatus()

        # ja ir karogots, noņem karogu
        elif button_data[2] == 2:
            button_data[0].config(image=self.tile_plain)
            button_data[2] = 0
            button_data[0].bind('<Button-1>', self.left_click_dummy(button_data[3]))
            if button_data[1] == 1:
                self.correct_flags -= 1
            self.flags -= 1

    def checkStatus(self):
        if self.correct_flags == 99:
            self.wonGame()

    def update_flaglabel(self):
        self.flagLabel.config(text = "Karogi: "+ str(self.flags))

    def lostGame(self):
        global root
        messagebox.showinfo("Game Over","Jūs atvērāt mīnu.")
        root.quit()

    def wonGame(self):
        messagebox.showinfo("You Win","Visas mīnas ir neutralizētas.")
        global root
        root.quit() #aizver logu

    def getAdjacentCells(self, TileID):
        adjacentIDList = []
        if TileID == 0:
            adjacentIDList = [1, 30, 31]
            return adjacentIDList
        elif TileID == 29:
            adjacentIDList = [28, 59, 58]
        elif TileID == 450:
            adjacentIDList = [451, 420, 421]
        elif TileID == 479:
            adjacentIDList = [478, 449, 448]
        elif TileID > 0 and TileID < 29: #augšējā rinda
            num1 = TileID - 1
            num2 = TileID + 1
            num3 = TileID + 29
            num4 = TileID + 30
            num5 = TileID + 31
            adjacentIDList=[num1,num2,num3,num4,num5]
        elif TileID%30 == 0: #kreisā kolumna
            num1 = TileID + 1
            num2 = TileID - 30
            num3 = TileID - 29
            num4 = TileID + 30
            num5 = TileID + 31
            adjacentIDList = [num1,num2,num3,num4,num5]
        elif (TileID+1)%30 == 0: #labā kolumna
            num1 = TileID - 1
            num2 = TileID - 30
            num3 = TileID - 31
            num4 = TileID + 30
            num5 = TileID + 29
            adjacentIDList = [num1,num2,num3,num4,num5]
        elif TileID > 450 and TileID < 479: #apakšējā rinda
            num1 = TileID - 1
            num2 = TileID + 1
            num3 = TileID - 31
            num4 = TileID - 30
            num5 = TileID - 29
            adjacentIDList = [num1, num2, num3, num4, num5]
        else:
            num1 = TileID - 1
            num2 = TileID + 1
            num3 = TileID - 31
            num4 = TileID - 30
            num5 = TileID - 29
            num6 = TileID + 29
            num7 = TileID + 30
            num8 = TileID + 31
            adjacentIDList = [num1, num2, num3, num4, num5, num6, num7, num8]
        return adjacentIDList
#beigu klase

def main():
    global root
    #izveido tk logrīku
    root = Tk()
    #programmas nosaukums
    root.title("Advanced Minesweeper")
    root.geometry("800x450")
    minesweeper = Advanced(root)
    #uzsākt event loop
    root.mainloop()

main()