# -*- coding: utf-8 -*-
"""Qt wizard on linear thermic study case
"""
"""
    modified by Takeru who belongs
    to Japanese Localization Subcommittee in JSWG (Japan Salome-Meca Working Group)
    on Mar 12 2014
"""

from PyQt4 import QtGui as qt

import aster_s.salome_tree as ST
from aster_s.wizards import linear_thermic as LT

import aster_s_gui.wizards.common as WC


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

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

        exp = SMesh()
        grp = exp.add_group(LT.GRP_NO)
        grp.register((2, 3), [SMesh.node])
        grp = exp.add_group(LT.GRP_MA)
        grp.register((2, 3), [SMesh.edge, SMesh.face])
        grp.register((3,), [SMesh.volume])
        self.register("imposed-temps", exp)

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

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

    def validate(self, mesh, mod):
        """Validate the mesh"""
        return WC.at_least_a_group(self.give("imposed-temps"), mesh, mod)


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

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

        exp = Geom()
        grp = exp.add_group(LT.GRP_NO)
        grp.register((2, 3), [Geom.vertex])
        grp = exp.add_group(LT.GRP_MA)
        grp.register((2, 3), [Geom.face, Geom.shell])
        grp.register((2,), [Geom.edge])
        grp.register((3,), [Geom.solid, Geom.compsolid])
        self.register("imposed-temps", exp)

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

        exp = Geom()
        grp = exp.add_group("source")
        grp.register((2,), [Geom.face, Geom.shell])
        grp.register((3,), [Geom.solid, Geom.compsolid])
        self.register("source", exp)

    def validate(self, mesh, mod):
        """Validate the mesh"""
        return WC.at_least_a_group(self.give("imposed-temps"), mesh, mod)


class ThermalConductance(WC.Param):
    """Thermal conductance coefficient
    """

    def __init__(self, dft="0.54"):
        self._dft = dft
        self.rangev = (0., 1e100)
        self.decs_nb = 10
        lamda_symb = u"\N{GREEK SMALL LETTER LAMDA}"
#        self.title = u"Thermal conductivity (%s)" % lamda_symb
#        self.title = u"熱伝導率 (%s)" % lamda_symb
        self.title = qt.QApplication.translate("WizardLinearThermic", "Thermal conductivity", None, qt.QApplication.UnicodeUTF8)
        self.title += " (%s)" % lamda_symb
        self.suffix = u"(%s > 0)" % lamda_symb

    def add_to(self, page, grid, ridx):
        """Add to page and grid"""
        grid.addWidget(qt.QLabel(self.title), ridx, 0)
        minv, maxv = self.rangev
        entry = WC.create_entry(WC.Double(minv, maxv, self.decs_nb))
        page.register_qt_field("th-conduct*", entry)
        entry.setText(self._dft)
        grid.addWidget(entry, ridx, 1)
        grid.addWidget(qt.QLabel(self.suffix), ridx, 2)


class TempPage(WC.WizardPage):
    """Page for defining imposed temperatures
    """

    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 = [("T", 0.)]
        exp = self.give_field("exp-store").give_exp("imposed-temps")
        lst = exp.find_groups(self.give_field("mesh"))
#        tit = u"Adding imposed temperatures on groups" 
#        tit = u"境界条件（温度）を指定するグループに対して値を設定する" 
        tit = qt.QApplication.translate("WizardLinearThermic", "Adding imposed temperatures on groups", None, qt.QApplication.UnicodeUTF8)
        WC.add_condition_selector(self, lst, dims, "bound-temps*", tit)


def add_imposed_temps_page(wiz):
    """Add page on imposed temperatures"""
#    page = wiz.add_page(u"Boundaries conditions", TempPage())
#    page = wiz.add_page(u"境界条件（温度）の設定", TempPage())
    page = wiz.add_page(qt.QApplication.translate("WizardLinearThermic", "Boundaries conditions (tempratures)", None, qt.QApplication.UnicodeUTF8), TempPage())
    page.register("bound-temps*", None)


class StreamPage(WC.WizardPage):
    """Page for defining streams normal to a 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())
        exp = self.give_field("exp-store").give_exp("stream")
        grps = exp.find_groups(self.give_field("mesh"))
        dims = [("Stream", 0.)]
#        tit = u"Adding streams normal to a face (optional)"
#        tit = u"境界条件（熱流束）を指定するグループに対して値を設定する"
        tit = qt.QApplication.translate("WizardLinearThermic", "Adding streams normal to a face (optional)", None, qt.QApplication.UnicodeUTF8)
        WC.add_condition_selector(self, grps, dims, "normal-streams", tit)


def add_normal_streams_page(wiz):
    """Add page on streams normal to a face"""
#    page = wiz.add_page(u"Boundaries conditions", StreamPage())
#    page = wiz.add_page(u"境界条件（熱流束）の設定", StreamPage())
#    page = qt.QApplication.translate("WizardLinearThermic", "Boundaries conditions (streams)", None, qt.QApplication.UnicodeUTF8)
    page = wiz.add_page(qt.QApplication.translate("WizardLinearThermic", "Boundaries conditions (streams)", None, qt.QApplication.UnicodeUTF8), StreamPage())
    page.register("normal-streams", None)


class VolumicPage(WC.WizardPage):
    """Page for selecting volumic sources
    """

    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("source")
        grps = exp.find_groups(self.give_field("mesh"))
        dims = [("Source", 0.)]
#        tit = u"Adding volumic sources (optional)"
#        tit = u"境界条件（熱源）を指定するグループに対して値を設定する"
        tit = qt.QApplication.translate("WizardLinearThermic", "Adding volumic sources (optional)", None, qt.QApplication.UnicodeUTF8)
        WC.add_condition_selector(self, grps, dims, "volumic-sources", tit)


def add_volumic_sources_page(wiz):
    """Add page on volumic sources"""
#    page = wiz.add_page(u"Boundaries conditions", VolumicPage())
#    page = wiz.add_page(u"境界条件（熱源）の設定", VolumicPage())
#    page = qt.QApplication.translate("WizardLinearThermic", "Boundaries conditions (sources)", None, qt.QApplication.UnicodeUTF8)
    page = wiz.add_page(qt.QApplication.translate("WizardLinearThermic", "Boundaries conditions (sources)", None, qt.QApplication.UnicodeUTF8), VolumicPage())
    page.register("volumic-sources", None)


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

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

        comm = LT.CommWriter()
        comm.use(LT.Modelisation(getf("model")))
        comm.use(LT.ThermalConductance(self.get_float("th-conduct")))
        th_consts = comm.use(LT.ThermalConstraints())

        temp_conds = th_consts.add(LT.TempConds())
        mesh = getf("mesh")
        exp = getf("exp-store").give_exp("imposed-temps")
        for gname, temp in getf("bound-temps"):
            gname = str(gname)
            grp_type = exp.give_group_key(mesh, gname)
            temp_conds.add(LT.TempImpo(grp_type, gname, temp))

        opt_fields = [
            ("normal-streams", LT.NormalStreams, LT.NormalStream),
            ("volumic-sources", LT.VolSources, LT.VolSource),
        ]
        for field_name, csts_cls, cst_cls in opt_fields:
            vals = getf(field_name)
            if not vals:
                continue
            csts = th_consts.add(csts_cls())
            for gname, val in vals:
                csts.add(cst_cls(gname, val))

        comm.write(self.get_str("command-file"))

        self.add_case("linear-thermic")
        return True


def create_wizard(mod):
    """Create the linear thermic wizard"""
#    wiz = WC.Wizard(u"Linear thermal analysis", mod)
#    wiz = WC.Wizard(u"線形熱伝導解析", mod)
    wiz = WC.Wizard(qt.QApplication.translate("WizardLinearThermic", "Linear thermal analysis", None, qt.QApplication.UnicodeUTF8), mod)
    WC.add_model_page(wiz, [
        WC.Mode3D,
        WC.Plane,
        ])
    exp_store = WC.ExpStore()
    exp_store.register(WC.ExpStore.smesh, SMeshExp())
    exp_store.register(WC.ExpStore.geom, GeomExp())
    WC.add_mesh_page(wiz, mod, exp_store)
#    title = u"Thermal conductivity definition"
#    title = u"熱伝導率の設定"
    #qt.QApplication.translate("WizardLinearThermic", "", None, qt.QApplication.UnicodeUTF8)
    title = qt.QApplication.translate("WizardLinearThermic", "Thermal conductivity definition", None, qt.QApplication.UnicodeUTF8)
    WC.add_material_page(wiz, title, [
        ThermalConductance(),
    ])
    add_imposed_temps_page(wiz)
    add_normal_streams_page(wiz)
    add_volumic_sources_page(wiz)
    WC.add_command_file_page(wiz, FinalPage(mod))
    return wiz


