"""
 handles settings file management and retrieval of settings
 
 settings retrieval is (mostly) done in a non-pythonic way,
 hard to break those java habits!
 
 They should all be refactored to use @property
"""

import platform
import os
import json
import copy
import tkinter as tk
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
import logging
import yaml

class Settings(FileSystemEventHandler):
    defaultProfile = [ {
                        "profile": "Default",
                        "logLevel": 20,
                        "fleetServer": "peld-fleet.com",
                        "profileSettings": 
                            { "windowX": 0, "windowY": 0,
                             "windowHeight": 225, "windowWidth": 350,
                             "compactTransparency": 65,
                             "seconds": 10, "interval": 100,
                             "graphDisabled": 0,
                             "dpsIn": [{"color": "#FF0000", "transitionValue": 0, "labelOnly": 0, "showPeak": 0}],
                             "dpsOut": [{"color": "#00FFFF", "transitionValue": 0, "labelOnly": 0, "showPeak": 0}],
                             "logiOut": [], "logiIn": [],
                             "capTransfered": [], "capRecieved": [],
                             "capDamageOut": [], "capDamageIn": [],
                             "mining": [],
                             "labels": {
                                 "dpsIn": {"row": 0, "column": 7, "inThousands": 0, "decimalPlaces": 1},
                                 "dpsOut": {"row": 0, "column": 0, "inThousands": 0, "decimalPlaces": 1},
                                 "logiOut": {"row": 1, "column": 0, "inThousands": 0, "decimalPlaces": 1},
                                 "logiIn": {"row": 1, "column": 7, "inThousands": 0, "decimalPlaces": 1},
                                 "capTransfered": {"row": 1, "column": 1, "inThousands": 0, "decimalPlaces": 1},
                                 "capRecieved": {"row": 1, "column": 6, "inThousands": 0, "decimalPlaces": 1},
                                 "capDamageOut": {"row": 0, "column": 1, "inThousands": 0, "decimalPlaces": 1},
                                 "capDamageIn": {"row": 0, "column": 6, "inThousands": 0, "decimalPlaces": 1},
                                 "mining": {"row": 2, "column": 7, "inThousands": 0, "decimalPlaces": 1}
                                 },
                             "labelColumns": [4,4],
                             "detailsOrder": [
                                 "dpsOut",
                                 "dpsIn",
                                 "logiOut",
                                 "logiIn",
                                 "capTransfered",
                                 "capRecieved",
                                 "capDamageOut",
                                 "capDamageIn"
                                 ],
                             "detailsWindow": {
                                 "show": 1,
                                 "width": 200,
                                 "height": 250,
                                 "x": 0,
                                 "y": 0
                                 },
                             "fleetWindow": {
                                 "show": 1,
                                 "width": 600,
                                 "height": 400,
                                 "x": 200,
                                 "y": 200,
                                 "showAggregate": 1,
                                 "showDpsOut": 1,
                                 "showDpsIn": 1,
                                 "showLogiOut": 1
                                 }
                             }
                        } ]
    def __init__(self):
        self.observer = Observer()
        
        if (platform.system() == "Windows"):
            self.path = os.environ['APPDATA'] + "\\PELD"
            filename = "PELD.json"
        else:
            self.path = os.environ['HOME']
            filename = ".peld"
            
        if not os.path.exists(self.path):
            os.mkdir(self.path)
            
        self.fullPath = os.path.join(self.path, filename)
            
        if not os.path.exists(self.fullPath):
            settingsFile = open(self.fullPath, 'w')
            json.dump(self.defaultProfile, settingsFile, indent=4)
            settingsFile.close()
            
        self.observer.schedule(self, self.path, recursive=False)
        self.observer.start()
            
        settingsFile = open(self.fullPath, 'r')
        self.allSettings = json.load(settingsFile)
        settingsFile.close()
        self.currentProfile = self.allSettings[0]["profileSettings"]

        self.lowCPUMode = False
        
    def on_moved(self, event):
        if not event.dest_path.endswith('.json'):
            return
        try:
            currentProfileName = self.allSettings[self.selectedIndex.get()]["profile"]
        except AttributeError:
            return
        settingsFile = open(self.fullPath, 'r')
        self.allSettings = json.load(settingsFile)
        settingsFile.close()
        self.mainWindow.profileMenu.delete(0,tk.END) 
        self.initializeMenu(self.mainWindow)
        
        i = 0
        for profile in self.allSettings:
            if (profile["profile"] == currentProfileName):
                self.currentProfile = profile["profileSettings"]
                self.selectedIndex.set(i)
                self.mainWindow.event_generate('<<ChangeSettings>>')
                return
            i += 1
        self.currentProfile = self.allSettings[0]["profileSettings"]
        self.selectedIndex.set(0)
        self.mainWindow.event_generate('<<ChangeSettings>>')
        
    def initializeMenu(self, mainWindow):
        self.mainWindow = mainWindow
        self.selectedIndex = tk.IntVar()
        i = 0
        for profile in self.allSettings:
            self.mainWindow.profileMenu.add_radiobutton(label=profile["profile"], variable=self.selectedIndex, 
                                 value=i, command=self.switchProfile)
            i += 1
        self.selectedIndex.set(0)
        
        self.mainWindow.profileMenu.add_separator()
        self.mainWindow.profileMenu.add_command(label="Add New Profile", command=lambda: self.addProfileWindow(add=True))
        self.mainWindow.profileMenu.add_command(label="Duplicate Current Profile", command=lambda: self.addProfileWindow(duplicate=True))
        self.mainWindow.profileMenu.add_command(label="Rename Current Profile", command=lambda: self.addProfileWindow(rename=True))
        self.mainWindow.profileMenu.add_command(label="Delete Current Profile", command=self.deleteProfileWindow)
        
    def addProfileWindow(self, add=False, duplicate=False, rename=False):
        if rename and (self.allSettings[self.selectedIndex.get()]["profile"] == "Default"):
            tk.messagebox.showerror("Error", "You can't rename the Default profile.")
            return
        
        self.newProfileWindow = tk.Toplevel()
        self.newProfileWindow.wm_attributes("-topmost", True)
        
        if add:
            self.newProfileWindow.wm_title("New Profile")
        elif duplicate:
            self.newProfileWindow.wm_title("Duplicate Profile")
        elif rename:
            self.newProfileWindow.wm_title("Rename Profile")
            
        try:
            self.newProfileWindow.iconbitmap(sys._MEIPASS + '\\app.ico')
        except Exception:
            try:
                self.newProfileWindow.iconbitmap("app.ico")
            except Exception:
                pass
        self.newProfileWindow.geometry("320x80")
        self.newProfileWindow.update_idletasks()
        
        tk.Frame(self.newProfileWindow, height="10", width="1").grid(row="0", column="0")
        
        profileLabel = tk.Label(self.newProfileWindow, text="    New Profile Name:")
        profileLabel.grid(row="1", column="0")
        self.profileString = tk.StringVar()
        if duplicate:
            self.profileString.set(self.allSettings[self.selectedIndex.get()]["profile"])
        if rename:
            self.profileString.set(self.allSettings[self.selectedIndex.get()]["profile"])
        profileInput = tk.Entry(self.newProfileWindow, textvariable=self.profileString, width=30)
        profileInput.grid(row="1", column="1")
        profileInput.focus_set()
        profileInput.icursor(tk.END)
        
        tk.Frame(self.newProfileWindow, height="10", width="1").grid(row="2", column="0")
        
        buttonFrame = tk.Frame(self.newProfileWindow)
        buttonFrame.grid(row="100", column="0", columnspan="5")
        tk.Frame(buttonFrame, height="1", width="30").grid(row="0", column="0")
        if add:
            okButton = tk.Button(buttonFrame, text="  Add  ", command=lambda: self.addProfile(add=True))
            profileInput.bind("<Return>", lambda e: self.addProfile(add=True))
        elif duplicate:
            okButton = tk.Button(buttonFrame, text="  Add  ", command=lambda: self.addProfile(duplicate=True))
            profileInput.bind("<Return>", lambda e: self.addProfile(duplicate=True))
        elif rename:
            okButton = tk.Button(buttonFrame, text="  Rename  ", command=lambda: self.addProfile(rename=True))
            profileInput.bind("<Return>", lambda e: self.addProfile(rename=True))
        okButton.grid(row="0", column="1")
        tk.Frame(buttonFrame, height="1", width="30").grid(row="0", column="2")
        cancelButton = tk.Button(buttonFrame, text="  Cancel  ", command=self.newProfileWindow.destroy)
        cancelButton.grid(row="0", column="3")
        
    def addProfile(self, add=False, duplicate=False, rename=False):
        if (self.profileString.get() == "Default"):
            tk.messagebox.showerror("Error", "There can only be one profile named 'Default'")
            return
        for profile in self.allSettings:
            if self.profileString.get() == profile["profile"]:
                tk.messagebox.showerror("Error", "There is already a profile named '" + self.profileString.get() + "'")
                return
        if add:
            newProfile = copy.deepcopy(self.defaultProfile[0])
            newProfile["profile"] = self.profileString.get()
            self.allSettings.insert(0, newProfile)
        elif duplicate:
            newProfile = copy.deepcopy(self.allSettings[self.selectedIndex.get()])
            newProfile["profile"] = self.profileString.get()
            self.allSettings.insert(0, newProfile)
        elif rename:
            self.allSettings[self.selectedIndex.get()]["profile"] = self.profileString.get()
            self.allSettings.insert(0, self.allSettings.pop(self.selectedIndex.get()))
        self.mainWindow.profileMenu.delete(0,tk.END) 
        self.initializeMenu(self.mainWindow)
        self.switchProfile()
        self.newProfileWindow.destroy()
    
    def deleteProfileWindow(self):
        if (self.allSettings[self.selectedIndex.get()]["profile"] == "Default"):
            tk.messagebox.showerror("Error", "You can't delete the Default profile.")
            return
        okCancel = tk.messagebox.askokcancel("Continue?", "Are you sure you want to delete the current profile?")
        if not okCancel:
            return
        self.allSettings.pop(self.selectedIndex.get())
        self.mainWindow.profileMenu.delete(0,tk.END) 
        self.initializeMenu(self.mainWindow)
        self.switchProfile()
        self.currentProfile = self.allSettings[0]["profileSettings"]
    
    def getCapDamageInSettings(self):
        if self.lowCPUMode:
            return []
        return copy.deepcopy(self.currentProfile["capDamageIn"])
    
    def getCapDamageOutSettings(self):
        if self.lowCPUMode:
            return []
        return copy.deepcopy(self.currentProfile["capDamageOut"])
    
    def getCapRecievedSettings(self):
        if self.lowCPUMode:
            return []
        return copy.deepcopy(self.currentProfile["capRecieved"])
    
    def getCapTransferedSettings(self):
        if self.lowCPUMode:
            return []
        return copy.deepcopy(self.currentProfile["capTransfered"])
    
    def getDpsInSettings(self):
        if self.lowCPUMode:
            return []
        return copy.deepcopy(self.currentProfile["dpsIn"])
    
    def getDpsOutSettings(self):
        if self.lowCPUMode:
            return []
        return copy.deepcopy(self.currentProfile["dpsOut"])
    
    def getLogiInSettings(self):
        if self.lowCPUMode:
            return []
        return copy.deepcopy(self.currentProfile["logiIn"])
    
    def getLogiOutSettings(self):
        if self.lowCPUMode:
            return []
        return copy.deepcopy(self.currentProfile["logiOut"])
    
    def getMiningSettings(self):
        if self.lowCPUMode:
            return []
        try:
            return copy.deepcopy(self.currentProfile["mining"])
        except KeyError:
            self.setSettings(mining=copy.deepcopy(self.defaultProfile[0]["profileSettings"]["mining"]))
            return copy.deepcopy(self.currentProfile["mining"])
        
    def getMiningM3Setting(self):
        if self.lowCPUMode:
            return []
        try:
            return self.currentProfile["mining"][0]["showM3"]
        except KeyError:
            return False
    
    def getInterval(self):
        if self.lowCPUMode:
            return 100
        return self.currentProfile["interval"]
    
    def getSeconds(self):
        if self.lowCPUMode:
            return 2
        return self.currentProfile["seconds"]
    
    def getWindowHeight(self):
        return self.currentProfile["windowHeight"]
    
    def getWindowWidth(self):
        return self.currentProfile["windowWidth"]
    
    def getWindowX(self):
        return self.currentProfile["windowX"]
    
    def getWindowY(self):
        return self.currentProfile["windowY"]
    
    def getCompactTransparency(self):
        try:
            return self.currentProfile["compactTransparency"]
        except KeyError:
            self.setSettings(compactTransparency=65)
            return self.currentProfile["compactTransparency"]
        
    def getGraphDisabled(self):
        if self.lowCPUMode:
            return True
        try:
            return self.currentProfile["graphDisabled"]
        except KeyError:
            self.setSettings(graphDisabled=0)
            return self.currentProfile["graphDisabled"]
        
    def getLabels(self):
        try:
            labelsCopy = copy.deepcopy(self.currentProfile["labels"])
            if "mining" not in labelsCopy:
                placementArray = [[x,y] for x in range(8) for y in range(8)]
                for entry in labelsCopy:
                    for place in placementArray:
                        if place[0] == labelsCopy[entry]["row"] and place[1] == labelsCopy[entry]["column"]:
                            placementArray.remove(place)
                labelsCopy["mining"] = {"row": placementArray[0][0], "column": placementArray[0][1], "inThousands": 0, "decimalPlaces": 1}
            return labelsCopy
        except KeyError:
            self.setSettings(labels=copy.deepcopy(self.defaultProfile[0]["profileSettings"]["labels"]))
            return copy.deepcopy(self.currentProfile["labels"])
    
    def getLabelColumns(self):
        try:
            return copy.deepcopy(self.currentProfile["labelColumns"])
        except KeyError:
            self.setSettings(labelColumns=[4,4])
            return copy.deepcopy(self.currentProfile["labelColumns"])
        
    @property
    def detailsWindow(self):
        return self.currentProfile.get("detailsWindow") or self.defaultProfile[0]["profileSettings"]["detailsWindow"]
    
    @property
    def detailsWindowShow(self):
        if self.lowCPUMode:
            return False
        if 'detailsWindow' in self.currentProfile and 'show' in self.currentProfile["detailsWindow"]:
            return self.currentProfile["detailsWindow"]["show"]
        else:
            return self.defaultProfile[0]["profileSettings"]["detailsWindow"]["show"]
        
    @detailsWindowShow.setter
    def detailsWindowShow(self, value):
        if 'detailsWindow' in self.currentProfile:
            self.currentProfile["detailsWindow"]["show"] = value
        else:
            self.currentProfile["detailsWindow"] = {}
            self.currentProfile["detailsWindow"]["show"] = value
        
    @property
    def detailsWindowHeight(self):
        if 'detailsWindow' in self.currentProfile and 'height' in self.currentProfile["detailsWindow"]:
            return self.currentProfile["detailsWindow"]["height"]
        else:
            return self.defaultProfile[0]["profileSettings"]["detailsWindow"]["height"]
    
    @detailsWindowHeight.setter
    def detailsWindowHeight(self, value):
        if 'detailsWindow' in self.currentProfile:
            self.currentProfile["detailsWindow"]["height"] = value
        else:
            self.currentProfile["detailsWindow"] = {}
            self.currentProfile["detailsWindow"]["height"] = value
        
    @property
    def detailsWindowWidth(self):
        if 'detailsWindow' in self.currentProfile and 'width' in self.currentProfile["detailsWindow"]:
            return self.currentProfile["detailsWindow"]["width"]
        else:
            return self.defaultProfile[0]["profileSettings"]["detailsWindow"]["width"]
    
    @detailsWindowWidth.setter
    def detailsWindowWidth(self, value):
        if 'detailsWindow' in self.currentProfile:
            self.currentProfile["detailsWindow"]["width"] = value
        else:
            self.currentProfile["detailsWindow"] = {}
            self.currentProfile["detailsWindow"]["width"] = value
    
    @property
    def detailsWindowX(self):
        if 'detailsWindow' in self.currentProfile and 'x' in self.currentProfile["detailsWindow"]:
            return self.currentProfile["detailsWindow"]["x"]
        else:
            return self.defaultProfile[0]["profileSettings"]["detailsWindow"]["x"]
    
    @detailsWindowX.setter
    def detailsWindowX(self, value):
        if 'detailsWindow' in self.currentProfile:
            self.currentProfile["detailsWindow"]["x"] = value
        else:
            self.currentProfile["detailsWindow"] = {}
            self.currentProfile["detailsWindow"]["x"] = value
    
    @property
    def detailsWindowY(self):
        if 'detailsWindow' in self.currentProfile and 'y' in self.currentProfile["detailsWindow"]:
            return self.currentProfile["detailsWindow"]["y"]
        else:
            return self.defaultProfile[0]["profileSettings"]["detailsWindow"]["y"]
    
    @detailsWindowY.setter
    def detailsWindowY(self, value):
        if 'detailsWindow' in self.currentProfile:
            self.currentProfile["detailsWindow"]["y"] = value
        else:
            self.currentProfile["detailsWindow"] = {}
            self.currentProfile["detailsWindow"]["y"] = value
    
    @property
    def disableUpdateReminderFor(self):
        for profile in self.allSettings:
            if (profile["profile"] == "Default"):
                return profile.get("disableUpdateReminderFor")
    
    @disableUpdateReminderFor.setter
    def disableUpdateReminderFor(self, value):
        for profile in self.allSettings:
            if (profile["profile"] == "Default"):
                profile["disableUpdateReminderFor"] = value
        self.writeSettings()
        
    @property
    def logLevel(self):
        for profile in self.allSettings:
            if (profile["profile"] == "Default"):
                if not profile.get("logLevel"):
                    profile["logLevel"] = self.defaultProfile[0]["logLevel"]
                    self.writeSettings()
                return profile.get("logLevel")
    
    @logLevel.setter
    def logLevel(self, value):
        for profile in self.allSettings:
            if (profile["profile"] == "Default"):
                profile["logLevel"] = value
        self.writeSettings()
        
    @property
    def detailsOrder(self):
        if 'detailsOrder' in self.currentProfile:
            return copy.deepcopy(self.currentProfile["detailsOrder"])
        else:
            return copy.deepcopy(self.defaultProfile[0]["profileSettings"]["detailsOrder"])
    
    @detailsOrder.setter
    def detailsOrder(self, value):
        self.currentProfile["detailsOrder"] = value
        self.writeSettings()
        
    @property
    def fleetServer(self):
        for profile in self.allSettings:
            if (profile["profile"] == "Default"):
                if not profile.get("fleetServer"):
                    profile["fleetServer"] = self.defaultProfile[0]["fleetServer"]
                    self.writeSettings()
                return profile.get("fleetServer")
            
    @fleetServer.setter
    def fleetServer(self, value):
        for profile in self.allSettings:
            if (profile["profile"] == "Default"):
                profile["fleetServer"] = value
        self.writeSettings()
        
    @property
    def fleetWindowShow(self):
        if self.lowCPUMode:
            return False
        if 'fleetWindow' in self.currentProfile and 'show' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["show"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["show"]
            
    @fleetWindowShow.setter
    def fleetWindowShow(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["show"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["show"] = value
        
    @property
    def fleetWindowWidth(self):
        if 'fleetWindow' in self.currentProfile and 'width' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["width"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["width"]
            
    @fleetWindowWidth.setter
    def fleetWindowWidth(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["width"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["width"] = value
        
    @property
    def fleetWindowHeight(self):
        if 'fleetWindow' in self.currentProfile and 'height' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["height"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["height"]
            
    @fleetWindowHeight.setter
    def fleetWindowHeight(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["height"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["height"] = value
        
    @property
    def fleetWindowX(self):
        if 'fleetWindow' in self.currentProfile and 'x' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["x"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["x"]
            
    @fleetWindowX.setter
    def fleetWindowX(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["x"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["x"] = value
        
    @property
    def fleetWindowY(self):
        if 'fleetWindow' in self.currentProfile and 'y' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["y"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["y"]
            
    @fleetWindowY.setter
    def fleetWindowY(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["y"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["y"] = value
        
    @property
    def fleetWindowShowAggregate(self):
        if 'fleetWindow' in self.currentProfile and 'showAggregate' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["showAggregate"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["showAggregate"]
            
    @fleetWindowShowAggregate.setter
    def fleetWindowShowAggregate(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["showAggregate"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["showAggregate"] = value
        
    @property
    def fleetWindowShowDpsOut(self):
        if 'fleetWindow' in self.currentProfile and 'showDpsOut' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["showDpsOut"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["showDpsOut"]
            
    @fleetWindowShowDpsOut.setter
    def fleetWindowShowDpsOut(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["showDpsOut"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["showDpsOut"] = value
        
    @property
    def fleetWindowShowDpsIn(self):
        if 'fleetWindow' in self.currentProfile and 'showDpsIn' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["showDpsIn"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["showDpsIn"]
            
    @fleetWindowShowDpsIn.setter
    def fleetWindowShowDpsIn(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["showDpsIn"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["showDpsIn"] = value
        
    @property
    def fleetWindowShowLogiOut(self):
        if 'fleetWindow' in self.currentProfile and 'showLogiOut' in self.currentProfile["fleetWindow"]:
            return self.currentProfile["fleetWindow"]["showLogiOut"]
        else:
            return self.defaultProfile[0]["profileSettings"]["fleetWindow"]["showLogiOut"]
            
    @fleetWindowShowLogiOut.setter
    def fleetWindowShowLogiOut(self, value):
        if 'fleetWindow' in self.currentProfile:
            self.currentProfile["fleetWindow"]["showLogiOut"] = value
        else:
            self.currentProfile["fleetWindow"] = {}
            self.currentProfile["fleetWindow"]["showLogiOut"] = value

    def setOverviewFiles(self, characterDict):
        for profile in self.allSettings:
            if (profile["profile"] == "Default"):
                profile["overviewFiles"] = characterDict
                self.writeSettings()

    def getOverviewFiles(self):
        for profile in self.allSettings:
            if (profile["profile"] == "Default"):
                if 'overviewFiles' not in profile:
                    if not hasattr(self, 'overviewNotificaitonShown'):
                        logging.info('No overview settings set, showing overview notification for this session...')
                        self.overviewNotificaitonShown = True
                        from settings.overviewSettings import OverviewNotification
                        OverviewNotification()
                    return {}
                return profile["overviewFiles"]

    def getOverviewFile(self, characterName):
        overviewFiles = self.getOverviewFiles()
        if characterName in overviewFiles:
            return overviewFiles[characterName]
        else:
            return overviewFiles["default"] if 'default' in overviewFiles else None

    def getOverviewSettings(self, characterName):
        overviewFile = self.getOverviewFile(characterName)
        if not overviewFile:
            return None
        try:
            with open(overviewFile, encoding='utf8') as overviewFileContent:
                return yaml.safe_load(overviewFileContent.read())
        except Exception as e:
            logging.exception('Exception loading overview settings file: ' + overviewFile)
            logging.exception(e)
            tk.messagebox.showerror("Error", "Error loading overview settings file:\n"+overviewFile)
            return None
    
    def setSettings(self, capDamageIn=None, capDamageOut=None, capRecieved=None, capTransfered=None,
                    dpsIn=None, dpsOut=None, logiIn=None, logiOut=None, mining=None,
                    interval=None, seconds=None,
                    windowHeight=None, windowWidth=None, windowX=None, windowY=None, compactTransparency=None,
                    labels=None, labelColumns=None, graphDisabled=None,
                    detailsOrder=None, detailsWindowShow=None):
        """ 
        this funciton is dumb, ugly, and deprecated.
        Settings should be set through properties
        Some cleanup would be needed to remove it entirely
        """
        if not capDamageIn == None:
            self.currentProfile["capDamageIn"] = capDamageIn
        if not capDamageOut == None:
            self.currentProfile["capDamageOut"] = capDamageOut
        if not capRecieved == None:
            self.currentProfile["capRecieved"] = capRecieved
        if not capTransfered == None:
            self.currentProfile["capTransfered"] = capTransfered
        if not dpsIn == None:
            self.currentProfile["dpsIn"] = dpsIn
        if not dpsOut == None:
            self.currentProfile["dpsOut"] = dpsOut
        if not logiIn == None:
            self.currentProfile["logiIn"] = logiIn
        if not logiOut == None:
            self.currentProfile["logiOut"] = logiOut
        if not mining == None:
            self.currentProfile["mining"] = mining
        if not interval == None:
            self.currentProfile["interval"] = interval
        if not seconds == None:
            self.currentProfile["seconds"] = seconds
        if not windowHeight == None:
            self.currentProfile["windowHeight"] = windowHeight
        if not windowWidth == None:
            self.currentProfile["windowWidth"] = windowWidth
        if not windowX == None:
            self.currentProfile["windowX"] = windowX
        if not windowY == None:
            self.currentProfile["windowY"] = windowY
        if not compactTransparency == None:
            self.currentProfile["compactTransparency"] = compactTransparency
        if not labels == None:
            self.currentProfile["labels"] = labels
        if not labelColumns == None:
            self.currentProfile["labelColumns"] = labelColumns
        if not graphDisabled == None:
            self.currentProfile["graphDisabled"] = graphDisabled
        if not detailsWindowShow == None:
            self.detailsWindowShow = detailsWindowShow
        if not detailsOrder == None:
            self.currentProfile["detailsOrder"] = detailsOrder
        
        self.writeSettings()
    
    def switchProfile(self):
        self.mainWindow.saveWindowGeometry()
        self.allSettings.insert(0, self.allSettings.pop(self.selectedIndex.get()))
        self.currentProfile = self.allSettings[0]["profileSettings"]
        self.mainWindow.profileMenu.delete(0,tk.END) 
        self.initializeMenu(self.mainWindow)
        self.mainWindow.geometry("%sx%s+%s+%s" % (self.getWindowWidth(), self.getWindowHeight(), 
                                       self.getWindowX(), self.getWindowY()))
        self.mainWindow.detailsWindow.geometry("%sx%s+%s+%s" % (self.detailsWindowWidth, self.detailsWindowHeight, 
                                                self.detailsWindowX, self.detailsWindowY))
        self.mainWindow.update_idletasks()
        self.mainWindow.graphFrame.readjust(0)
        self.mainWindow.animator.changeSettings()
        self.writeSettings()
    
    def writeSettings(self):
        logging.info('New settings:')
        logging.info(str(self.currentProfile))
        tempFile = os.path.join(self.path, "PELD_temp.json")
        settingsFile = open(tempFile, 'w')
        json.dump(self.allSettings, settingsFile, indent=4)
        settingsFile.close()
        os.remove(self.fullPath)
        self.observer.unschedule_all()
        os.rename(tempFile, self.fullPath)
        self.observer.schedule(self, self.path, recursive=False)