#! /usr/bin/python

# 6ta Practica Laboratorio 
# Complementos Matematicos I
# Consigna: Implementar los siguientes metodos

# Para descargar py-gnuplot: http://sourceforge.net/projects/gnuplot-py/files/latest/download?source=files

import argparse
import Gnuplot

# Para testing
# TODO: Borrar
grafo1 = ([1, 2, 3, 4, 5, 6, 7], 
          [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 1)])


class LayoutGraph:
    
    def __init__(self, grafo, iters, refresh, c1, c2, verbose=False):
        '''    
        Parametros de layout:
        iters: cantidad de iteraciones a realizar
        refresh: Numero de iteraciones entre actualizaciones de pantalla. 
        0 -> se grafica solo al final.
        c1: constante usada para calcular la repulsion entre nodos
        c2: constante usada para calcular la atraccion de aristas
        '''

        # Guardo el grafo
        self.grafo = grafo

        # Inicializo estado
        # Falta...
        self.posiciones = {}
        self.fuerzas = {}        
        
        # Guardo opciones
        self.iters = iters
        self.verbose = verbose
        # faltan...
        self.refresh = 0
        self.c1 = 1.0
        self.c2 = 2.5


    def randomize(self):
        ''' Inicializa en forma aleatoria las posiciones de los nodos'''
        pass


    def step(self):
        ''' Efectua un paso de la simulacion fisica y actualiza las posiciones de los nodos'''

        # 1: Calcular repulsiones de nodos (actualiza fuerzas)
        # 2: Calcular atracciones de aristas (actualiza fuerzas)
        # 3: Calcular fuerza de gravedad (opcional)
        # 4: En base a fuerzas, actualizar posiciones, setear fuerzas a cero
        pass


    def dibujar(self):
        ''' Dibuja (o actualiza) el estado del grafo gr en pantalla'''
        pass


    def layout(self):
        '''
        Aplica el algoritmo de Fruchtermann-Reingold para obtener (y mostrar) 
        un layout        
        '''

        # Inicializamos las posiciones
        self.randomize()

        # Si es necesario, lo mostramos por pantalla
        if (self.refresh > 0):
            self.dibujar()

        # Bucle principal
        for i in range(0, self.iters):
            # Realizar un paso de la simulacion
            self.step()
                
            # Si es necesario, lo mostramos por pantalla
            if (self.refresh > 0 and i % self.refresh == 0):
                self.dibujar()
        
        # Ultimo dibujado al final
        self.dibujar()


def main():
    # Definimos los argumentos de lina de comando que aceptamos
    parser = argparse.ArgumentParser()

    # Verbosidad, opcional, False por defecto
    parser.add_argument('-v', '--verbose', 
                        action='store_true', 
                        help='Muestra mas informacion')
    # Cantidad de iteraciones, opcional, 50 por defecto
    parser.add_argument('--iters', type=int, 
                        help='Cantidad de iteraciones a efectuar', 
                        default=50)

    args = parser.parse_args()

    #     Descomentar abajo para ver funcionamiento de argparse
    #     print args.iters
    #     print args.verbose
    #     return

    # Creamos nuestro objeto LayoutGraph
    layout_gr = LayoutGraph(
        grafo1,  # Cambiar!!!
        iters=args.iters,
        refresh=1,
        c1=2.0,
        c2=2.5,
        verbose=args.verbose
        )
    
    # Ejecutamos el layout
    layout_gr.layout()
    return


if __name__ == '__main__':
    main()
