# -*- coding: utf-8 -*-
import wx
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from vis.UtilPlot import IFEvtProp, Images

#######################################
#  ChartToolBar
#######################################         
class ChartToolBar(NavigationToolbar2Wx, wx.ToolBar):
    """
    matplotlib 画像操作用のツールバーの拡張クラス
    印刷処理追加と、画面設定処理のオーバーライド
    """
    #######################################
    def __init__(self, parent, order):
        """
        コンストラクタ
        @param parent  親クラスのインスタンス
        @params order  イベントディスパッチャのID
        @retval 無
        """
        self.parent = parent
        # イベント管理クラスのインスタンスを取得
        self.ifi = IFEvtProp(order)
        #先にスーパークラスのコンストラクタを実行させる
        NavigationToolbar2Wx.__init__(self, parent.canvas)
        # フラグ類の初期化
        self._idle = True
        self.statbar = None
        self.downEvt = None
        self.printingFlag = False
        # イベント格納用リストを準備
        self.evtlst = [None]
 
    ##################################    
    def _init_toolbar(self):
        """
        ツールバーを作成
        @param 無し
        @retval 無し
        """
        #先にスーパークラスのツールバーを作る
        NavigationToolbar2Wx._init_toolbar(self)

        self._parent = self.parent.canvas.GetParent()
        #プリンタのアイコンをツールバーに追加
        _NTB3_PRINT    =wx.NewId()
        self.SetToolBitmapSize(wx.Size(24,24))
        self.AddSeparator()
        self.AddSimpleTool(_NTB3_PRINT, Images().GetBmp("Printer"),
                           'Print', 'Print graph image')

        #プリンタアイコン押下時のイベントハンドラ作成 
        if wx.VERSION_STRING >= '2.5':
            self.Bind(wx.EVT_TOOL, self.OnPrint, id=_NTB3_PRINT)
        else:
            wx.EVT_TOOL(self, _NTB3_PRINT, self.OnPrint)

        self.Realize()
        
    ##################################    
    def OnPrint(self, evt):
        """
        印刷要求を通知
        @param  evt    イベント情報
        @retval 無し
        """ 
        # 印刷イベント通知
        self.ifi.NotifyEvent(self,"print")
        
    ##################################    
    def back(self, evt):
        """
        バックワード処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #先にスーパークラスのバックワード処理処理を実行
        NavigationToolbar2Wx.back(self, evt)
        self.evtPoint = self.evtPoint - 1 
        # ヒストリ処理
        self._GetHistory()
                
    ##################################    
    def forward(self, evt):
        """
        フォワード処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #先にスーパークラスのフォワード処理処理を実行
        NavigationToolbar2Wx.forward(self, evt)
        self.evtPoint += 1
        # ヒストリ処理
        self._GetHistory()
        
    ##################################    
    def _GetHistory(self):
        """
        ヒストリ処理
        @param  無し
        @retval 無し
        """ 
        # イベント取得 
        evt = self.evtlst[self.evtPoint]
        # イベントがNon だったら、Home ボタン押下イベント
        if evt == None:
            # ホームポジションイベントを通知
            self.ifi.NotifyEvent(self,"home")
        else:
            # 表示範囲変更イベントを通知
            self.ifi.NotifyEvent(self,"changexy", self.evtlst[self.evtPoint])                                               
        
    ##################################    
    def home(self, evt):
        """
        ホームポジション処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #先にスーパークラスのホームポジション処理を実行
        try:
            NavigationToolbar2Wx.home(self, evt)
        except:
            # ズーム後にプロットを被せたときに発生する例外の抑制
            pass
        # イベントを格納
        self.evtlst.append(None)
        self.evtPoint = len(self.evtlst)-1
        # ホームポジションイベントを通知
        self.ifi.NotifyEvent(self,"home")   

    ##################################    
    def back(self, evt):
        """
        バックワード処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #スーパークラスのバックワード処理を実行
        try:
            NavigationToolbar2Wx.back(self, evt)
        except:
            # ズーム後にプロットを被せたときに発生する例外の抑制
            pass
        # 表示範囲変更イベントを通知
        self.ifi.NotifyEvent(self,"changexy", (self.downEvt, evt))

    ##################################    
    def forward(self, evt):
        """
        フォワード処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #スーパークラスのフォワード処理を実行
        try:
            NavigationToolbar2Wx.forward(self, evt)
        except:
            # ズーム後にプロットを被せたときに発生する例外の抑制
            pass
        # 表示範囲変更イベントを通知
        self.ifi.NotifyEvent(self,"changexy", (self.downEvt, evt))

    ##################################    
    def release_zoom(self, evt):
        """
        拡大イベント処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #先にスーパークラスのズーム処理を実行
        NavigationToolbar2Wx.release_zoom(self, evt)
        # マウスクリック点がグラフ外であれば
        if self.downEvt == None:
            # 何もしない
            return
        # イベントを格納
        self.evtlst.append((self.downEvt, evt))
        self.evtPoint = len(self.evtlst)-1
        # 表示範囲変更イベントを通知
        self.ifi.NotifyEvent(self,"changexy", (self.downEvt, evt))

    ##################################    
    def release_pan(self, evt):
        """
        パンイベント処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #先にスーパークラスのパン処理を実行
        NavigationToolbar2Wx.release_pan(self, evt)
        # マウスクリック点がグラフ外であれば
        if self.downEvt == None:
            # 何もしない
            return
        # イベントを格納
        self.evtlst.append((self.downEvt, evt))
        self.evtPoint = len(self.evtlst)-1
        # 表示範囲変更イベントを通知
        self.ifi.NotifyEvent(self,"changexy", (self.downEvt, evt))        
        
    ##################################    
    def press_zoom(self, evt):
        """
        拡大イベント処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #先にスーパークラスのズーム処理を実行
        NavigationToolbar2Wx.press_zoom(self, evt)
        # グラフ内であれば
        if evt.inaxes:
            # ドラッグ開始点のイベントを保存
            self.downEvt = evt
        else:
            self.downEvt = None

    ##################################    
    def press_pan(self, evt):
        """
        パンイベント処理 (オーバーライド関数)
        @param  evt    イベント情報
        @retval 無し
        """                  
        #先にスーパークラスのパン処理を実行
        NavigationToolbar2Wx.press_pan(self, evt)
        # グラフ内であれば
        if evt.inaxes:
            # パン開始点のY位置を保存
            self.downEvt = evt
        else:
            self.downEvt = None
        
    ##################################    
    def save(self, evt):
        """
        キャンバスに描画されている画像を保存(オーバライド関数)
        @param evt イベント
        @retval 無
        """ 
        # 画像保存用ファイルの絶対パスを取得

        # 保存ファイルタイプの拡張子を取得

        filetypes = "PNG (*.png)|*.png|PS (*.ps)|*.ps|EPS (*.eps)|*.eps"
        # ファイル保存ダイアログを表示
        dlg =wx.FileDialog(self.parent.frame, "Save the image", "", "", filetypes,
                           wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR)
        # OK であればファイルを保存

        if dlg.ShowModal() == wx.ID_OK:
           
            # 指定されたパスに日本語が含まれていないかどうかをチェック
            try:
                # wxPython 2.8 on Linux では拡張子を自動付加しない(バグ?)ため
                # 拡張子のチェックを行う。
                path, ext = os.path.splitext(dlg.GetPath())
                # 拡張子が正しく入力されていたらパスを返す 
                if ext == ".png"  or ext == ".ps" or ext ==".eps":
                    # パスに日本語が含まれている場合例外が発生
                    try:
                        fname = str(dlg.GetPath())
                    except:
                        raise PlotException('Common','C021',())
                    else:
                        # パスを指定してファイル保存イベントを通知
                        self.ifi.NotifyEvent(self,"save", fname) 
                else:    
                    # エラーメッセージを表示して保存を行わない
                    raise PlotException('Common','C024',())
            except PlotException, ex:
                PlotMessage(self.parent.frame,ex)
