package elaprendiz.estructuras.funciones;

import elaprendiz.graficos.funciones.Funcion;

import java.awt.Point;

import java.util.Observer;
import java.util.Observable;

import elaprendiz.estructuras.nodos.ArbolNodo;
import elaprendiz.estructuras.EstructuraLienzo;
import elaprendiz.estructuras.LienzoBinario;

public class ContratoArbol extends Funcion implements Observer {

  boolean bloqueado = false;

  public ContratoArbol(LienzoBinario canvas) {
    int level = canvas.getLevel();

    int[] values;

    for (int i = 0; i < level; i++) {
      values = canvas.getLevelValues(i);

      if (values[2] == LienzoBinario.LEVEL_TWO) {
	values[0] = (int) (values[1] / 2);
	values[1] = values[1] * 2;
	values[2] = LienzoBinario.LEVEL_ONE;
      }
      else {
	values[0] = (int) (values[0] / 2);

	if (values[0] == values[1])
	  values[2] = LienzoBinario.LEVEL_TWO;
      }

      canvas.setLevelValues(i, values);
    }

    ArbolNodo parent;
    ArbolNodo leftChild;
    ArbolNodo rightChild;

    int startCheck;
    int endCheck;

    int xPosition;
    int yPosition;

    boolean functionsRun = false;

    for (int i = 0; i < level; i++) {

      startCheck = (int) Math.pow(2, i);
      endCheck   = (int) Math.pow(2, (i + 1));

      values = canvas.getLevelValues(i);

      for (int j = startCheck; j < endCheck; j++) {
	if ( (parent = canvas.getNodeAtRank(j)) != null) {

	  if ( (leftChild = parent.getLeftChild()) != null) {
	    xPosition = parent.origin().x - values[0];
	    yPosition = parent.origin().y + values[1];
	    
	    if ( (leftChild.origin().x != xPosition) ||
		 (leftChild.origin().y != yPosition)) {

	      Funcion mover = new MoverSubArbol(new Point(xPosition, yPosition),
					       leftChild);
	      mover.addObserver(this);

	      canvas.addFunction(mover);
	      
	      functionsRun = true;
	    }
	  }

	  if ( (rightChild = parent.getRightChild()) != null) {
	    xPosition = parent.origin().x + values[0];
	    yPosition = parent.origin().y + values[1];

	    if ( (rightChild.origin().x != xPosition) ||
		 (rightChild.origin().y != yPosition)) {

	      Funcion mover = new MoverSubArbol(new Point(xPosition, yPosition),
					       rightChild);
	      mover.addObserver(this);

	      canvas.addFunction(mover);

	      functionsRun = true;
	    }
	  }
	}
      }
    }

    if (functionsRun)
      bloqueado = true;
  }

  public void update(Observable observed, Object arg) {
    if (observed instanceof MoverSubArbol) {
      bloqueado = false;
    }
  }

  public void performFuncion() {
    if (bloqueado == false) {
      terminado = true;
    }
  }
}
