import numpy as np

from checkfield import checkfield
from fielddisplay import fielddisplay
from project3d import project3d
from WriteData import WriteData


class giaivins(object):
    """GIA class definition for Ivins and James model

    Usage:
        giaivins = giaivins()
    """

    def __init__(self, *args): #{{{
        self.mantle_viscosity       = np.nan
        self.lithosphere_thickness  = np.nan
        self.cross_section_shape    = 0

        nargin = len(args)
        if nargin == 0:
            self.setdefaultparameters()
        else:
            raise Exception('constructor not supported')
    #}}}

    def __repr__(self): #{{{
        s = '   giaivins parameters:\n'
        s += '{}\n'.format(fielddisplay(self, 'mantle_viscosity', 'mantle viscosity [Pa s]'))
        s += '{}\n'.format(fielddisplay(self, 'lithosphere_thickness', 'lithosphere thickness (km)'))
        s += '{}\n'.format(fielddisplay(self, 'cross_section_shape', "1: square-edged (default). 2: elliptical. See iedge in GiaDeflectionCore"))
        return s
    #}}}

    def setdefaultparameters(self): #{{{
        self.cross_section_shape = 1
        return self
    #}}}

    def checkconsistency(self, md, solution, analyses): #{{{
        if 'GiaAnalysis' not in analyses:
            return md

        md = checkfield(md, 'fieldname', 'gia.mantle_viscosity', 'NaN', 1, 'Inf', 1, 'size', [md.mesh.numberofvertices], '>', 0)
        md = checkfield(md, 'fieldname', 'gia.lithosphere_thickness', 'NaN', 1, 'Inf', 1, 'size', [md.mesh.numberofvertices], '>', 0)
        md = checkfield(md, 'fieldname', 'gia.cross_section_shape', 'numel', [1], 'values', [1, 2])

        # Be sure that if we are running a masstransport ice flow model coupled 
        # with giaivins, that thickness forcings are not provided into the 
        # future.
        if solution == 'TransientSolution' and md.transient.ismasstransport and md.transient.isgia:
            # Figure out if thickness is a transient forcing
            if md.geometry.thickness.shape[0] == md.mesh.numberofvertices + 1:
                # Recover the furthest time "in time"
                if md.geometry.thickness[-1, -1] != md.timestepping.start_time:
                    md.checkmessage('if masstransport is on, transient thickness forcing for the giaivins model should not be provided in the future. Synchronize your start_time to correspond to the most recent transient thickness forcing timestep')
        return md
    #}}}

    def marshall(self, prefix, md, fid): #{{{
        WriteData(fid, prefix, 'name', 'md.gia.model', 'data', 1, 'format', 'Integer')
        WriteData(fid, prefix, 'object', self, 'fieldname', 'mantle_viscosity', 'format', 'DoubleMat', 'mattype', 1)
        WriteData(fid, prefix, 'object', self, 'fieldname', 'lithosphere_thickness', 'format', 'DoubleMat', 'mattype', 1, 'scale', 10.**3.)
        WriteData(fid, prefix, 'object', self, 'fieldname', 'cross_section_shape', 'format', 'Integer')
    #}}}

    def extrude(self, md): #{{{
        self.mantle_viscosity = project3d(md, 'vector', self.mantle_viscosity, 'type', 'node')
        self.lithosphere_thickness = project3d(md, 'vector', self.lithosphere_thickness, 'type', 'node')
        return self
    #}}}
