# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------------
# Name:        SliceViewer
# Purpose:
#
# Author:
#
# Created:     22/01/2016
# Copyright:   (c)
# Licence:
#-------------------------------------------------------------------------------

#######################################
#  SliceViewer
#######################################

from __future__ import print_function
import six
if six.PY2:
    import thread as _thread
    import Queue as queue
else:
    import _thread
    import queue
import os, sys
import socket
import time
import threading
import subprocess

from uGao.QtCom import SearchPath, CommQt
view_path = SearchPath( "View", isFile=False )
if view_path is not None:
    sys.path.append(view_path)

class SliceViewer(object) :
    """
    プロッタのファサードクラス
    Python インタープリタ からプロッタを起動し
    制御するためのユーザインターフェイスを提供
    """
    # プロッタ通信クラスのインスタンスリスト
    plotList = []
    # plotList のロック用
    lck = _thread.allocate_lock()

    #########################################
    def __init__(self,data=None, closeFlag = True):
        """
        コンストラクタ
        @param  data  プロッタに表示するデータ、省略可
        　　　　エレメントアレイまたはエレメントアレイのリスト
        @closeFlag   親プロセス終了時に、プロッタをクローズするか
        　　　　　　 否かのフラグ
        @retval 無し
        """
        self.plot = None

        # プロッタの作成
        self.NewPlot(data, closeFlag)

    #########################################
    def NewPlot(self, data=None, closeFlag = True):
        """
        プロッタを追加し、カレントプロッタとする
        @param  data  プロッタに表示するデータ、省略可
        　　　　エレメントアレイまたはエレメントアレイのリスト
        @param closeFlag  親プロセス終了時に、子プロセスを終了させるかどうかのフラグ
        @retval 無し
        """
        # 引数リストを作成
        pno = len(self.plotList) +1
        strPno = "%d" % pno

        if closeFlag == True:
            cflag = "True"
        else:
            cflag = "False"

        arg = ["SliceViewerMain.py", strPno, cflag]
        # プロセスID とプロッタ番号からポート番号を生成
        pxx = (os.getpid() % 500)*20
        portno = 10000+ pxx + pno

        # GUI通信クラスのインスタンス取得
        p = CommQt()

        # プロセス生成と通信接続に成功したなら
        if p.NewComm(portno, arg):
            # 旧カレントプロッタのアイコン化要求
            #self._IconizeCurrent()

            self.lck.acquire()
            # 追加したプロッタをリストへ追加
            #self.plotList.append(p)
            # ロックの解放
            self.lck.release()

            # 追加したプロッタをカレントプロッタとする。
            self.plot = p
            # データが指定されていたら
            if not data is None:
                # データを追加
                self.AddData(data)
        else:
            print("\nError!!  Cannot create a new plotter!!.")

#######################################
#  User Command
#######################################
# コマンドヘルプ
    def help(self):
        print("*---------------------------")
        print("*** Slice Viewer Command ***")
        print("*---------------------------")
        print("+ setFocalPoint(x, y, z)")
        print("+ setViewPoint(x, y, z)")
        print("+ setDistance(dist)")
        print("+ setAzimuth(az)")
        print("+ setElevation(ele)")
        print("+ setScalarRange(min, max)")
        print("+ setAxisLength(lenX, lenY, lenZ)")
        print("+ setGridScale(scaleX, scaleY, scaleZ)")
        print("+ setOutputDirectory(directory)")
        print("+ doSliceAx1(proc, pos, delta, ax2bin, ax3bin)")
        print("  - proc:")
        print("      0: Draw on main view")
        print("      1: Draw by M2Plot")
        print("      2: Save as Image (should setOutputDirectory)")
        print("      3: Save as ECA (should setOutputDirectory)")
        print("  - pos: position of plane")
        print("  - delta: thickness of plane")
        print("  - ax2bin, ax3bin: bin for each direction")
        print("+ doSliceAx2(proc, pos, delta, ax3bin, ax1bin)")
        print("  - proc:")
        print("      0: Draw on main view")
        print("      1: Draw by M2Plot")
        print("      2: Save as Image (should setOutputDirectory)")
        print("      3: Save as ECA (should setOutputDirectory)")
        print("  - pos: position of plane")
        print("  - delta: thickness of plane")
        print("  - ax1bin, ax3bin: bin for each direction")
        print("+ doSliceAx3(proc, pos, delta, ax1bin, ax2bin)")
        print("  - proc:")
        print("      0: Draw on main view")
        print("      1: Draw by M2Plot")
        print("      2: Save as Image (should setOutputDirectory)")
        print("      3: Save as ECA (should setOutputDirectory)")
        print("  - pos: position of plane")
        print("  - delta: thickness of plane")
        print("  - ax1bin, ax2bin: bin for each direction")
        print("+ doFreeSlice(proc, org[0], org[1], org[2], x[0], x[1], x[2], ")
        print("              y[0], y[1], y[2], xbin, ybin, xrange[0], xrange[1], yrange[0], yrange[1], delta)")
        print("  - proc:")
        print("      0: Draw on main view")
        print("      1: Draw by M2Plot")
        print("      2: Save as Image (should setOutputDirectory)")
        print("      3: Save as ECA (should setOutputDirectory)")
        print("  - org: Origin of plane")
        print("  - x: point on x-axis")
        print("  - y: point on y-axis")
        print("  - xbin, ybin: bin for each direction")
        print("  - xrange, yrange: view range for each direction")
        print("  - delta: thickness of plane")


# 注視点を指定
    def setFocalPoint(self, x, y, z):
        strCmd = "setFocalPoint %s %s %s\n" % (str(x), str(y), str(z))
        self.plot.PutCommand(strCmd)

# 注視点を指定
    def setViewPoint(self, x, y, z):
        strCmd = "setViewPoint %s %s %s\n" % (str(x), str(y), str(z))
        self.plot.PutCommand(strCmd)

# 視点の距離を指定
    def setDistance(self, dist):
        strCmd = "setDistance %s\n" % str(dist)
        self.plot.PutCommand(strCmd)

# 方位角を指定
    def setAzimuth(self, az):
        strCmd = "setAzimuth %s\n" % str(az)
        self.plot.PutCommand(strCmd)

# 視点の仰角を指定
    def setElevation(self, ele):
        strCmd = "setElevation %s\n" % str(ele)
        self.plot.PutCommand(strCmd)

# set scalar range
    def setScalarRange(self, min, max):
        strCmd = "setScalarRange %s %s\n" %(str(min), str(max))
        self.plot.PutCommand(strCmd)

# set axis length
    def setAxisLength(self, lenX, lenY, lenZ):
        strCmd = "setAxisLength %s %s %s\n" %(str(lenX), str(lenY), str(lenZ))
        self.plot.PutCommand(strCmd)

# set grid scale
    def setGridScale(self, scaleX, scaleY, scaleZ):
        strCmd = "setGridScale %s %s %s\n" %(str(scaleX), str(scaleY), str(scaleZ))
        self.plot.PutCommand(strCmd)

# set output directory
    def setOutputDirectory(self, directory):
        strCmd = "setOutputDirectory %s\n" %(str(directory))
        self.plot.PutCommand(strCmd)

# basic slice Ax1
    def doSliceAx1(self, proc, pos, delta, ax2bin, ax3bin):
        strCmd = "doSliceAx1 %s %s %s %s %s\n" %(str(proc), str(pos), \
                  str(delta), str(ax2bin), str(ax3bin))
        self.plot.PutCommand(strCmd)

# basic slice Ax2
    def doSliceAx2(self, proc, pos, delta, ax3bin, ax1bin):
        strCmd = "doSliceAx2 %s %s %s %s %s\n" %(str(proc), str(pos), \
                  str(delta), str(ax3bin), str(ax1bin))
        self.plot.PutCommand(strCmd)

# basic slice Ax3
    def doSliceAx3(self, proc, pos, delta, ax1bin, ax2bin):
        strCmd = "doSliceAx3 %s %s %s %s %s\n" %(str(proc), str(pos), \
                  str(delta), str(ax1bin), str(ax2bin))
        self.plot.PutCommand(strCmd)

    def doFreeSlice(self, proc, org1, org2, org3, x1, x2, x3, y1, y2, y3, \
                 xbin, ybin, xrange1, xrange2, yrange1, yrange2, thickness):
        strCmd = "doFreeSlice %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n" %(str(proc), str(org1), \
                                                                                      str(org2), str(org3), str(x1), \
                                                                                      str(x2), str(x3), str(y1), str(y2), str(y3), \
                                                                                      str(xbin), str(ybin), str(xrange1), \
                  str(xrange2), str(yrange1), str(yrange2), str(thickness))

        self.plot.PutCommand(strCmd)

# set data [inamura 170227]-->
#[inamura 180422]
    def setData(self, ecm, title="Empty", xkey="-", ykey="-", zkey="-", xbin="-", ybin="-", zbin="-"):
        from uGao.uGaoUtil import TempFile
        import Manyo
        TMPF = TempFile()
        temppath = TMPF.GetTempName(".srlz")
        if temppath is None:
            print("Error Error Error")
            return
        crw = Manyo.WriteSerializationFileBinary(temppath)
        crw.Save(ecm)
        del crw

        title = title.strip().replace(" ","_")
        strCmd = "setData %s %s %s %s %s %s %s %s\n"%(temppath,title,xkey,ykey,zkey,xbin,ybin,zbin) #[inamura 180422]
        #print("command="+strCmd)
        ret = self.plot.PutCommand(strCmd)
        if ret is None:
            return False
        else:
            return True

    def setAxesTitles(self, xtitle="X", ytitle="Y",  ztitle="Z"):
        strCmd = "setAxesTitles %s %s %s\n"%(xtitle,ytitle,ztitle)
        ret = self.plot.PutCommand(strCmd)
        if ret is None:
            return False
        else:
            return True
#<--[inamura 170227]

#########################################

if __name__ == '__main__':
    SliceViewer()
