"""
@package nviz.workspace

@brief wxNviz workspace settings

Classes:
 - workspace::NvizSettings

(C) 2007-2011 by the GRASS Development Team

This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.

@author Anna Kratochvilova <kratochanna gmail.com> (wxNviz / Google SoC 2011)
"""

import copy
import six

from core.settings import UserSettings

try:
    from nviz import wxnviz
except ImportError:
    wxnviz = None


class NvizSettings(object):
    def __init__(self):
        pass

    def SetConstantDefaultProp(self):
        """Set default constant data properties"""
        data = dict()
        for key, value in six.iteritems(UserSettings.Get(group="nviz", key="constant")):
            data[key] = value
        color = (
            str(data["color"][0])
            + ":"
            + str(data["color"][1])
            + ":"
            + str(data["color"][2])
        )
        data["color"] = color

        return data

    def SetSurfaceDefaultProp(self, data=None):
        """Set default surface data properties"""
        if not data:
            data = dict()
        for sec in ("attribute", "draw", "mask", "position"):
            data[sec] = {}

        #
        # attributes
        #
        for attrb in ("shine",):
            data["attribute"][attrb] = {}
            for key, value in six.iteritems(
                UserSettings.Get(group="nviz", key="surface", subkey=attrb)
            ):
                data["attribute"][attrb][key] = value
            data["attribute"][attrb]["update"] = None

        #
        # draw
        #
        data["draw"]["all"] = False  # apply only for current surface
        for control, value in six.iteritems(
            UserSettings.Get(group="nviz", key="surface", subkey="draw")
        ):
            if control[:3] == "res":
                if "resolution" not in data["draw"]:
                    data["draw"]["resolution"] = {}
                if "update" not in data["draw"]["resolution"]:
                    data["draw"]["resolution"]["update"] = None
                data["draw"]["resolution"][control[4:]] = value
                continue

            if control == "wire-color":
                value = str(value[0]) + ":" + str(value[1]) + ":" + str(value[2])
            elif control in ("mode", "style", "shading"):
                if "mode" not in data["draw"]:
                    data["draw"]["mode"] = {}
                continue

            data["draw"][control] = {"value": value}
            data["draw"][control]["update"] = None

        value, desc = self.GetDrawMode(
            UserSettings.Get(group="nviz", key="surface", subkey=["draw", "mode"]),
            UserSettings.Get(group="nviz", key="surface", subkey=["draw", "style"]),
            UserSettings.Get(group="nviz", key="surface", subkey=["draw", "shading"]),
        )

        data["draw"]["mode"] = {"value": value, "desc": desc, "update": None}
        # position
        for coord in ("x", "y", "z"):
            data["position"][coord] = UserSettings.Get(
                group="nviz", key="surface", subkey=["position", coord]
            )
        data["position"]["update"] = None

        return data

    def SetVolumeDefaultProp(self):
        """Set default volume data properties"""
        data = dict()
        for sec in ("attribute", "draw", "position"):
            data[sec] = dict()
            for sec in ("isosurface", "slice"):
                data[sec] = list()

        #
        # draw
        #
        for control, value in six.iteritems(
            UserSettings.Get(group="nviz", key="volume", subkey="draw")
        ):
            if control == "shading":
                sel = UserSettings.Get(
                    group="nviz", key="volume", subkey=["draw", "shading"]
                )
                value, desc = self.GetDrawMode(shade=sel, string=False)

                data["draw"]["shading"] = {}
                data["draw"]["shading"]["isosurface"] = {
                    "value": value,
                    "desc": desc["shading"],
                }
                data["draw"]["shading"]["slice"] = {
                    "value": value,
                    "desc": desc["shading"],
                }
            elif control == "mode":
                sel = UserSettings.Get(
                    group="nviz", key="volume", subkey=["draw", "mode"]
                )
                if sel == 0:
                    desc = "isosurface"
                else:
                    desc = "slice"
                data["draw"]["mode"] = {
                    "value": sel,
                    "desc": desc,
                }
            elif control == "box":
                box = UserSettings.Get(
                    group="nviz", key="volume", subkey=["draw", "box"]
                )
                data["draw"]["box"] = {"enabled": box}

            else:
                data["draw"][control] = {}
                data["draw"][control]["isosurface"] = {"value": value}
                data["draw"][control]["slice"] = {"value": value}

            if "update" not in data["draw"][control]:
                data["draw"][control]["update"] = None

        #
        # isosurface attributes
        #
        for attrb in ("shine",):
            data["attribute"][attrb] = {}
            for key, value in six.iteritems(
                UserSettings.Get(group="nviz", key="volume", subkey=attrb)
            ):
                data["attribute"][attrb][key] = value

        return data

    def SetIsosurfaceDefaultProp(self):
        """Set default isosurface properties"""
        data = dict()
        for attr in ("shine", "topo", "transp", "color", "inout"):
            data[attr] = {}
            data[attr]["update"] = None
            if attr == "inout":
                data[attr]["value"] = 0
                continue
            for key, value in six.iteritems(
                UserSettings.Get(group="nviz", key="volume", subkey=attr)
            ):
                data[attr][key] = value
        return data

    def SetSliceDefaultProp(self):
        """Set default slice properties"""
        data = dict()
        data["position"] = copy.deepcopy(
            UserSettings.Get(group="nviz", key="volume", subkey="slice_position")
        )
        data["position"]["update"] = None

        data["transp"] = copy.deepcopy(
            UserSettings.Get(group="nviz", key="volume", subkey="transp")
        )
        return data

    def SetVectorDefaultProp(self, longDim, data=None):
        """Set default vector data properties"""
        if not data:
            data = dict()
        for sec in ("lines", "points"):
            data[sec] = {}

        self.SetVectorLinesDefaultProp(data["lines"])
        self.SetVectorPointsDefaultProp(data["points"], longDim)

        return data

    def SetVectorLinesDefaultProp(self, data):
        """Set default vector properties -- lines"""
        # width
        data["width"] = {
            "value": UserSettings.Get(
                group="nviz", key="vector", subkey=["lines", "width"]
            )
        }

        # color
        value = UserSettings.Get(group="nviz", key="vector", subkey=["lines", "color"])
        color = str(value[0]) + ":" + str(value[1]) + ":" + str(value[2])
        data["color"] = {"value": color}

        # mode
        if UserSettings.Get(group="nviz", key="vector", subkey=["lines", "flat"]):
            type = "flat"

        else:
            type = "surface"

        data["mode"] = {}
        data["mode"]["type"] = type
        data["mode"]["update"] = None

        # height
        data["height"] = {
            "value": UserSettings.Get(
                group="nviz", key="vector", subkey=["lines", "height"]
            )
        }
        # thematic
        data["thematic"] = {
            "rgbcolumn": UserSettings.Get(
                group="nviz", key="vector", subkey=["lines", "rgbcolumn"]
            ),
            "sizecolumn": UserSettings.Get(
                group="nviz", key="vector", subkey=["lines", "sizecolumn"]
            ),
            "layer": 1,
            "usecolor": False,
            "usewidth": False,
        }
        if "object" in data:
            for attrb in ("color", "width", "mode", "height", "thematic"):
                data[attrb]["update"] = None

    def SetVectorPointsDefaultProp(self, data, longDim):
        """Set default vector properties -- points"""
        size_fraction = 0.005
        # size
        autosize = UserSettings.Get(
            group="nviz", key="vector", subkey=["points", "autosize"]
        )
        if autosize:
            data["size"] = {"value": longDim * size_fraction}
        else:
            data["size"] = {
                "value": UserSettings.Get(
                    group="nviz", key="vector", subkey=["points", "size"]
                )
            }

        # width
        data["width"] = {
            "value": UserSettings.Get(
                group="nviz", key="vector", subkey=["points", "width"]
            )
        }

        # marker
        data["marker"] = {
            "value": UserSettings.Get(
                group="nviz", key="vector", subkey=["points", "marker"]
            )
        }

        # color
        value = UserSettings.Get(group="nviz", key="vector", subkey=["points", "color"])
        color = str(value[0]) + ":" + str(value[1]) + ":" + str(value[2])
        data["color"] = {"value": color}

        # mode
        data["mode"] = {"type": "surface"}
        # 'surface' : '', }

        # height
        data["height"] = {
            "value": UserSettings.Get(
                group="nviz", key="vector", subkey=["points", "height"]
            )
        }

        data["thematic"] = {
            "rgbcolumn": UserSettings.Get(
                group="nviz", key="vector", subkey=["points", "rgbcolumn"]
            ),
            "sizecolumn": UserSettings.Get(
                group="nviz", key="vector", subkey=["points", "sizecolumn"]
            ),
            "layer": 1,
            "usecolor": False,
            "usesize": False,
        }
        if "object" in data:
            for attrb in ("size", "width", "marker", "color", "height", "thematic"):
                data[attrb]["update"] = None

    def GetDrawMode(self, mode=None, style=None, shade=None, string=False):
        """Get surface draw mode (value) from description/selection

        :param mode:
        :param style:
        :param shade:
        :param string: if True input parameters are strings otherwise
                       selections
        """
        if not wxnviz:
            return None

        value = 0
        desc = {}

        if string:
            if mode is not None:
                if mode == "coarse":
                    value |= wxnviz.DM_WIRE
                elif mode == "fine":
                    value |= wxnviz.DM_POLY
                else:  # both
                    value |= wxnviz.DM_WIRE_POLY

            if style is not None:
                if style == "wire":
                    value |= wxnviz.DM_GRID_WIRE
                else:  # surface
                    value |= wxnviz.DM_GRID_SURF

            if shade is not None:
                if shade == "flat":
                    value |= wxnviz.DM_FLAT
                else:  # surface
                    value |= wxnviz.DM_GOURAUD

            return value

        # -> string is False
        if mode is not None:
            if mode == 0:  # coarse
                value |= wxnviz.DM_WIRE
                desc["mode"] = "coarse"
            elif mode == 1:  # fine
                value |= wxnviz.DM_POLY
                desc["mode"] = "fine"
            else:  # both
                value |= wxnviz.DM_WIRE_POLY
                desc["mode"] = "both"

        if style is not None:
            if style == 0:  # wire
                value |= wxnviz.DM_GRID_WIRE
                desc["style"] = "wire"
            else:  # surface
                value |= wxnviz.DM_GRID_SURF
                desc["style"] = "surface"

        if shade is not None:
            if shade == 0:
                value |= wxnviz.DM_FLAT
                desc["shading"] = "flat"
            else:  # surface
                value |= wxnviz.DM_GOURAUD
                desc["shading"] = "gouraud"

        return (value, desc)

    def SetDecorDefaultProp(self, type):
        """Set default arrow properties"""
        data = {}

        # arrow
        if type == "arrow":
            data["arrow"] = copy.deepcopy(UserSettings.Get(group="nviz", key="arrow"))
            data["arrow"]["color"] = "%d:%d:%d" % (
                UserSettings.Get(group="nviz", key="arrow", subkey="color")[:3]
            )
            data["arrow"].update(
                copy.deepcopy(
                    UserSettings.Get(
                        group="nviz", key="arrow", settings_type="internal"
                    )
                )
            )
            data["arrow"]["show"] = False

        # arrow
        if type == "scalebar":
            data["scalebar"] = copy.deepcopy(
                UserSettings.Get(group="nviz", key="scalebar")
            )
            data["scalebar"]["color"] = "%d:%d:%d" % (
                UserSettings.Get(group="nviz", key="scalebar", subkey="color")[:3]
            )
            data["scalebar"].update(
                copy.deepcopy(
                    UserSettings.Get(
                        group="nviz", key="scalebar", settings_type="internal"
                    )
                )
            )
            data["scalebar"]["id"] = 0
        return data
