#!/usr/bin/env python

'''foamGUI.py - main frame'''

import wx, os

from aboutFoam import OpenFoamAbout
from foamDirTree import FoamDirPanel
from foamWork import FoamWorkPanel
from redStd import OutputPanel
import random

class FoamFrame(wx.Frame):
  '''OF main frame class'''
  def __init__(self, parent=None, remoteData=None, *args, **kwargs):
    if remoteData is not None:
        kwargs['title'] = "OpenFOAM on {} / Username: {}".format(remoteData['hostname'],
            remoteData['login'])
    else:
        kwargs['title'] = "OpenFOAM Test Frame"
    kwargs['size'] = (1200, 800)
    wx.Frame.__init__(self, parent, *args, **kwargs)

    #standart frame items
    self.initStatusBar()
    self.createMenuBar()

    self.remoteData = remoteData
    self.panel = SplitterPanel(self, self.remoteData)

  def initStatusBar(self):
    '''status bar initialisation function'''
    self.statusbar = self.CreateStatusBar() #create a status bar at the botom
    self.statusbar.SetFieldsCount(2)   #divide it in 2 parts
    self.statusbar.SetStatusWidths([-3, -1])

  def menuData(self):
    '''menu items data base'''
    return [["&File", (
              #("&New", "New OpenFOAM case generation", self.OnNew, wx.ID_NEW),
              ("&Open", "Open OpenFOAM case folder", self.OnOpen, wx.ID_OPEN),
              #("&Save", "Save the case", self.OnSave, wx.ID_SAVE),
              ("", "", ""),
              ("&Quit", "Quit application", self.OnCloseWindow, wx.ID_EXIT))],
            ["&Help", (
              ("About...", "Show about window", self.OnAbout),
              ("", "", ""))]]

  def createMenuBar(self):
    menuBar = wx.MenuBar()
    for eachMenuData in self.menuData():
      menuLabel = eachMenuData[0]
      menuItems = eachMenuData[1]
      menuBar.Append(self.createMenu(menuItems), menuLabel)
    self.SetMenuBar(menuBar)

  def createMenu(self, menuData):
    menu = wx.Menu()
    for eachItem in menuData:
      if len(eachItem) == 2:
        label = eachItem[0]
        subMenu = self.createMenu(eachItem[1])
        menu.AppendMenu(wx.NewId(), label, subMenu)
      else:
        self.createMenuItem(menu, *eachItem)
    return menu

  def createMenuItem(self, menu, label, status, handler, ID=-1, kind=wx.ITEM_NORMAL):
    if not label:
      menu.AppendSeparator()
      return
    menuItem = menu.Append(ID, label, status, kind)
    self.Bind(wx.EVT_MENU, handler, menuItem)

  def OnOpen(self, event):
    dlg = wx.DirDialog(self, "Chose an OpenFOAM case directory:",
                       style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
    if dlg.ShowModal() == wx.ID_OK:
      self.remoteData['casePath'] = dlg.GetPath()
      g = os.walk(self.remoteData['casePath']).next()  #tuple of case folder contents (casePath, dirsTuple, filesTuple)
      casePatent = set(['system', 'constant']) #patent for OF case dictionaries

      #check if the selected folder is a valid OF case
      if casePatent.issubset(set(g[1])):
          print "Case {} opened".format(self.remoteData['casePath'])
          self.panel.ReplaceWindows(self.remoteData)
      else: #if it's not valid
        #pop a message error
        mesg = wx.MessageDialog(self.panel, 'Invalid OpenFOAM case folder selected!',
                                     "Selection Error", wx.OK|wx.ICON_WARNING)
        if mesg.ShowModal() == wx.ID_OK:
            print 'Error: Invalid OpenFOAM case folder!'

  def OnCloseWindow(self, event):
    self.Destroy()

  def OnAbout(self, event):
    dlg = OpenFoamAbout(self)
    dlg.ShowModal() #show dilog box, modal means cannot do anything till press "OK"
    dlg.Destroy()

  def OnUnvalidOFcase(self, event):
    self.panel.Destroy()

class SplitterPanel(wx.SplitterWindow):
  '''foam working pannel'''
  def __init__(self, parent, userData, *args, **kwargs):
    wx.SplitterWindow.__init__(self, parent, *args, **kwargs)

    #self.GetParent().SendSizeEvent()    #fit the panel size

    '''splitters'''
    right = wx.SplitterWindow(self)

    '''panels'''
    left = wx.Panel(self, style=wx.SUNKEN_BORDER)
    top = wx.Panel(right, style=wx.SUNKEN_BORDER)
    bottom = OutputPanel(right, style=wx.SUNKEN_BORDER)

    '''split'''
    right.SplitHorizontally(top, bottom, 550)
    self.SplitVertically(left, right, 200)

    self.Layout()

  def ReplaceWindows(self, userData):
    '''replace panels for new cases'''
    left = self.GetWindow1()
    right = self.GetWindow2()
    top = right.GetWindow1()
    self.ReplaceWindow(left, FoamDirPanel(self, userData['casePath'], style=wx.SUNKEN_BORDER))
    right.ReplaceWindow(top, FoamWorkPanel(right, userData, style=wx.SUNKEN_BORDER))
    self.Layout()

if __name__ == '__main__':
  from remote_data import loginInfo
  app = wx.App(False)
  FoamFrame(None, loginInfo).Show()
  app.MainLoop()
