#!/usr/bin/python
#coding=utf8

# Copyright © 2012 Tim Radvan
# 
# This file is part of Kurt.
# 
# Kurt is free software: you can redistribute it and/or modify it under the 
# terms of the GNU Lesser General Public License as published by the Free 
# Software Foundation, either version 3 of the License, or (at your option) any 
# later version.
# 
# Kurt is distributed in the hope that it will be useful, but WITHOUT ANY 
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
# details.
# 
# You should have received a copy of the GNU Lesser General Public License along 
# with Kurt. If not, see <http://www.gnu.org/licenses/>.

"""Graphical interface for kurtc.py"""

from Tkinter import *
from tkFont import Font
import tkFileDialog
import tkMessageBox

import subprocess
import sys
import os
import shutil

try:
    import kurt
except ImportError: # try and find kurt directory
    path_to_file = os.path.join(os.getcwd(), __file__)
    path_to_lib = os.path.split(os.path.split(path_to_file)[0])[0]
    sys.path.append(path_to_lib)

from kurt.files import *
from kurt.compiler import *
from kurt.decompiler import *



# Attempt to find My Documents / home folder
HOME_FOLDER = os.path.expanduser("~")
try:
    import win32com.client
except ImportError:
    win32com = None
if win32com:
    objShell = win32com.client.Dispatch("WScript.Shell")
    HOME_FOLDER = objShell.SpecialFolders("MyDocuments")



def open_file(path):
    """Opens Explorer/Finder with given path, depending on platform"""
    if sys.platform=='win32':
        os.startfile(path)
        #subprocess.Popen(['start', path], shell= True)
    
    elif sys.platform=='darwin':
        subprocess.Popen(['open', path])
    
    else:
        try:
            subprocess.Popen(['xdg-open', path])
        except OSError:
            pass
            # xdg-open *should* be supported by recent Gnome, KDE, Xfce


class App:
    def __init__(self, master):
        self.master = master
        content = Frame(master)
        content.grid(column=0, row=0)
        
        # File chooser
        self.file_path = Entry(content, width=80)
        self.file_path.grid(column=0, row=0, columnspan=2, sticky="NSEW", padx=4, pady=4)
        Button(content,
            text = "Choose .sb file",
            command = self.choose_file,
        ).grid(column=0, row=1, sticky="E", padx=8, pady=4)
        Button(content,
            text = "Choose directory",
            command = self.choose_folder,
        ).grid(column=1, row=1, sticky="W", padx=8, pady=4)
        
        # hr
        Frame(content, height=4, bd=2, relief="sunken").grid(column=0, row=2, columnspan=2, sticky="NSEW", pady=8)
        
        # Action buttons
        self.action_font = Font(size=16)
        Button(content,
            text = "Decompile",
            command = self.decompile,
            font = self.action_font,
        ).grid(column=0, row=3, sticky="E", padx=8, pady=4)
        Button(content,
            text = "Compile",
            command = self.compile,
            font = self.action_font,
        ).grid(column=1, row=3, sticky="WN", padx=8, pady=4)
         
        dl = Message(content, width=300, text="""scratch project -> folder structure

Export project contents to separate files. Creates a folder called "<project name> files", with a subfolder for each sprite.
        """)
        dl.grid(column=0, row=4, sticky="E", padx=8)
        cl = Message(content, width=300, text="""folder structure -> scratch project

Take a folder structure generated by decompile, and compiles all the images and scripts back into a .sb file.
        """)
        cl.grid(column=1, row=4, sticky="WN", padx=8)
        
        self.set_file_path(HOME_FOLDER)
        self.file_path.focus_set()
    
    def choose_file(self):
        filename = tkFileDialog.askopenfilename(
            title = "Choose Scratch project",
            initialfile = self.get_file(),
            defaultextension = 'sb',
            filetypes = ("{Scratch Project Files} {.sb}",)
        )
        if filename:
            self.set_file(filename)
            
    def choose_folder(self):
        print self.get_folder()
        path = tkFileDialog.askdirectory(
            initialdir = self.get_folder() or HOME_FOLDER,
            title = "Choose folder containing project files",
        )
        
        if path:
            self.set_folder(path)
    
    def get_folder(self):
        """Return "<project> files" folder"""
        path = self.file_path.get()
        if not path:
            return
        
        # Work out "<project> files" folder from .sb file
        # TODO
        
        return path
        
    def get_file(self):
        """Return selected .sb file"""
        path = self.file_path.get()
        if not path:
            return
        
        # Work out .sb file from "<project> files" folder
        # TODO
        
        return path
    
    def set_file(self, filename):
        """Set selection to .sb file"""
        self.set_file_path(filename)
    
    def set_folder(self, path):
        """Set selection to "<project> files" folder"""
        self.set_file_path(path)
    
    def set_file_path(self, path):
        """Update the file_path Entry widget"""
        self.file_path.delete(0, END)
        self.file_path.insert(0, path)
    
    def decompile(self):
        path = self.get_file()
        if not path:
            tkMessageBox.showerror("Invalid path", "Enter path to .sb file")
            return
        
        project = ScratchProjectFile(path, load=False)
        error = None
        
        try:
            decompile(project)
        except FolderExistsException, e:
            path = e.message
            response = tkMessageBox.askokcancel("Folder Exists", "WARNING: Overwrite folder '%s'?" % path)
            if response:
                shutil.rmtree(path)
                self.decompile()
            return
        
        except FileNotFoundException, e:
            error = "Missing file: %s" % unicode(e)
        except InvalidProject, e:
            error = "Invalid project: %s" % unicode(e)
        
        if error:
            tkMessageBox.showerror("Error", error)
        else:        
            (project_dir, name) = os.path.split(project.path)
            folder = os.path.join(project_dir, "%s files" % project.name)
        
            self.set_folder(folder)
            tkMessageBox.showinfo("Decompiled!", "Saved in folder %s" % folder)
            open_file(folder)
    
    def compile(self):
        path = self.get_file()
        if not path:
            tkMessageBox.showerror("Invalid path", 'Enter path to "<project> files" folder')
            return
        
        if path.endswith(".sb"):
            path = path[:-3]
        if path.endswith(" files"):
            path = path[:-6]
        
        error = None
        try:
            project = compile(path)
            project.save()
        
        except FileExistsException, e:
            path = e.message
            response = tkMessageBox.askokcancel("File exists", "WARNING: Overwrite file '%s'? THIS CANNOT BE UNDONE." % path)
            if response:
                os.remove(path)
                self.compile()
            return
        
        except InvalidFile, e:
            error = "Invalid file: %s" % e
        except FolderNotFoundException, e:
            error = "Missing folder: %s" % unicode(e)
        
        if error:
            tkMessageBox.showerror("Error", error)
        else:
            file = project.path
            self.set_file(file)
            tkMessageBox.showinfo("Compiled!", "Saved to %s" % file)
            open_file(file)
    
    def closed(self):
        pass # Save, perhaps?



root = Tk()
root.title("kurt compiler")
root.resizable(0, 0)

app = App(root)


def closed():
    app.closed()
    root.destroy()

root.protocol('WM_DELETE_WINDOW', closed)


root.mainloop()