## ------------------------------------------------------------------------
## iSiLK - A python-based graphical user interface for SiLK
## ------------------------------------------------------------------------
## Copyright (C) 2006-2007 Carnegie Mellon University. All Rights Reserved.
## ------------------------------------------------------------------------
## Authors: Andrew Kompanek (ajk@cert.org)
## ------------------------------------------------------------------------
## GNU General Public License (GPL) Rights pursuant to Version 2, June 1991
## Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013
## ------------------------------------------------------------------------
## See the LICENSE file included in this distribution
## ------------------------------------------------------------------------

import tools
import resultset
import silk
import string
import silkutils
import wx, ws, copy
import config.filteroptions, config.silk
from controls.filteroptionspanel import FieldPanel, FieldValidator
from controls.filteroptionspanel import _bin_size_doc_
from querybuilder import PreviewCommandPanel


class CountTool(tools.AnalysisTool):
    def __init__(self, **kargs):
        tools.AnalysisTool.__init__(self, **kargs)
        
    def CreateDialog(parentResult, parent):
        return TrendDialog(parentResult, parent)
    CreateDialog = staticmethod(CreateDialog)
    
    def CanRun(parentResult):
        return parentResult.IsFilterResult()
    CanRun = staticmethod(CanRun)

    def _GetResultClass(self):
        return resultset.CountResult

    def _GetResultName(self):
        return "Untitled rwcount timeseries"

    def _RunAnalysis(self, context, inputFileName, outputFileName):
        silk.count(context, inputFileName, outputFileName, **self.opts)
        
    def _GetCommandLines(inputFile, outputFile, **kargs):
        cmd = silk.build_count_command(False, "", inputFile, outputFile, commandsOnly=True, **kargs)
        return cmd
    _GetCommandLines = staticmethod(_GetCommandLines)

class BinSizeCtrl(FieldPanel):
    def __init__(self, parent, label_text, field_name, *args, **kargs):
        initial_val = "1800"
        choices = config.filteroptions.CFG_BIN_SIZE_OPTIONS.keys()
        config_options = config.filteroptions.CFG_BIN_SIZE_OPTIONS
        validator = FieldValidator(self, "Bin Size", string.digits,
            silkutils.validate_bin_size_arg, _bin_size_doc_)            
        FieldPanel.__init__(self, parent, label_text, field_name, initial_val,
            config.filteroptions.CFG_BIN_SIZE_OPTIONS, config_options, validator=validator, *args, **kargs)
        self.Bind(wx.EVT_COMBOBOX, self.OnOptionCombo, self.combo)


class TrendDialog(wx.Dialog):
    def __init__(self, parentResult, parent, *args, **kargs):
        wx.Dialog.__init__(self, parent, -1,
            "Running rwcount on result", *args, **kargs)
        self.parentResult = parentResult
        self.cbBinSize = BinSizeCtrl(self, "Bin Size (s)", "bin-size")
        # Allow user to assign a name and see a preview
        self._createNameEditor()
        self.previewPanel = PreviewCommandPanel(self,  "Not yet initialized")
        # Create buttons
        sz = wx.BoxSizer(wx.HORIZONTAL)
        sz.Add(wx.Button(self, wx.ID_CANCEL, "Cancel"), flag=wx.ALL, border=10)
        btnCreate = wx.Button(self, wx.ID_OK, "Run Analysis") #, (110,-1), (100,-1))
        sz.Add(btnCreate, flag=wx.ALL, border=10)
        # Create is default button
        btnCreate.SetDefault()
        # Escape key or close causes cancel
        self.SetEscapeId(wx.ID_CANCEL)
        szDlg = wx.BoxSizer(wx.VERTICAL)
        szDlg.Add(self.cbBinSize, flag=wx.ALL, border=8)
        szDlg.Add(self.previewPanel, flag=wx.ALL|wx.EXPAND, border=8)
        szDlg.Add(self.szName, flag=wx.ALL|wx.ALIGN_RIGHT, border=8)
        szDlg.Add(sz, flag=wx.ALL|wx.ALIGN_RIGHT, border=8)
        self.SetSizerAndFit(szDlg)
        self.Bind(ws.EVT_OPTION_CHANGE, self.OnOptionChange)
        self.RefreshCommandLine()
        
    def _createNameEditor(self):
        self.name = wx.TextCtrl(self, -1, "Untitled rwcount time-series", 
            validator=ws.NameValidator(), size=(200,-1))
        self.szName = szName = wx.BoxSizer(wx.HORIZONTAL)
        szName.Add(ws.SmStaticText(self, -1, "Name"),
            flag=wx.RIGHT|wx.ALIGN_CENTER, border=6)
        szName.Add(self.name, flag=wx.ALIGN_CENTER|wx.RIGHT, border=10)
        
    def GetResultName(self):
        return self.name.GetValue()

    def GetOptions(self):
        opts = {} 
        opts["bin-size"] = int(self.cbBinSize.GetValue())
        return opts
        
    def SetOptions(self, opts):
        if not "bin-size" in opts:
            return
        self.cbBinSize.SetValue(str(opts["bin-size"]))
        
    def GetCommandLine(self):
        opts = copy.copy(self.GetOptions())
        if config.silk.opts["WORK_REMOTE"]:
            cmd = silk.build_count_command(False, self.parentResult.GetRemoteDir(),
                    self.parentResult.GetFileName(), "$output", **opts)            
        else:
            cmd = silk.build_count_command(False, self.parentResult.GetLocalDir(),
                    self.parentResult.GetFileName(), "$output", **opts)
        print "cmd = %s" % cmd
        return cmd

    def RefreshCommandLine(self):
        cmd = self.GetCommandLine()
        self.previewPanel.SetContent(cmd)
        
    def OnOptionChange(self, evt):
        self.RefreshCommandLine()
        