/* Positional Element Functions (requires AJAX Prototype)
 * Description:  Provides several functions for moving elements
 *               and also simulating a popup window.
 * Programmer:   Aaron Harrell
 * Copyright:    2008
 * Created:      11/17/2008
 * @version      0.01
 * ------------- Modifications --------------
 * mm/dd/yyy abc  changed/added this or that (put latest changes at top)
*/

/*! \file positional.js
* \brief Positional Element Functions (requires AJAX Prototype)
*
* Provides several functions for moving elements and also simulating a popup window.
*/

var sgc_onTop = 100; //!< Provides the z-index for use with pop-ups.

function centerInWindow(moveThis){
  element = $(moveThis);
  
  var elementDims = element.getDimensions();
  var viewPort = document.viewport.getDimensions();
  var offsets = document.viewport.getScrollOffsets();
  // alert(offsets);
  offsetW = (Prototype.Browser.IE)?offsets[0]*2:offsets[0];
  offsetH = (Prototype.Browser.IE)?offsets[1]*2:offsets[1];
  // offsetW = (Prototype.Browser.IE)?offsets.left*2:offsets.left;
  // offsetH = (Prototype.Browser.IE)?offsets.top*2:offsets.top;
  var centerX = Math.floor((viewPort.width / 2) + (offsetW - elementDims.width / 2));
  var centerY = Math.floor((viewPort.height / 2) + (offsetH - elementDims.height / 2));
  if(centerX < 0){
    centerX = parseInt(13);
  }
  if(centerY < 0){
    centerY = parseInt(13);
  }  
  element.setStyle({position:'absolute',top:centerY+'px',left:centerX+'px'});
}

/*! \fn positionHere(moveThis,anchorTo,setLeft,setTop)
* \brief This function anchors an element to another element's position(once per call, it will not continually follow that element). Parameters can be sent that specify a numeric offset from the top left corner of the anchor, or the words 'center', 'right', 'top', 'middle' or 'bottom' can be used.
* \param moveThis Contains the id of the object to move.
* \param anchorTo Contains the id of the anchor.
* \param setLeft Contains the left offset.
* \param setTop Contains the top offset.
*/
function positionHere(moveThis,anchorTo,setLeft,setTop){
/* This function requires an Element to move and an 'anchor' Element.
 *  If anchorTo is not provided, moveThis is used as the anchor.
 *  setLeft and setTop are optional.
 *  Examples:
 *  positionHere($('outerDiv'),$('_resizeTop'));
 *  positionHere($('outerDiv'),$('_resizeTop'),10,10);
 *  positionHere($('outerDiv'),$('_resizeTop'),'center','middle');
*/

  moveThis = $(moveThis);
  anchorTo = $(anchorTo) || moveThis;
  if(setLeft == 'center'){
    setLeft = (anchorTo.getWidth() - moveThis.getWidth())/2;
  }else if(setLeft == 'right'){
    setLeft = anchorTo.getWidth() - moveThis.getWidth();
  }else{
    setLeft = (isNaN(setLeft))?0:setLeft;
    setLeft = parseInt(setLeft) || 0;
  }
  if(setTop == 'middle'){
    setTop = (anchorTo.getHeight() - moveThis.getHeight())/2;
  }else if(setTop == 'bottom'){
    setTop = anchorTo.getHeight() - moveThis.getHeight();
  }else{
    setTop = (isNaN(setTop))?0:setTop;
    setTop = parseInt(setTop) || 0;
  }
  setTop += (Prototype.Browser.IE)?moveThis.cumulativeScrollOffset()[1]*2:0;
  // alert('setLeft='+setLeft+' setTop='+setTop);
  Element.show(moveThis);
  moveThis.absolutize();
  moveThis.clonePosition(anchorTo,{setWidth:false,setHeight:false,offsetLeft:setLeft,offsetTop:setTop});
  moveThis.style.zIndex = sgc_onTop++;
  
  // if(Prototype.Browser.IE){ 
    // alert(moveThis.cumulativeScrollOffset());
  // }
}

/*! \fn initFloater(fauxWindow,fauxControl,anchorTo)
* \brief This function releases an element from its relative position and enables the 'control' to be used to move that element around like a normal window. If an 'anchor' element is specified, the 'window' element will centered on that elements position.
* \param fauxWindow Contains the id of the object to move.
* \param fauxControl Contains the id of the controller.
* \param anchorTo Contains the id of the anchor.
*/
function initFloater(fauxWindow,fauxControl,anchorTo){
/* Required: An Element to move and an Element to control movement.
 *  Contoller should be inside main element or it may flake out.
 *  If no fauxController is provided, the fauxWindow is used as the controller.
 *  anchorTo is optional, ties your fauxWindow to the provided 'anchor' element (centered)
 *  Examples:
 *  initFloater($('outerDiv'));
 *  initFloater($('outerDiv'),$('control'));
 *  initFloater($('outerDiv'),$('control'),$('_resizeTop'));
*/

  var dragging=false;
  var initY=null;
  var initX=null;

  //Make sure things are setup right
  fauxWindow = $(fauxWindow);
  anchorTo = $(anchorTo);
  fauxControl = $(fauxControl) || fauxWindow;
  Element.show(fauxWindow);
  fauxWindow.absolutize();
  fauxControl.style.cursor="move";
  if(anchorTo){
    positionHere(fauxWindow,anchorTo,'center','middle');
  }else{
    fauxWindow.clonePosition(fauxWindow,{setWidth:false,setHeight:false,setLeft:true,setTop:true});
  }
  fauxWindow.style.zIndex = sgc_onTop++;

  //when the user clicks on the divider, start proceedings
  fauxControl.observe("mousedown",function(event){
    if(!dragging){
      //save this for later
      initY=event.pointerY()-parseInt(fauxWindow.style.top);
      initX=event.pointerX()-parseInt(fauxWindow.style.left);
      dragging=true;
      fauxWindow.style.zIndex = sgc_onTop++;
			Element.setOpacity(fauxWindow,.7);
      //while the user is dragging the fauxControl, move the fauxWindow on the y/x-axis
      document.observe("mousemove",function(event){
        if(dragging){
          var y=event.pointerY()-initY;
          fauxWindow.style.top=y+"px";
          var x=event.pointerX()-initX;
          fauxWindow.style.left=x+"px";
        }
      });
      //when the user lets go, resize the panes
      document.observe("mouseup",function(event){
      if(dragging){
          dragging=false;
          document.stopObserving('mouseup');
          document.stopObserving('mousemove');
     			Element.setOpacity(fauxWindow,1);
       }
      });
    }
  });
	fauxWindow.observe("mousedown",function(event){
    fauxWindow.style.zIndex = sgc_onTop++;
	});
}

/*! \fn releaseFloater(fauxWindow,fauxControl)
* \brief This function clears all observations of an element initiated by the initFloater function and hides the element.
* \param fauxWindow Contains the id of the object to move.
* \param fauxControl Contains the id of the controller.
*/
function releaseFloater(fauxWindow,fauxControl){
/* This function requires an Element and its controller.
 *  Use this to hide the popup and remove the event observers.
 *  If no fauxController is provided, the fauxWindow is used as the controller.
*/
  fauxWindow = $(fauxWindow);
  fauxControl = $(fauxControl) || fauxWindow;

  fauxControl.stopObserving('mousedown');
  fauxControl.style.cursor="default";
  Element.hide(fauxWindow);
}

