// rotating image gallery script by hans anderson

//global variables
var followMouse = false;
var recordNextMouseCoordinates = true;
var currentCoordinates = new Vector2D();
var clickedCoordinates = new Vector2D();
var scrolledSinceMouseDown = new Vector2D();
var previousSpreadFactor = 1;

function moveImages(e)
{
  
  if (document.layers) { //Netscape 
    currentCoordinates.x = e.pageX;
    currentCoordinates.y = e.pageY;
    var xMousePosMax = window.innerWidth + window.pageXOffset;
  } else if (document.all) { // IE
    currentCoordinates.x = window.event.x + document.body.scrollLeft;
    currentCoordinates.y = window.event.y;		
  } else if (document.getElementById) {//Netscape
    currentCoordinates.x = e.pageX;
    currentCoordinates.y = e.pageY;
    var xMousePosMax = window.innerWidth + window.pageXOffset;
  }
  
  // stop following the mouse if it goes off the right edge of the browser
  if (currentCoordinates.x < 15) {
    ignoreMouse();
    return;
  }
  
  if (recordNextMouseCoordinates) { 
    clickedCoordinates = new Vector2D(currentCoordinates.x, currentCoordinates.y);
    scrolledSinceMouseDown = new Vector2D(0, 0);
    for (var idNumber = 0; idNumber < numImages; idNumber++) {
      var idString = "div" + idNumber.toString();
      var vectorString = idString + "home";
      eval(vectorString).x = parseInt(document.getElementById(idString).style.left.slice(0,-2));
      eval(vectorString).y = parseInt(document.getElementById(idString).style.top.slice(0,-2));
    }
    recordNextMouseCoordinates = false;
  }
  
  if (followMouse) {
    var mouseDragVector = new Vector2D((currentCoordinates.x - clickedCoordinates.x), (currentCoordinates.y - clickedCoordinates.y));
    var rotationAngle = 6*angularDistance(clickedCoordinates, mouseDragVector);
    if (!rotationAngle) rotationAngle = 0;
    var cosine = Math.cos(-rotationAngle);
    var sine = Math.sin(-rotationAngle);
    var spreadFactor = currentCoordinates.magnitude()/clickedCoordinates.magnitude();
    if (!spreadFactor) spreadFactor = 1;
    //to prevent the images from collecting in the corner:
    if ((imageLocation(1).magnitude() < 60)&&(spreadFactor < previousSpreadFactor)){ 
      spreadFactor = previousSpreadFactor;
    } else {
      previousSpreadFactor = spreadFactor;
    }
    for (var idNumber = 0; idNumber < numImages; idNumber++) {
      //we multiply rotationAngle by 5 to make it go a little faster.
      spreadAndRotate(idNumber, Math.pow(spreadFactor, 1.4), cosine, sine);
    }
  }	 
}

// by "angular distance", we mean to borrow from the term "angular velocity".  Angular distance is
// the angle of the arc spanned by the vector starting from the location where the mouse button 
// was pressed and pointing to the current location. The angle is measured from the origin, 
// in the top left of the page.
function angularDistance (startPoint, vector){
  var angle = startPoint.angleOfIntersection(vector);
  var sin = Math.sin(angle);
  var radius = startPoint.magnitude();
  var radiusMouseDragDotProduct = sin * vector.magnitude();
  return (radiusMouseDragDotProduct / radius); //why the radius and not the circumference? cause it works.
}

function imageLocation(idNumber){
  var idString = "div" + idNumber.toString();
  var x = 0;
  var y = 0;
  //for I.E.
  if (document.all){
window.status = document.getElementById(idString).style.pixelLeft;
    x = document.getElementById(idString).style.pixelLeft;
    y = document.getElementById(idString).style.pixelTop;
  }
  //for other browsers
  else {	
    x = parseInt(document.getElementById(idString).style.left.slice(0,-2));
    y = parseInt(document.getElementById(idString).style.top.slice(0,-2));
  }  
  return new Vector2D(x, y);
}

function Vector2D_angleOfIntersection(vect){
  return (vect.getAngle() - this.getAngle());
}

function Vector2D (x, y) { // a 2d vector object
  this.x = x;
  this.y = y;
  this.dotProduct = Vector2D_dotProduct_this;
  this.normalize = Vector2D_normalize;
  this.getAngle = Vector2D_getAngle;
  this.magnitude = Vector2D_magnitude;
  this.angleOfIntersection = Vector2D_angleOfIntersection;
  this.toString = Vector2D_toString;
}

// this is useful in determining the component of the mouse drag 
// vector that is parallel to the radius drawn from the center 
// of the circle ot the point where the mouse clicked down.  
// It will be zero if vectorA is perpendicular to vectorB.
function Vector2D_dotProduct (vectorA, vectorB){
  return Math.round(vectorA.x*vectorB.x) + Math.round(vectorA.y*vectorB.y);
}

// just in case you prefer to call dotProduct like this:
// vectorA.dotProduct(vectorB)
function Vector2D_dotProduct_this (vectorB){
  return Vector2D_dotProduct(this, vectorB);
}

function Vector2D_toString(){
  return ("coordinates: " + this.x + ', ' + this.y);
}

// returns a normalized version but doesn't affect the original
function Vector2D_normalize(){
  var magnitude = this.magnitude();
  var x = this.x / magnitude;
  var y = this.y / magnitude;
  return new Vector2D(x, y);
}

function Vector2D_magnitude(){
  var magnitude = Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
  return magnitude;
}

// find the angle of inclination of a vector
function Vector2D_getAngle(){ // returns in radians
  var vec = this.normalize();
  if (vec.x >= 0) {
    return Math.asin(vec.y);
  } else {
    if (vec.y >= 0) {
      return Math.acos(vec.x);
    } else {
      return - Math.acos(vec.x);
    }
  }
}

function rotate(idNumber, cosine, sine){
  var idString = "div" + idNumber.toString();
  var locationVectorString = "div" + idNumber.toString() + "home";
  var oldX = eval(locationVectorString).x;
  var oldY = eval(locationVectorString).y;
    
  //for I.E.
  if (document.all){
    document.getElementById(idString).style.pixelLeft = 
      Math.round((cosine * oldX) + (sine * oldY)) + "px";
    document.getElementById(idString).style.pixelTop = 
      Math.round((-sine * oldX) + (cosine * oldY)) + "px";
  }
  //for other browsers
  else {	
    document.getElementById(idString).style.left = 
      Math.round((cosine * oldX) + (sine * oldY)) + "px";
    document.getElementById(idString).style.top = 
      Math.round((-sine * oldX) + (cosine * oldY)) + "px";
  }
}

function spreadAndRotate(idNumber, spreadFactor, cosine, sine){
  var idString = "div" + idNumber.toString();
  var locationVectorString = "div" + idNumber.toString() + "home";
  var oldX = eval(locationVectorString).x;
  var oldY = eval(locationVectorString).y;
    
  //for I.E.
  if (document.all){
    document.getElementById(idString).style.pixelLeft = 
      Math.round(spreadFactor * ((cosine * oldX) + (sine * oldY)));
    document.getElementById(idString).style.pixelTop = 
      Math.round(spreadFactor * ((-sine * oldX) + (cosine * oldY)));
  }
  //for other browsers
  else {	
    document.getElementById(idString).style.left = 
      Math.round(spreadFactor * ((cosine * oldX) + (sine * oldY))) + "px";
    document.getElementById(idString).style.top = 
      Math.round(spreadFactor * ((-sine * oldX) + (cosine * oldY))) + "px";
  }
}

function spreadOut(idNumber, spreadFactor){
  var idString = "div" + idNumber.toString();
  var locationVectorString = "div" + idNumber.toString() + "home";
  var oldX = eval(locationVectorString).x;
  var oldY = eval(locationVectorString).y;
  
  //if spreadFactor is null use 1 instead
  if(!spreadFactor) spreadFactor = 1;
  
  //for I.E.
  if (document.all){
    document.getElementById(idString).style.pixelLeft = Math.round(spreadFactor * oldX);
    document.getElementById(idString).style.pixelTop = Math.round(spreadFactor * oldY);
  }
  //for other browsers
  else {	
    document.getElementById(idString).style.left = Math.round(spreadFactor * oldX) + "px";
    document.getElementById(idString).style.top = Math.round(spreadFactor * oldY) + "px";
  }
}

function handleMouse()
{
  followMouse = true;
  recordNextMouseCoordinates = true;
  if (document.layers) { // Netscape
    document.captureEvents(Event.MOUSEMOVE);
    document.onmousemove = moveImages;
  } else if (document.all) { // Internet Explorer
    document.onmousemove = moveImages;
  } else if (document.getElementById) { // Netcsape 6
    document.onmousemove = moveImages;
  }
}

function ignoreMouse(e){
  followMouse = false;
}

//register event handlers
document.onmouseup=ignoreMouse;
document.onmousedown=handleMouse;
