# -*- coding: utf-8 -*-
"""Qt wizard on linear static plus study case
"""
"""
    created by Takeru who belongs
    to Japanese Localization Subcommittee in JSWG (Japan Salome-Meca Working Group)
    on Mar 12 2014
"""
#print "Check1"
import sys
from PyQt4 import QtGui as qt

import aster_s.salome_tree as ST
import aster_s.wizards.linear_static_plus as LSP
import aster_s_gui
import aster_s_gui.wizards.common as WC
from aster_s.utils import log_gui
#from pprint import pprint

#print "Check2"

def is_valid_mesh(cexp, mesh, mod):
    """A valid mesh needs to have groups for pressure"""
    is_valid = True
    log_gui.debug("is_valid_mesh %s / %s", mesh, mod)
    if not mesh:
        mess = "A mesh is required"
        mod.launch(aster_s_gui.ERROR, mess)
        is_valid = False
        return is_valid
    if not cexp.give("pressure").find_groups(mesh):
        mess = "At least a group without nodes need to be defined " \
               "on the selected object"
        mod.launch(aster_s_gui.ERROR, mess)
        is_valid = False
    return is_valid


class SMeshExp(WC.CompoExp):
    """Linear static SMESH explorator
    """

    def __init__(self):
        WC.CompoExp.__init__(self)
        SMesh = ST.SMeshExplorator

        exp = SMesh()
        no_grp = exp.add_group(LSP.GRP_NO)
        no_grp.register((2, 3), [SMesh.node])
        ma_grp = exp.add_group(LSP.GRP_MA)
        ma_grp.register((2, 3), [SMesh.edge])
        ma_grp.register((3,), [SMesh.face, SMesh.volume])
        self.register("boundaries", exp)
        self.register("pressure", ma_grp)

        exp = SMesh()
        grp = exp.add_group("load_vertex")
        grp.register((2,3), [SMesh.node])
        self.register("load_vertex", exp)

        exp = SMesh()
        grp = exp.add_group("load_edge")
        grp.register((2,3), [SMesh.edge])
        self.register("load_edge", exp)

        exp = SMesh()
        grp = exp.add_group("load_face")
        grp.register((3,), [SMesh.face])
        self.register("load_face", exp)


    def validate(self, mesh, mod):
        """A valid mesh needs to have mesh groups for defining pressure"""
        return is_valid_mesh(self, mesh, mod)


class GeomExp(WC.CompoExp):
    """Linear static GEOM explorator
    """

    def __init__(self):
        WC.CompoExp.__init__(self)
        Geom = ST.GeomExplorator

        exp = Geom()
        no_grp = exp.add_group(LSP.GRP_NO)
        no_grp.register((2, 3), [Geom.vertex])
        ma_grp = exp.add_group(LSP.GRP_MA)
        ma_grp.register((2, 3), [Geom.edge])
        ma_grp.register((3,), [Geom.face, Geom.shell])
        self.register("boundaries", exp)
        self.register("pressure", ma_grp)

        exp = Geom()
        grp = exp.add_group("load_vertex")
        grp.register((2,3), [Geom.vertex])
        self.register("load_vertex", exp)

        exp = Geom()
        grp = exp.add_group("load_edge")
        grp.register((2,3), [Geom.edge])
        self.register("load_edge", exp)

        exp = Geom()
        grp = exp.add_group("load_face")
        grp.register((3,), [Geom.face])
        self.register("load_face", exp)


    def validate(self, mesh, mod):
        """A valid geometry needs to have mesh groups for defining pressure"""
        return is_valid_mesh(self, mesh, mod)


class LoadVertexPage(WC.WizardPage):
    """Wizard page on axis loading to vertex or nodes"""

    def cleanupPage(self):
        """Clean page in case user navigates"""
        WC.WizardPage.cleanup(self)

    def initializePage(self):
        """Query the model on meshes"""
        WC.WizardPage.initialize(self)
        self.page.use(qt.QVBoxLayout())
        exp = self.give_field("exp-store").give_exp("load_vertex")
        grps = exp.find_groups(self.give_field("mesh"))
        #dims = [(u"LoadVertex", 1.)]
        dims = [("FX", 0.), ("FY", 0.)]
        if self.give_field("model").dim == 3:
            dims.append(("FZ", 0.))
#        tit = u"Adding Load to Vertex on meshes groups"
#        tit = u"境界条件（点荷重）を指定するグループ（点）に対して値を設定する"
        tit = qt.QApplication.translate("WizardLinearStaticPlus", "Adding Load to Vertexes or Nodes on meshes groups", None, qt.QApplication.UnicodeUTF8)
        ## The last groups should be seen first
        #grps.reverse()
        #WC.add_condition_selector(self, grps, dims, "vertex-loading*", tit)
        WC.add_condition_selector(self, grps, dims, "vertex-loading", tit)


def add_loadvertex_page(wiz):
    """Add page on axis loading to vertex"""
#    page = wiz.add_page(u"Boundaries conditions", PressurePage())
#    page = wiz.add_page(u"境界条件（点荷重）の設定", LoadVertexPage())
    page = wiz.add_page(qt.QApplication.translate("WizardLinearStaticPlus", "Boundaries conditions (Load to Vertexes or Nodes on meshes groups)", None, qt.QApplication.UnicodeUTF8), LoadVertexPage())
    #page.register("vertex-loading*", None)
    page.register("vertex-loading", None)


class LoadEdgePage(WC.WizardPage):
    """Wizard page on axis loading to edge"""

    def cleanupPage(self):
        """Clean page in case user navigates"""
        WC.WizardPage.cleanup(self)

    def initializePage(self):
        """Query the model on meshes"""
        WC.WizardPage.initialize(self)
        self.page.use(qt.QVBoxLayout())

        dims = [("FX", 0.), ("FY", 0.)]
        if self.give_field("model").dim == 3:
            dims.append(("FZ", 0.))
        exp = self.give_field("exp-store").give_exp("load_edge")
        grps = exp.find_groups(self.give_field("mesh"))
        #dims = [(u"LoadEdge", 1.)]
#        tit = u"Adding Load to Edge on meshes groups"
#        tit = u"境界条件（エッジ荷重）を指定するグループ（エッジ）に対して値を設定する"
        tit = qt.QApplication.translate("WizardLinearStaticPlus", "Adding Load to Edges on meshes groups", None, qt.QApplication.UnicodeUTF8)
        # The last groups should be seen first
        grps.reverse()
        #WC.add_condition_selector(self, grps, dims, "edge-loading*", tit)
        WC.add_condition_selector(self, grps, dims, "edge-loading", tit)


def add_loadedge_page(wiz):
    """Add page on pressure loading"""
#    page = wiz.add_page(u"Boundaries conditions", PressurePage())
#    page = wiz.add_page(u"境界条件（荷重）の設定", LoadEdgePage())
    page = wiz.add_page(qt.QApplication.translate("WizardLinearStaticPlus", "Boundaries conditions (Load to Edges on meshes groups)", None, qt.QApplication.UnicodeUTF8), LoadEdgePage())
    #page.register("edge-loading*", None)
    page.register("edge-loading", None)


class LoadFacePage(WC.WizardPage):
    """Wizard page on Axis loading to Face
    """

    def cleanupPage(self):
        """Clean page in case user navigates"""
        WC.WizardPage.cleanup(self)

    def initializePage(self):
        """Query the model on meshes"""
        WC.WizardPage.initialize(self)
        self.page.use(qt.QVBoxLayout())
        dims = [("FX", 0.), ("FY", 0.)]
        if self.give_field("model").dim == 3:
            dims.append(("FZ", 0.))
        exp = self.give_field("exp-store").give_exp("load_face")
        grps = exp.find_groups(self.give_field("mesh"))
        #dims = [(u"LoadFace", 1.)]
#        tit = u"Adding Load to Edge on meshes groups"
#        tit = u"境界条件（面荷重）を指定するグループ（面）に対して値を設定する"
        tit = qt.QApplication.translate("WizardLinearStaticPlus", "Adding Load to Faces on meshes groups", None, qt.QApplication.UnicodeUTF8)
        # The last groups should be seen first
        grps.reverse()
        #WC.add_condition_selector(self, grps, dims, "face-loading*", tit)
        WC.add_condition_selector(self, grps, dims, "face-loading", tit)


def add_loadface_page(wiz):
    """Add page on pressure loading"""
#    page = wiz.add_page(u"Boundaries conditions", PressurePage())
#    page = wiz.add_page(u"境界条件（荷重）の設定", LoadFacePage())
    page = wiz.add_page(qt.QApplication.translate("WizardLinearStaticPlus", "Boundaries conditions (Load to Faces on meshes groups)", None, qt.QApplication.UnicodeUTF8), LoadFacePage())
    #page.register("face-loading*", None)
    page.register("face-loading", None)


class PressurePage(WC.WizardPage):
    """Wizard page on pressure loading
    """

    def cleanupPage(self):
        """Clean page in case user navigates"""
        WC.WizardPage.cleanup(self)

    def initializePage(self):
        """Query the model on meshes"""
        WC.WizardPage.initialize(self)
        self.page.use(qt.QVBoxLayout())
        exp = self.give_field("exp-store").give_exp("pressure")
        grps = exp.find_groups(self.give_field("mesh"))
        dims = [(u"Pressure", 1.)]
#        tit = u"Adding pressure on meshes groups"
#        tit = u"境界条件（圧力）を指定するグループに対して値を設定する"
        tit = qt.QApplication.translate("WizardLinearStaticPlus", "Adding pressure on meshes groups", None, qt.QApplication.UnicodeUTF8)
        # The last groups should be seen first
        grps.reverse()
        #WC.add_condition_selector(self, grps, dims, "pressure-loading*", tit)
        WC.add_condition_selector(self, grps, dims, "pressure-loading", tit)


def add_pressure_page(wiz):
    """Add page on pressure loading"""
#    page = wiz.add_page(u"Boundaries conditions", PressurePage())
#    page = wiz.add_page(u"境界条件（圧力）の設定", PressurePage())
#qt.QApplication.translate("WizardLinearStaticPlus", "", None, qt.QApplication.UnicodeUTF8)
    page = wiz.add_page(qt.QApplication.translate("WizardLinearStaticPlus", "Boundaries conditions (Pressure)", None, qt.QApplication.UnicodeUTF8), PressurePage())
    #page.register("pressure-loading*", None)
    page.register("pressure-loading", None)


class FinalPage(WC.FinalPage):
    """Build case
    """

    def validatePage(self):
        """Validate the wizard"""
        getf = self.give_field

        comm = LSP.CommWriter()
        comm.use(LSP.Modelisation(getf("model")))
        comm.use(LSP.YoungModulus(self.get_float("young-modulus")))
        comm.use(LSP.PoissonRatio(self.get_float("poisson-ratio")))
        mech_consts = comm.use(LSP.MechConstraints())
        bound_conds = mech_consts.add(LSP.BoundConds())
        mesh = getf("mesh")
        exp = getf("exp-store").give_exp("boundaries")

        if getf("group-boundaries"):
            for cond in getf("group-boundaries"):
                gname = str(cond[0])
                grp_type = exp.give_group_key(mesh, gname)
                bound_conds.add(LSP.DplFromName(grp_type, gname, *cond[1:]))
        else:
            mess = "Warning: You have not defined boundary conditions "
            self._mod.launch(aster_s_gui.INFO, mess)

        opt_fields = [
            ("vertex-loading", LSP.LoadVertex, LSP.LoadVertex),
            ("edge-loading", LSP.LoadEdge, LSP.LoadEdge),
            ("face-loading", LSP.LoadFace, LSP.LoadFace),
            ("pressure-loading", LSP.Pressure, LSP.Pressure),
        ]
        for field_name, csts_cls, cst_cls in opt_fields:
            vals = getf(field_name)
            if not vals:
                continue
            csts = mech_consts.add(csts_cls())
            #pprint(vals, sys.stderr)
            if field_name == "pressure-loading":
                for gname, val in vals:
                    csts.add(LSP.GrpPres(str(gname), val))
            else:
#                for gname, fx_val, fy_val, fz_val in vals:
#                    csts.add(LSP.GrpLoad(str(gname), fx_val, fy_val, fz_val))
                 f_vals = []
                 #print "type(vals[0]) = %s" % type(vals[0])
                 #print "len(vals[0]) = %i" % len(vals[0])
                 #pprint(vals)
                 if len(vals[0]) == 2:
                     print "Check vals 1"
                     for gname, fx_val, fy_val in vals:
                        f_vals = [fx_val, fy_val]
                        csts.add(LSP.GrpLoad(str(gname), f_vals, field_name))
                 #         print "Check (dim2)"
                 #         csts.add(LSP.GrpLoad2(str(gname), fx_val, fy_val))
                 elif len(vals[0]) == 3:
                     print "Check vals 2"
                     for gname, fx_val, fy_val in vals:
                        f_vals = [fx_val, fy_val]
                        csts.add(LSP.GrpLoad(str(gname), f_vals, field_name))
                 #         print "Check (dim2)"
                 #         csts.add(LSP.GrpLoad2(str(gname), fx_val, fy_val))
                 else:
                     print "Check vals 3"
                     for gname, fx_val, fy_val, fz_val in vals:
                        f_vals = [fx_val, fy_val, fz_val]
                        csts.add(LSP.GrpLoad(str(gname), f_vals, field_name))
                 #         print "Check (dim3)"
                 #         csts.add(LSP.GrpLoad3(str(gname), fx_val, fy_val, fz_val))

        #pressure = mech_consts.add(LSP.Pressure())
        #if getf("pressure-loading"):
        #    for gname, val in getf("pressure-loading"):
        #        pressure.add(LSP.GrpPres(str(gname), val))
        #else:
        #    mess = "Warning: You have not defined pressure "
        #    self._mod.launch(aster_s_gui.INFO, mess)
        comm.write(self.get_str("command-file"))
        self.add_case("linear-static-plus")
        return True


def create_wizard(mod):
    """Create the linear static wizard"""
#    wiz = WC.Wizard(u"Isotropic linear elastic study", mod)
    #print "Check3"
    #wiz = WC.Wizard(u"等方性線形弾性材料の応力解析", mod)
    wiz = WC.Wizard(qt.QApplication.translate("WizardLinearStaticPlus", "Isotropic linear elastic study", None, qt.QApplication.UnicodeUTF8), mod)
    WC.add_model_page(wiz, [
        WC.Mode3D,
        WC.PlaneStress,
        WC.PlaneStrain,
        WC.AxisSymmetric,
        ])

    #print "Check4"
    exp_store = WC.ExpStore()
    #print "Check4-1"
    #print WC.ExpStore.smesh
    #print SMeshExp()
    exp_store.register(WC.ExpStore.smesh, SMeshExp())
    #print "Check4-2"
    exp_store.register(WC.ExpStore.geom, GeomExp())
    #print "Check5"
    WC.add_mesh_page(wiz, mod, exp_store)
#    title = u"Young's modulus and Poisson ratio definitions"
#    title = u"ヤング係数とポアソン比の設定"
    title = qt.QApplication.translate("WizardLinearStaticPlus", "Young's modulus and Poisson ratio definitions", None, qt.QApplication.UnicodeUTF8)
    WC.add_material_page(wiz, title, [
        WC.YoungModulus(),
        WC.PoissonRatio(),
    ])
    WC.add_boundaries_page(wiz)
    print "Check Boundaries"
    add_loadvertex_page(wiz)
    print "Check LoadVertex"
    add_loadedge_page(wiz)
    print "Check LoadEdge"
    add_loadface_page(wiz)
    print "Check LoadFace"
    add_pressure_page(wiz)
    print "Check Pressure"
    WC.add_command_file_page(wiz, FinalPage(mod))
    print "Check CommandFile"
    #print "Check6"
    return wiz


