//Javascript referance for DIV positioning for MapZit and MapVision mapping
//Version 1.0 June 2001 Beacon Dodsworth
//Modified in Jan 2003 in order to improve cross browser compatibility and also make the content more generic.
//
//Please report any changes that you make to this file to michaelh@beacon-dodsworth.co.uk
//See notes in the associated readme.

//Object Constructor
	function DIVLayer(id,parent,content,left,top)
	{
		//alert('DIVLayer');
		this.id              = id;
		this.content         = content;
		this.xpos            = left;
		this.ypos            = top;
		this.originalleft    = left;
		this.originaltop     = top;
		
		//Need to retrieve this object from the page in order to set width and height
		if (document.getElementById) {
    	elent = document.getElementById(id);
    	this.width  = elent.offsetWidth;
    	//alert('id:' + id + ' width:' + elent.offsetWidth); 
    	this.height = elent.offsetHeight; 
    	this.obj = elent.style;
    } else {
        if (document.layers) {
        	if (parent != '')
        	{
            this.obj = document.layers[parent].document.layers[id];
          }
          else
          {
            this.obj = document.layers[id];	
          }
          this.width = this.obj.clip.width;
    	    this.height = this.obj.clip.height;  
        } else {
            if (document.all) {
              elent = document.all[id];
              this.width = elent.offsetWidth;
    	        this.height = elent.offsetHeight;
    	        this.obj = elent.style;
            }
        }
    }	
		this.right = this.xpos + this.width;
		this.bottom = this.ypos + this.height;
		this.cx = this.xpos + (this.width/2);
		this.cy = this.ypos + (this.height/2);
		
		this.moveto          = MoveTo;
		this.moveby          = MoveBy;
		this.safemoveto      = MoveTo2;	//stops moving to negative position on screen
		this.safemoveby      = MoveBy2;	//stops moving to negative position on screen
		this.centrefromtl    = Centrefromtopleft;
		this.centrescreen    = CentreScreen;
		this.centre          = CentreScreenX;
		this.defaultposition = DefaultPosition;
		this.makeright       = MakeRight;
		this.makebottom      = MakeBottom;
		this.shuffle         = shuffle;
		this.show            = show;
		this.hide            = hide;
		//this.movedfar        = FarfromOrigin;
		this.writediv        = WriteDIV;
	}
	
	function MoveTo(left,top){
		//alert('MoveTo(' + left + ',' + top + ')');
		this.xpos = left;
		this.ypos = top;
    this.obj.left = this.xpos;
    this.obj.top  = this.ypos;
    this.right = this.xpos + this.width;
		this.bottom = this.ypos + this.height;
		this.cx = this.xpos + (this.width/2);
		this.cy = this.ypos + (this.height/2);
	}
	
	function MoveTo2(left,top){
		//alert('MoveTo(' + left + ',' + top + ')');
		if(left < 0){
	  	left = 0;
	  }
	  if(top < 0){
	  	top = 0;
	  }
		this.moveto(left,top);
	}
	
	function MoveBy(dx,dy){
		//alert('MoveBy(' + dx + ',' + dy + ')');
		this.moveto(this.xpos + dx,this.ypos + dy);
	}
	
	function MoveBy2(dx,dy){
		//alert('MoveBy(' + dx + ',' + dy + ')');
		this.safemoveto(this.xpos + dx,this.ypos + dy);
	}
	
	function Centrefromtopleft()
	{
		//alert('CentreTL');
		this.moveby(-this.width/2,-this.height/2);
	}
	
	function CentreScreen()
	{
		//alert('CentreScreen');
		this.moveto((available_width/2-this.width/2),(available_height/2-this.height/2));
	}
	
	function CentreScreenX()
	{
		//alert('CentreScreenX');
	  //alert(available_width/2);
	  //alert(this.width/2);
	  this.safemoveto((available_width/2-this.width/2),this.ypos)
	}
	
	function DefaultPosition()
	{
		this.moveto(this.originalleft,this.originaltop);
		alert(this.width);
	}
	
	function MakeRight(newright){
		//Make the right of this object equal to right
		this.moveto(newright - this.width,this.ypos);	
  }

  function MakeBottom(newbottom){
  	//Make the bottom of this object equal to newbottom	
  	//alert('makebottom of ' + this.id + ' = ' + newbottom);
  	this.moveto(this.xpos,newbottom - this.height);
  }
	
	function WriteDIV(){
		document.write("<DIV class=bigplacename id=" + this.id + ">" + this.content + "</DIV>");
	}
	
	function shuffle(id2)
	{
		var midx;
		var midy;
		var dx;
		var dy;
		var dy2;
		
		//alert('Entering shuffle');
		
		//First calculate if this place name overlaps with placename id2
		//width/height etc. should already have been set by the centre function
	  if (RectanglesIntersect(this,id2))
			{
			//alert('overlap found between ' + this.id + ' and ' + id2.id);
			//These layers overlap so move them apart.
			//Calculate the midpoint of the vector between the two centrepoints
			midx = (this.cx + id2.cx) / 2;
			midy = (this.cy + id2.cy) / 2;
			
			//Deside what direction to move this layer in.
			dx = midx - this.cx;
			//alert('dx:' + dx);
			dy = midy - this.cy;
			//alert('dy:' + dy);
				
			if (Math.abs(dx) < Math.abs(dy)){
				//alert('Moving horizontally');
			  //Move horizontally	
				//Move the leftmost of these two so that it's right is midx
				//and the rightmost so that it's left is midx		
				if (this.cx < id2.cx){
					//alert(this.id + ' is leftmost');
				  this.makeright(midx);
				  id2.moveto(midx,id2.ypos);
				}
				else{
				  //alert(id2.id + ' is leftmost');
				  id2.makeright(midx);
				  this.moveto(midx,this.ypos);
				}	
			}
			else{
			  //alert('Moving vertically');
				//Move vertically
				//Move the topmost of these two so that it's bottom is midy
				//and the bottommost so that it's top is midy		
				
				if (this.cy < id2.cy){
					//alert(id2.id + ' is topmost');
				  this.makebottom(midy);
				  id2.moveto(id2.xpos,midy);
				}
				else{
				  //alert(id2.id + ' is topmost');
				  id2.makebottom(midy);
				  this.moveto(this.xpos,midy);
				}	
			}
			return true;
		}
		else
		{
			//No intersection
			//alert('no overlap');
			return false;
		}
	}
	
	function show()
	{
    if (document.layers) {
      this.obj.visibility = 'show';
    } else {
			this.obj.visibility = 'visible';
    }
  }

  function hide()
  {
		this.obj.visibility = 'hidden';
  }
  

	
	function RectanglesIntersect(r1,r2)
  {
  	//alert('checking Rectangles overlap');
  	//alertBounds(r1);
  	//alertBounds(r2);
    return(r2.right  > r1.xpos) &&
           (r2.xpos  < r1.right) &&
           (r2.ypos < r1.bottom) &&
           (r2.bottom > r1.ypos);
  }
  
  function FarfromOrigin()
  {
  	//Calculate how far this layer is from it's starting location...
  	//var dx;
  	var dy;
  	//dx = this.xpos - this.originalleft;
  	dy = this.ypos - this.originaltop;
  	return(dy/this.height); 
  }
  
  function alertBounds(r1)
  {
  	alert(r1.id + ':' + r1.xpos + ',' + r1.ypos + ',' + r1.right + ',' + r1.bottom);
  }
	
	
/*----------------------------------------------------------------------------------------------------------*/

	//Functions that apply to the placename array
	
	function positionplaces()
	{
		for (var i=0; i<PlaceNames.length; i++){
			PlaceNames[PlaceNames[i]].defaultposition();
		}
	}
	
	function centrebuyingpoints(){
		for (var i=0; i<BuyingPoints.length; i++){
			BuyingPoints[BuyingPoints[i]].centrefromtl();
		}
	}
	
	function centreplacenames(){
		for (var i=0; i<Placenames.length; i++){
			Placenames[Placenames[i]].centrefromtl();
		}
	}
	
	function shufflebuyingpoints(noiterations)
	{
  	var shuffled;
  	var anyshuffled;
  	var noshuffles;
  	var p1;
  	var p2;
  	noshuffles = 0;
  	anyshuffled = true;
  	
  	//alert('in shufflebuyingpoints');
  	
  	while (anyshuffled && noshuffles < noiterations)
  	{
  		noshuffles ++;
  		anyshuffled = false;
  		for (var i=0; i<BuyingPoints.length; i++){
  			for (var j=0; j<BuyingPoints.length; j++){
  			//for (var j=0; 2; j++){
  				if(i != j){
  					//alert('i != j');
  					p1 = BuyingPoints[BuyingPoints[i]];
  					p2 = BuyingPoints[BuyingPoints[j]];
  					//alert(p1);
  					shuffled = p1.shuffle(p2);
  					anyshuffled = anyshuffled || shuffled;
  				}
  			}
  		}
  	}

  	if (noshuffles < noiterations){
  		status = 'Points was shuffled ' + noshuffles + ' times in order to remove overlaps';
  	}
  	else{
  		if (noshuffles == 0){
  			status = 'points were not shuffled';
  		}
  		else{
  			status = 'Points was shuffled ' + noshuffles + ' times - some overlaps may remain.'
  		}
  	}
	}
	
	function shuffleplacenames(noiterations)
	{
  	var shuffled;
  	var anyshuffled;
  	var noshuffles;
  	var p1;
  	var p2;
  	noshuffles = 0;
  	anyshuffled = true;
  	
  	//alert('in shufflePlacenames');
  	
  	while (anyshuffled && noshuffles < noiterations)
  	{
  		noshuffles ++;
  		anyshuffled = false;
  		for (var i=0; i<Placenames.length; i++){
  			for (var j=0; j<Placenames.length; j++){
  			//for (var j=0; 2; j++){
  				if(i != j){
  					//alert('i != j');
  					p1 = Placenames[Placenames[i]];
  					p2 = Placenames[Placenames[j]];
  					//alert(p1);
  					shuffled = p1.shuffle(p2);
  					anyshuffled = anyshuffled || shuffled;
  				}
  			}
  		}
  	} 
	}
	
	function shuffle2buyingpoints()
	{
  	var shuffled;
  	var anyshuffled;
  	var noshuffles;
  	var p1;
  	var p2;
  	noshuffles = 0;
  	anyshuffled = true;
  	
  	//alert('in shufflebuyingpoints');
  	
  	while (anyshuffled && noshuffles < noiterations)
  	{
  		noshuffles ++;
  		anyshuffled = false;
  		for (var i=0; i<BuyingPoints.length; i++){
  			for (var j=0; j<BuyingPoints.length; j++){
  			//for (var j=0; 2; j++){
  				if(i != j){
  					//alert('i != j');
  					p1 = BuyingPoints[BuyingPoints[i]];
  					p2 = BuyingPoints[BuyingPoints[j]];
  					//alert(p1);
  					shuffled = p1.shuffle(p2);
  					anyshuffled = anyshuffled || shuffled;
  				}
  			}
  		}
  	}

  	if (noshuffles < noiterations){
  		status = 'Points was shuffled ' + noshuffles + ' times in order to remove overlaps';
  	}
  	else{
  		if (noshuffles == 0){
  			status = 'points were not shuffled';
  		}
  		else{
  			status = 'Points was shuffled ' + noshuffles + ' times - some overlaps may remain.'
  		}
  	}
	}

