from abaqus import *
from abaqusConstants import *
import section
import regionToolset
import part
import material
import sketch
from Parts import GeometryBuilder as gb


def centrosome( **kwargs ):
    """
    Creates a centrosome part object, assigns material and section

    :param kwargs: model parameters

    :type kwargs: dict

    :return: centrosome part

    :rtype: object
    """
    # Create Centrosome sketch
    l = kwargs['CentrosomeLength']
    r = kwargs['CentrosomeRadius']

    s = gb.create_centrosome_sketch(l, r, **kwargs)

    # Create Centrosome part
    p = gb.create_centrosome_part(s, 'centrosome', **kwargs)

    # Define material
    # CentrosomeE -> Elastic modulus of MT material
    # CentrosomeNu -> Poisson ratio of MT material

    ElasticModulus = kwargs['CentrosomeE']
    PoissonRatio = kwargs['CentrosomeNu']
    gb.define_material('centrosome_material', ElasticModulus, PoissonRatio, **kwargs)

    # Define section
    modelname = kwargs['modelname']
    mdb.models[modelname].HomogeneousSolidSection(
        name='centrosome-section',
        material='centrosome_material',
        thickness=None)

    # Assign section
    gb.assign_centrosome_section(p, 'centrosome', 'centrosome-section', **kwargs)
    return p


def microtubule( type, l, i, **kwargs ):
    """
    Creates a microtubule part object and assigns material and section

    :param type: Either aMT or ipMT

    :type type: str

    :param l: Length of the microtubule

    :type l: float

    :param i: Sequential index of the microtubule

    :type i: int

    :param kwargs: model parameters

    :type kwargs: dict

    :return: Null

    :rtype: Null
    """
    # Create part
    p, MTname = gb.create_MT_part(l, type, i, **kwargs)

    # Define material
    # ElasticModulus -> Elastic modulus of MT material
    # PoissonRatio -> Poisson ratio of MT material

    ElasticModulus = kwargs['ElasticModulus']
    PoissonRatio = kwargs['PoissonRatio']
    gb.define_material('MT_material', ElasticModulus, PoissonRatio, **kwargs)

    # Define pipe-like profile
    # r1 -> inner radius of MT
    # r2 -> outer radius of MT

    modelname = kwargs['modelname']
    r1 = kwargs['d']/2
    r2 = kwargs['D']/2
    mdb.models[modelname].PipeProfile(
        name='MT-profile',
        r=r2, t=(r2 - r1) / 2,
        formulation=THICK_WALL)

    # Define section
    gb.create_section('MT-section', 'MT-profile', 'MT_material', **kwargs)

    # Assign section
    gb.assign_MT_section(p, MTname, **kwargs)

    # Assign beam section orientation
    gb.assign_MT_section_orientation(MTname, **kwargs)


def connector( i, length, connectorname, **kwargs ):
    """
    Creates a connector part object and assigns material and section

    :param i: Sequential number of the connector

    :type i: int

    :param length: Length of the connector

    :type length: float

    :param connectorname: Name of the connector

    :type connectorname: str

    :param kwargs: model parameters

    :type kwargs: dict

    :return: Null

    :rtype: Null
    """
    # Create part
    p = gb.create_connector_part(connectorname, length, **kwargs)

    # Define circular profile and section
    '''
    r -> radius of a connector beam
    E -> Elastic modulus of connector material
    nu -> Poisson ratio of connector material
    '''
    r = kwargs['connectorRadius']
    modelname = kwargs['modelname']
    mdb.models[modelname].CircularProfile(name='connector-profile', r=r)
    E = kwargs['connectorE']
    nu = kwargs['connectorNu']
    gb.define_material('connector_material', E, nu, **kwargs)
    sectionName = 'connector-section'
    sectionProfile = 'connector-profile'
    sectionMaterial = 'connector_material'
    gb.create_section(sectionName, sectionProfile, sectionMaterial, **kwargs)

    # Assign beam section
    region = gb.assign_connector_section(p, 'connector-section', **kwargs)

    # Assign beam section orientation
    p.assignBeamSectionOrientation(
        region=region,
        method=N1_COSINES,
        n1=(0.0, 0.0, -1.0))
