"""
This is an empty docstring.
"""

import numpy as np


class Constraint:
    def __init__(self, free):
        self.free = free # poner dtype boolean

    def is_free(self, c_component):
        return self.free[c_component]

    def print_constraint(self):
        print('{}'.format(self.free))


class Force:
    def __init__(self, force_components):
        self.components = np.array(force_components, dtype='float64')

    def get_component(self, c_component):
        return self.components[c_component]

    def print_force(self):
        print('{}'.format(self.components))



class Node:
    def __init__(self, position):
        self.position = np.array(position, dtype='float64')
        self.displacement = None
        self.constraint = None
        self.forces = None
        self.dof_numbers = None

    def set_displacement(self, new_displacement):
        self.displacement = np.array(new_displacement, dtype='float64')

    def set_constraint(self, new_constraint):
        self.constraint = new_constraint

    def set_force(self, new_force):
        self.force = new_force

    def get_position(self):
        return self.position

    def get_displacement(self):
        return self.displacement

    def get_constraint(self):
        return self.constraint

    def get_force(self):
        return self.force

    def get_dof_numbers(self):
        return self.dof_numbers


    def enumerate_dofs(self, start):
        current_dof = start

        if self.constraint == None:          # corregir esto por un si no existe
            self.dof_numbers = [current_dof, current_dof + 1, current_dof + 2]

        else:
            for i in range(2):
                if self.constraint.is_free(i) == None:  # corregir esto por un si no existe
                    self.dof_numbers[i] = -1
                else:
                    self.dof_numbers[i] = current_dof
                    current_dof = current_dof + 1

        return current_dof

    def print_node(self):
        print('{}'.format(self.position))


class Element:
    """
    """

    def __init__(self, elastic_modulus, area, node_1, node_2):
        self.elastic_modulus = elastic_modulus
        self. area = area
        self.node_1 = node_1
        self.node_2 = node_2
        self.dof_numbers

    def get_elastic_modulus(self):
        return self.elastic_modulus

    def get_area(self):
        return self.area

    def get_node_1(self):
        return self.node_1
    
    def get_node_2(self):
        return self.node_2

    def get_dofs(self):
        return self.dof_numbers


    def compute_stiffness_matrix(self):
        K = np.empty((6, 6), dtype='float64')
        diff = np.empty((3, 1), dtype='float64')
        component_1 = np.empty((3, 3), dtype='float64')
        component_2 = np.empty((3, 3), dtype='float64')

        diff = self.node_2.get_position() - self.node_1.get_position()
        #component_1 =
        #component_2 =
        # other operations

    def enumerate_dofs(self):
        self.dof_numbers = np.concatenate([self.node_1.get_dof_numbers(),
                                           self.node_1.get_dof_numbers()])

    def compute_force(self):
        position_node_1 = self.get_node_1().get_position()
        position_node_2 = self.get_node_2().get_position()
        displacement_node_1 = self.get_node_1().get_displacement()
        displacement_node_2 = self.get_node_2().get_displacement()

        # other operations

    #def get_length(self):

class Visualizer:
    """
    """

    def __init__(self, struct):
        self.struct = struct
        self.displacement_scale
        self.symbol_scale
        self.num_elements = self.struct.get_number_elements()

class Structure:
    """
    """

    def __init__(self,):
        self.nodes = list()
        self.elements = list()
        self.structure_displacement

    def get_node(self, node_id):
        self.nodes[node_id]

    def get_element(self, element_id):
        self.elements[element_id]

    def get_number_elements(self):
        return len(self.elements)

    

    def add_node(self, position_new_node):
        self.nodes.append(Node(position_new_node))
        return self.get_node[-1]

    def add_element(self, elastic_modulus, area, node_1_id, node_2_id):
        self.elements.append(Element(elastic_modulus, area,
                                     self.get_node[node_1_number],
                                     self.get_node[node_2_number],))
        return self.get_element[-1]