# This file was automatically generated by SWIG (https://www.swig.org).
# Version 4.1.1
#
# Do not make changes to this file unless you know what you are doing - modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _polefigure
else:
    import _polefigure

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "this":
            set(self, name, value)
        elif name == "thisown":
            self.this.own(value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


import ooflib.SWIG.engine.crystalsymmetry
import ooflib.SWIG.common.direction
class PoleFigure(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, arg2, arg3, arg4, arg5, arg6, arg7):
        _polefigure.PoleFigure_swiginit(self, _polefigure.new_PoleFigure(arg2, arg3, arg4, arg5, arg6, arg7))

    def getValue(self, arg2, arg3):
        return _polefigure.PoleFigure_getValue(self, arg2, arg3)

    def inside(self, arg2, arg3):
        return _polefigure.PoleFigure_inside(self, arg2, arg3)

    def getBinSize(self):
        return _polefigure.PoleFigure_getBinSize(self)

    def nCounts(self):
        return _polefigure.PoleFigure_nCounts(self)

    def minValue(self):
        return _polefigure.PoleFigure_minValue(self)

    def maxValue(self):
        return _polefigure.PoleFigure_maxValue(self)
    __swig_destroy__ = _polefigure.delete_PoleFigure

# Register PoleFigure in _polefigure:
_polefigure.PoleFigure_swigregister(PoleFigure)
# -*- python -*-

# This software was produced by NIST, an agency of the U.S. government,
# and by statute is not subject to copyright in the United States.
# Recipients of this software assume all responsibilities associated
# with its operation, modification and maintenance. However, to
# facilitate maintenance we ask that before distributing modified
# versions of this software, you first contact the authors at
# oof_manager@nist.gov. 

from ooflib.SWIG.common import direction
from ooflib.SWIG.common import ooferror
from ooflib.SWIG.engine import crystalsymmetry
from ooflib.common import color
from ooflib.common import debug
from ooflib.common import enum
from ooflib.common import primitives
from ooflib.common.IO import automatic
from ooflib.common.IO import colormap
from ooflib.common.IO import filenameparam
from ooflib.common.IO import oofmenu
from ooflib.common.IO import parameter
from ooflib.common.IO import pixelgroupparam
from ooflib.common.IO import placeholder
from ooflib.common.IO import whoville
from ooflib.orientationmap import orientmapmenu
import ooflib.common.microstructure
import os.path

import oofcanvas

def _makePoleFigure(menuitem, microstructure, pixels, symmetry,
                    pole, nBins,
                    min, max, colormap, size,
                    filename, overwrite):

# hemisphere==True means limit the plot to one hemisphere.  This
# was briefly a settable parameter until we learned that there are
# different ways of combining the hemispheres.  It's not clear
# what the best long term strategy is.
    hemisphere = True

    if os.path.exists(filename) and not overwrite:
        return

    mscontext = ooflib.common.microstructure.microStructures[microstructure]
    ms = mscontext.getObject()
    mscontext.begin_reading()
    try:
        pxls = placeholder.getPlaceHolderFromString(pixels)
        if pxls == placeholder.every:
            group = None        # hack. PoleFigure ctor assumes 0 ==> all
        elif pxls == placeholder.selection:
            group = ms.pixelselection.getSelectionAsGroup()
        else:
            group = ms.findGroup(pixels)
            if group is None:
                raise ooferror.ErrUserError("There is no group named %s!",
                                            pixels)

# Compile the data
        pfig = PoleFigure(ms, group, symmetry, pole.cdirection,
                          nBins, hemisphere)
        if pfig.nCounts() == 0:
            raise ooferror.ErrUserError(
                "No orientations detected!  Are Materials defined, "
                "and do they have an Orientation property?")

        if max == automatic.automatic:
            dmax = pfig.maxValue()
        else:
            dmax = float(max)
        if min == automatic.automatic:
            dmin = pfig.minValue()
        else:
            dmin = float(min)
        drange = dmax - dmin
        if drange != 0:
            factor = 1./drange
        else:
            factor = 1.
        offset = -dmin*factor
        binSize = pfig.getBinSize()

# Create the plot
        ppu = size/4.
        canvas = oofcanvas.OffScreenCanvas(ppu) 
        layer = canvas.newLayer("polefigure")
        for i in range(nBins):
            for j in range(nBins):
                if pfig.inside(i, j):
                    val = pfig.getValue(i, j)
                    clr = color.canvasColor(colormap(offset + val*factor))
                    poly = oofcanvas.CanvasPolygon.create()
                    poly.setFillColor(clr)
                    poly.addPoint((i*binSize, j*binSize))
                    poly.addPoint(((i+1)*binSize, j*binSize))
                    poly.addPoint(((i+1)*binSize, (j+1)*binSize))
                    poly.addPoint((i*binSize, (j+1)*binSize))
                    layer.addItem(poly)

        maxpix = size
        canvas.saveAsPDF(filename, maxpix, False)
# pdfout.end_layer()
# pdfout.show()
    finally:
        mscontext.end_reading()

orientmapmenu.orientmapmenu.addItem(
    oofmenu.OOFMenuItem(
        'Pole_Figure',
        callback=_makePoleFigure,
        ordering=100,
        params=[
            whoville.WhoParameter(
                "microstructure", whoville.getClass('Microstructure'),
                tip='The Microstructure from which to generate a pole figure.'),
            pixelgroupparam.PixelAggregateParameter(
                'pixels', value=placeholder.every.IDstring,
                tip="Pixels to include in the pole figure."),
            enum.EnumParameter(
                "symmetry", crystalsymmetry.AnisoCrystalSymmetry,
                tip="The crystal symmetry to assume for each pixel."
                " All equivalent orientations will be included."),
            parameter.ConvertibleRegisteredParameter(
                "pole", direction.Direction, direction.AngleDirection(0, 0),
                tip="The pole to plot."),
            parameter.IntParameter(
                "nBins", 30,
                tip="The number of bins to use in the x and y directions"
                " in the projected plot."
                ),
            parameter.AutoNumericParameter(
                "min", 0,
                tip="Minimum value to plot (MRD), or 'automatic'"),
            parameter.AutoNumericParameter(
                "max", automatic.automatic,
                tip="Maximum value to plot (MRD), or 'automatic'"),
            parameter.RegisteredParameter(
                "colormap", colormap.ColorMap,
                tip="How MRD values are converted to colors."),
            parameter.IntParameter(
                "size", 500,
                tip="Size of the plot (number of pixels along an edge)."),
            filenameparam.WriteFileNameParameter(
                "filename", ident="polefigure",
                tip="The name of the pdf file to create."),
            filenameparam.OverwriteParameter(
                "overwrite",
                tip="Overwrite an existing file?"),
            ],
        help="Plot a pole figure for a microstructure.",
        discussion="""<para>Plot a pole figure for the given
        Microstructure as a pdf file.</para>"""
        )
    )


