// =============================================================
//
// Copyright (c) 2000-2003 GE Smallworld. All Rights Reserved.
//
// =============================================================


// --------  Typed Object ------------------
function TypedObject(type, value) {
   //	----------------------------------------------------------------------
   //	This function (object definition) allows for a way to represent 
   //	typed objects in the JavaScript objects definition.
   //
   //	Parameters:
   //		type: The type of the object
   //		value: value for that object
   //	---------------------------------------------------------------------- 

   // setup methods
   this.copy = TypedObject_copy;
   
	this.type=type;
   
   if (value != undefined) {
      switch(type) {
   	 case 'float':
   	   this.value = parseFloat(value);		
   	   break;
   	 case 'integer':
   	   this.value = parseInt(value);
   	   break;
   	 case 'boolean':
   	   if (value.toLowerCase)
   	   	this.value = (value.toLowerCase() == 'true');
   	   else this.value = value;
   	   break;	
   	 case 'coordinate':
         // split apart values
   	 	var tempValue = value.split(',');
         
         // get x and y
         var x = parseFloat(tempValue[0]);
   	 	var y = parseFloat(tempValue[1]);
   
         // now save coordinate object as the value
         this.value = new Coordinate(x, y);
   
   	 	break;
   	 default:		
   	   this.value=value;
   	}
   }
}

function TypedObject_copy() {
   //	Copies this object.
   //
   //	Parameters: none
   //
   // Result: none
   
   var aTypedObject = new TypedObject(this.type);
   
   aTypedObject.value = this.value;
   
   return aTypedObject;
}                          



// ------------  Coordinate Object --------------
function Coordinate(x,y) {
	this.x =x;
	this.y =y;

	this.distanceTo=Coordinate_distanceTo;
	this.toString=Coordinate_toString;
}	

function Coordinate_distanceTo(anotherCoord) {
     var dx = this.x - anotherCoord.x;
     var dy = this.y - anotherCoord.y;

     return Math.sqrt( dx * dx + dy * dy);
}
	
function Coordinate_toString() { 
	return '('  + Math.round(this.x) + ',' + Math.round(this.y) +')';
}



// ------------  Bounding Box Object --------------
function Box(bnds) {
      this.string = bnds;
      var coords = bnds.split(' ');
      if(coords.length < 2) return;
      var min = coords[0].split(',');
      var max = coords[1].split(',');
      this.xmin = parseInt(min[0]);
      this.ymin = parseInt(min[1]);
      this.xmax = parseInt(max[0]);
      this.ymax = parseInt(max[1]);
      this.width = this.xmax - this.xmin;
      this.height = this.ymax - this.ymin;
      this.centre = new Coordinate((this.xmin + this.xmax)/2,(this.ymin + this.ymax)/2);
      this.distanceTo= Box_distanceTo;
      this.enlarge = Box_enlarge;
      this.contains= Box_contains;
      this.toString= Box_toString;
}

function Box_toString() {
	return this.string;
}

function Box_enlarge(inc) {
     this.xmin -= inc/2;
     this.xmax += inc/2;
     this.ymin -= inc/2;
     this.ymax += inc/2;
}

function Box_contains(pt) {
   return  (pt.x > this.xmin && pt.y > this.ymin && pt.x < this.xmax && pt.y < this.ymax);	
}

function Box_distanceTo(pt) {
     return this.centre.distanceTo(pt);
}


// --------------  AffineTransform Object -----------------
function AffineTransform(centreCoord, scale, width, height) {
   // setup methods
	this.copy = AffineTransform_copy;		
	this.toWorld = AffineTransform_toWorld;
	this.toPixel = AffineTransform_toPixel;		

   // save values
	this.centreCoord = centreCoord;
	this.scale = scale;
	this.width = width;
	this.height =height;
   
}

function AffineTransform_copy() {
   var aTransform = new AffineTransform(this.centreCoord,
                                        this.scale,
                                        this.width,
                                        this.height);

   return aTransform;   
}

function AffineTransform_toPixel(coord) {
	var pixX = (coord.x - this.centreCoord.x) / this.scale + this.width/2;
	var pixY = (this.centreCoord.y - coord.y) / this.scale + this.height/2;
	return new Coordinate(pixX,pixY);
}

function AffineTransform_toWorld(coord) {
	//alert((coord.x-this.width/2) + ' | ' + (this.height/2 - coord.y) + ' | ' + this.scale + ' | ' + this.centreCoord.x + ', ' + this.centreCoord.y);
	
	var worldX = (coord.x-this.width/2) * this.scale + this.centreCoord.x;

	var worldY = (this.height/2 - coord.y) * this.scale + this.centreCoord.y;

	return new Coordinate(worldX,worldY);
}


// --------------  Map Object --------------
function Map(aMap) {
	this.copy = Map_copy;
	this.getCoord=Map_getCoordinate;
}

function Map_copy() {
   var aMap = new Map();	

   aMap.transform = this.transform.copy();
   aMap.rendered_dscale = this.rendered_dscale.copy();
   aMap.rendered_view_scale = this.rendered_view_scale.copy();
   aMap.rendered_centre = this.rendered_centre.copy();
   aMap.rendered_world_name = this.rendered_world_name.copy();
   aMap.rendered_bbox = this.rendered_bbox.copy();
   aMap.image_pathname = this.image_pathname.copy();
   aMap.units = this.units.copy();
   aMap.unit_factor = this.unit_factor.copy();

   return aMap;   
}

function Map_getCoordinate(evt) {
	if (evt.target) { // gecko
	   return new Coordinate(evt.clientX - evt.target.offsetLeft, evt.clientY - evt.target.offsetTop );
	}
	else {
	   return new Coordinate( evt.offsetX, evt.offsetY);
    	}
}


// -----------  Response Object --------------
function Response() {
   // setup methods
   this.update = Response_update;
	this.registerObject = Response_registerObject;
   
	// set up registering of sub-objects
	this.registeredObjects = new Array(MAX_OBJECTS);
	this.objectCount = 0;
   
   // setup registry and client registry
   this.registry = new Registry();
   this.client_registry = new ClientRegistry();
}

function Response_update(aSourceResponse) {
	this.client_registry = aSourceResponse.client_registry.copy();
	this.registry = aSourceResponse.registry.copy();
	
	// loop for extra types
	for (var i=0; i < this.objectCount; i++) {
		if (eval('aSourceResponse.' + this.registeredObjects[i]) != null) {
			eval ('this.' + this.registeredObjects[i] + ' = aSourceResponse.' + this.registeredObjects[i] + '.copy()');
		}
	}
}

function Response_registerObject(aObject, aName) {
	for (var i=0; i < this.objectCount; i++) {
		// check to see if this is for the same function name
      // and content type
		if (this.registeredObjects[i] == aName) {
			eval('this.' + aName + ' = aObject;');
			return;
		}
	}
   
	this.registeredObjects[this.objectCount] = aName;
	eval('this.' + aName + ' = aObject;');
	this.objectCount++;
}


// -----------  Registry Object ------------------
function Registry() {
   // setup methods
	this.copy = Registry_copy;
}

function Registry_copy() {
	var aRegistry =  new Registry();
   
   aRegistry.swldy_scale = this.swldy_scale.copy();
   aRegistry.swldy_centre = this.swldy_centre.copy();
   aRegistry.swldy_themes = this.swldy_themes.copy();
   aRegistry.swldy_image_format = this.swldy_image_format.copy();
   aRegistry.swldy_image_quality = this.swldy_image_quality.copy();
   aRegistry.transparent = this.transparent.copy();
   aRegistry.swldy_image_interlace = this.swldy_image_interlace.copy();
   aRegistry.bgcolor = this.bgcolor.copy();

   if (aRegistry.swldy_dscale != undefined) {
      aRegistry.swldy_dscale = this.swldy_dscale.copy();
   }

   return aRegistry;
}


// -----------  Client Registry Object ------------------
function ClientRegistry() {
   // setup methods
	this.copy = ClientRegistry_copy;
}

function ClientRegistry_copy() {
	var aClientRegistry = new ClientRegistry();
   
   aClientRegistry.width = this.width.copy();
   aClientRegistry.height = this.height.copy();
   aClientRegistry.swldy_rot = this.swldy_rot.copy();
   aClientRegistry.swldy_world = this.swldy_world.copy();
   aClientRegistry.swldy_ace = this.swldy_ace.copy();
   aClientRegistry.swldy_dscale_locked = this.swldy_dscale_locked.copy();
   aClientRegistry.swldy_drapp = this.swldy_drapp.copy();
   aClientRegistry.srs = this.srs.copy();
   aClientRegistry.swldy_srs_locked = this.swldy_srs_locked.copy();
   aClientRegistry.script_name = this.script_name.copy();
   aClientRegistry.portal_url = this.portal_url.copy();
   aClientRegistry.language = this.language.copy();
   aClientRegistry.session_id = this.session_id.copy();	
}

