// 'outer_el' gets created and never deleted even as we redraw.
//  It holds the entire thing.
var CLOSED = 0;
var OPENED = 1;
var HELD_OPENED = 2;

var ANIMATE_INTERVAL_MS = 10;
var ANIMATE_INVISIBILE_STEPS = 40;
var ANIMATE_VISIBILE_STEPS = 20;
var ANIMATE_MAX_STEPS   = 10 + ANIMATE_INVISIBILE_STEPS;

var anidiv = function(spec, baggage) {
   
   var that = {}; 

   that.baggage = baggage || {};
   spec = spec || {};

   spec.max_height = spec.max_height || 10;
   spec.min_height = spec.min_height || 0;
   spec.cycle_ms   = spec.cycle_ms   || 0;

   that.px_per_step = (spec.max_height - spec.min_height) / ANIMATE_VISIBILE_STEPS;

   // this is private
   var my_el = document.createElement('DIV');
   my_el.style.width = "400";
   my_el.style.height = spec.min_height;
//   my_el.style.border = "blue dashed thin";
 

   that.client_el = document.createElement('DIV');
   my_el.appendChild(that.client_el);

   that.target_state = CLOSED;
   that.timer = null;
   that.step  = 0;
   that.nuke_next = false;

   that.container_el = function() { return my_el;}
   that.el           = function() { return that.client_el;}

   that.hold_open = function() {
      that.target_state = HELD_OPENED;
   }

   that.set_nuke = function() {
      that.nuke_next = true;
   }
   that.is_nuke = function() { 
      return that.nuke_next;
   }
   that.nuke = function() {
      remove_all_children(that.el());
      that.nuke_next = false;
   }

   that.release_open = function() {
      that.target_state = OPENED;
      that.animate();
   }

   my_el.onmouseover = function () { 
      if (that.target_state != HELD_OPENED) {
         that.target_state = OPENED; 
         that.animate();
      }
   }
   that.close = function(force) {
      if (force || that.target_state != HELD_OPENED) {
         that.target_state = CLOSED; 
         that.animate();
      }
   }

   my_el.onmouseout = function () { that.close(); }

   that.animate = function() {
      if (that.target_state == CLOSED) {
         that.client_el.style.display = "none";
         that.step--;
         if (that.step <= ANIMATE_INVISIBILE_STEPS) {
            that.step = 0;
            my_el.style.height = spec.min_height;
            if (spec.onclosed) {
               spec.onclosed(that);
            }
            return;
         }
      } else if (that.target_state == OPENED) {
         that.step++;
         if (that.step >= ANIMATE_MAX_STEPS) {
            that.step = ANIMATE_MAX_STEPS;
      // if I'm fully opened, I want to let the DIV size itself
            my_el.style.height = null;
            if (spec.onopened) {
               that.client_el.style.display = "inline";
               spec.onopened(that);
            }
            return;
         }
      }
      setTimeout(that.animate, ANIMATE_INTERVAL_MS);
      if (that.step >= ANIMATE_INVISIBILE_STEPS) {
         my_el.style.height = spec.min_height + 
            that.px_per_step*(that.step - ANIMATE_INVISIBILE_STEPS);
      }
   }

   return that;

}

