dojo.declare("imgchf.handle", null, {
	
});

dojo.declare("imgchf.rotate", null, {
	
});

dojo.declare("imgchf.pointfcn", null, {
	
});

imgchf.handle.SIZE = 7;
imgchf.handle.OFFSET = Math.round(imgchf.handle.SIZE / 2);
//imgchf.handle.OFFSET = Math.round(imgchf.handle.SIZE / 2);

imgchf.rotate.SIZE = 13;
imgchf.rotate.OFFSET = Math.round(imgchf.handle.SIZE / 2);

imgchf.handle.t = function(aHandle, m, bbox) 
{
	pt = {x: bbox.x + (bbox.width / 2), y: bbox.y};
	t = dojo.gfx.matrix.multiplyPoint(m, pt);
  	aHandle.setPosition(t.x - imgchf.handle.OFFSET, t.y - imgchf.handle.OFFSET);
};

imgchf.handle.b = function(aHandle, m, bbox) 
{
	pb = {x: bbox.x + (bbox.width / 2), y: bbox.y + bbox.height};
	b = dojo.gfx.matrix.multiplyPoint(m, pb);
  	aHandle.setPosition(b.x - imgchf.handle.OFFSET, b.y - imgchf.handle.OFFSET);
};

imgchf.handle.l = function(aHandle, m, bbox) 
{
	pl = {x: bbox.x, y: bbox.y + (bbox.height / 2)};
	l = dojo.gfx.matrix.multiplyPoint(m, pl);
  	aHandle.setPosition(l.x - imgchf.handle.OFFSET, l.y - imgchf.handle.OFFSET);
};

imgchf.handle.r = function(aHandle, m, bbox) 
{
	pr = {x: bbox.x + bbox.width, y: bbox.y + (bbox.height / 2)};
	r = dojo.gfx.matrix.multiplyPoint(m, pr);
  	aHandle.setPosition(r.x - imgchf.handle.OFFSET, r.y - imgchf.handle.OFFSET);
};

imgchf.handle.tl = function(aHandle, m, bbox) 
{
	p0 = {x: bbox.x, y: bbox.y};
	tl = dojo.gfx.matrix.multiplyPoint(m, p0);
  	aHandle.setPosition(tl.x - imgchf.handle.OFFSET - imgchf.handle.SIZE, tl.y - imgchf.handle.OFFSET - imgchf.handle.SIZE);
};

imgchf.handle.tr = function(aHandle, m, bbox) 
{
	p1 = {x: bbox.x + bbox.width, y: bbox.y};
	tr = dojo.gfx.matrix.multiplyPoint(m, p1);
  	aHandle.setPosition(tr.x + imgchf.handle.OFFSET, tr.y - imgchf.handle.OFFSET - imgchf.handle.SIZE);
};

imgchf.handle.bl = function(aHandle, m, bbox) 
{
	p2 = {x: bbox.x, y: bbox.y + bbox.height};
	bl = dojo.gfx.matrix.multiplyPoint(m, p2);
  	aHandle.setPosition(bl.x - imgchf.handle.OFFSET - imgchf.handle.SIZE, bl.y + imgchf.handle.OFFSET);
};

imgchf.handle.br = function(aHandle, m, bbox) 
{
	p3 = {x: bbox.x + bbox.width, y: bbox.y + bbox.height};
	br = dojo.gfx.matrix.multiplyPoint(m, p3);
  	aHandle.setPosition(br.x + imgchf.handle.OFFSET, br.y + imgchf.handle.OFFSET);
};

imgchf.rotate.br = function(aHandle, m, bbox) 
{

	p3 = {x: bbox.x + bbox.width, y: bbox.y + (bbox.height * 3 / 4)};
	br = dojo.gfx.matrix.multiplyPoint(m, p3);

	aHandle.rotateImage.setTransform(dojo.gfx.matrix.translate(br.x, br.y - 2 * imgchf.handle.OFFSET));
	if (dojo.render.html.ie) {
 		aHandle.setPosition(br.x + imgchf.handle.OFFSET + imgchf.handle.OFFSET + 2, br.y + 2); 
 	} else {
 		aHandle.setPosition(br.x + imgchf.handle.OFFSET + imgchf.handle.OFFSET + 3, br.y + 3); 
 	}
};

imgchf.pointfcn.pt = function(aHandle, m, pt) 
{
//  	dojo.debug("imgchf.pointSelect.pt");
	thePoint = dojo.gfx.matrix.multiplyPoint(m, pt);
  	aHandle.setPosition(thePoint.x, thePoint.y);
};

function TrackPoint(aHandle, x, y) {
//  	aHandle.mRootShape.applyPoint(m);
//  	dojo.debug("TrackPoint2 x:" + x + " y:" + y);
//  	var invmatrix = dojo.gfx.matrix.invert(aHandle.mRootShape.getTransform());
 // 	var invpoint = dojo.gfx.matrix.multiplyPoint(invmatrix, x, y);
//  	dojo.debug("TrackPoint invert x:" + invpoint.x + " y:" + invpoint.y);
  	
//  	this.mRootShape.movePoint(xTo, yTo, this.mIndex);
  	this.mRootShape.movePoint(x, y, aHandle.mIndex); // invpoint.x, invpoint.y, aHandle.mIndex);
}

function CreateTrackPoint(aHandle, x, y) {
//  	aHandle.mRootShape.applyPoint(m);
//  	dojo.debug("CreateTrackPoint x:" + x + " y:" + y);
//  	var invmatrix = dojo.gfx.matrix.invert(aHandle.mRootShape.getTransform());
 // 	var invpoint = dojo.gfx.matrix.multiplyPoint(invmatrix, x, y);
//  	dojo.debug("TrackPoint invert x:" + invpoint.x + " y:" + invpoint.y);
  	
//  	this.mRootShape.movePoint(xTo, yTo, this.mIndex);
  	this.mRootShape.moveCreatePoint(x, y, aHandle.mIndex); // invpoint.x, invpoint.y, aHandle.mIndex);
}

function TrackCorner_tl(aHandle, x, y) {
	x0 = x + imgchf.handle.OFFSET + imgchf.handle.SIZE;
	y0 = y + imgchf.handle.OFFSET + imgchf.handle.SIZE;
	TrackCorner(aHandle, x0, y0);
}
function TrackCorner_tr(aHandle, x, y) {
	x0 = x - imgchf.handle.SIZE;
	y0 = y + imgchf.handle.OFFSET + imgchf.handle.SIZE;
	TrackCorner(aHandle, x0, y0);
}
function TrackCorner_bl(aHandle, x, y) {
	x0 = x + imgchf.handle.OFFSET + imgchf.handle.SIZE;
	y0 = y - imgchf.handle.OFFSET;
	TrackCorner(aHandle, x0, y0);
}
function TrackCorner_br(aHandle, x, y) {
	x0 = x - imgchf.handle.OFFSET;
	y0 = y - imgchf.handle.OFFSET;
	TrackCorner(aHandle, x0, y0);
}

function TrackCorner(aHandle, x, y) {
  	rootmatrix = aHandle.mRootShape.mShape.getTransform();
	P2 = dojo.gfx.matrix.multiplyPoint(rootmatrix, aHandle.p);
	P1 = dojo.gfx.matrix.multiplyPoint(rootmatrix, aHandle.mAnchor.p);
	
	if (P2.x - P1.x) {
		scalex = (x - P1.x) / (P2.x - P1.x );
  	}
  	else {
  		scalex = 0;
  	}
  	if (P2.y - P1.y) {
  		scaley = (y - P1.y) / (P2.y - P1.y );
  	}
  	else {
  		scaley = 0;
  	}
  	
  	if (scalex > scaley) {
  		scaley = scalex;
  	} else {
  		scalex = scaley;
  	}
//	dojo.debug("scale is " + scalex + " " + scaley);
	m = dojo.gfx.matrix.scaleAt(scalex, scaley, aHandle.mAnchor.p);
		 	
  	aHandle.mRootShape.applyEffect(m);
}

function TrackHSide(aHandle, x, y) {
  	rootmatrix = aHandle.mRootShape.mShape.getTransform();
	P2 = dojo.gfx.matrix.multiplyPoint(rootmatrix, aHandle.p);
	P1 = dojo.gfx.matrix.multiplyPoint(rootmatrix, aHandle.mAnchor.p);
	
  	if (P2.y - P1.y) {
  		scaley = (y - P1.y) / (P2.y - P1.y );
  	}
  	else {
  		scaley = 0;
  	}
	
	m = dojo.gfx.matrix.scaleAt(1.0, scaley, aHandle.mAnchor.p);
		 	
  	aHandle.mRootShape.applyEffect(m);
}

function TrackVSide(aHandle, x, y) {
  	rootmatrix = aHandle.mRootShape.mShape.getTransform();
	P2 = dojo.gfx.matrix.multiplyPoint(rootmatrix, aHandle.p);
	P1 = dojo.gfx.matrix.multiplyPoint(rootmatrix, aHandle.mAnchor.p);
	
	if (P2.x - P1.x) {
		scalex = (x - P1.x) / (P2.x - P1.x );
  	}
  	else {
  		scalex = 0;
  	}
	scaley = 1;
	
	m = dojo.gfx.matrix.scaleAt(scalex, 1.0, aHandle.mAnchor.p);
		 	
  	aHandle.mRootShape.applyEffect(m);
}

function TrackRotate(aHandle, x, y) {
	// inspired by inkspace
	d1 = {x: x - aHandle.p.x, y: y - aHandle.p.y};
	dist1 = imgchf.distance(aHandle.p, {x: x, y: y});
	
	d2 = {x: aHandle.cX - aHandle.p.x, y: aHandle.cY - aHandle.p.y};
	dist2 = imgchf.distance(aHandle.p, {x: aHandle.cX, y: aHandle.cY});
	
	// normalize
	d1.x = d1.x / dist1;
	d1.y = d1.y / dist1;
	
	d2.x = d2.x / dist1;
	d2.y = d2.y / dist1;

	// inverse of d2
	d2.y = -d2.y;
	
	// take crossproduct
	
	d3 = {x: (d1.x * d2.x - d1.y * d2.y), y: (d1.y * d2.x + d1.x * d2.y)}; 
//	dojo.debug("d3 is " + d3.x + "," + d3.y);
	
	degrees = Math.atan2(d3.y,d3.x);
	
  rootmatrix = aHandle.mRootShape.getTransform();
  rotatePt = dojo.gfx.matrix.multiplyPoint(rootmatrix, aHandle.p);
  	
//  dojo.debug("anchor rotatePt xTo:" + aHandle.p.x + " yTo:" + aHandle.p.y);
//  dojo.debug("rotatePt xTo:" + rotatePt.x + " yTo:" + rotatePt.y);
  	
	m = dojo.gfx.matrix.rotateAt(-degrees, rotatePt);
		 	
  aHandle.mRootShape.applyRotate(m);
}

function DeletePoint(aHandle) {
	aHandle.mRootShape.delPoint(aHandle);
}

function NoDeletePoint(aHandle) {
}

dojo.declare("imgchf.handles", null, {
  initializer: function(aShape) {
  	this.mRootShape = aShape;
  	this.mBbox = aShape.getBoundingBox();
  	this.handles = [];
  	
  	bbox = this.mBbox;
  	aShape = this.mRootShape;
  	
//	dojo.debug('transform handles: bbox coords, bbox.x:' + bbox.x + ' bbox.width:' + bbox.width + ' bbox.y:' + bbox.y + ' bbox.height:' + bbox.height);
/*
		p0 = {x: bbox.x, y: bbox.y};
		p1 = {x: bbox.x + bbox.width, y: bbox.y};
		p2 = {x: bbox.x, y: bbox.y + bbox.height};
		p3 = {x: bbox.x + bbox.width, y: bbox.y + bbox.height};
*/
		p0 = {x: bbox.x, y: bbox.y};
		p1 = {x: bbox.x + bbox.width, y: bbox.y};
		p2 = {x: bbox.x, y: bbox.y + bbox.height};
		p3 = {x: bbox.x + bbox.width, y: bbox.y + bbox.height};
	
		pt = {x: bbox.x + (bbox.width / 2), y: bbox.y};
		pb = {x: bbox.x + (bbox.width / 2), y: bbox.y + bbox.height};
		pl = {x: bbox.x, y: bbox.y + (bbox.height / 2)};
		pr = {x: bbox.x + bbox.width, y: bbox.y + (bbox.height / 2)};
		
		pc = {x: bbox.x + (bbox.width / 2), y: bbox.y + (bbox.height / 2)};
	
	
		new_id = "shape_" + (gShapeCounter++);
  	gShapes[new_id] = this.handles.tl = new imgchf.handle.transformPoint(new_id, aShape, p0, TrackCorner_tl, imgchf.handle.tl); 

		new_id = "shape_" + (gShapeCounter++);
  	gShapes[new_id] = this.handles.tr = new imgchf.handle.transformPoint(new_id, aShape, p1, TrackCorner_tr, imgchf.handle.tr); 

		new_id = "shape_" + (gShapeCounter++);
  	gShapes[new_id] = this.handles.bl = new imgchf.handle.transformPoint(new_id, aShape, p2, TrackCorner_bl, imgchf.handle.bl); 

		new_id = "shape_" + (gShapeCounter++);
  	gShapes[new_id] = this.handles.br = new imgchf.handle.transformPoint(new_id, aShape, p3, TrackCorner_br, imgchf.handle.br); 

		new_id = "shape_" + (gShapeCounter++);
	 	gShapes[new_id] = this.handles.br_r = new imgchf.handle.rotatePoint(new_id, aShape, pc, TrackRotate, imgchf.rotate.br); 
/* no midpoint handles for now	
	new_id = "shape_" + (gShapeCounter++);
  	gShapes[new_id] = this.handles["t"] = new imgchf.handle.transformPoint(new_id, aShape, pt, TrackHSide, imgchf.handle.t); 

	new_id = "shape_" + (gShapeCounter++);
  	gShapes[new_id] = this.handles["b"] = new imgchf.handle.transformPoint(new_id, aShape, pb, TrackHSide, imgchf.handle.b); 

	new_id = "shape_" + (gShapeCounter++);
  	gShapes[new_id] = this.handles["l"] = new imgchf.handle.transformPoint(new_id, aShape, pl, TrackVSide, imgchf.handle.l); 

	new_id = "shape_" + (gShapeCounter++);
  	gShapes[new_id] = this.handles["r"] = new imgchf.handle.transformPoint(new_id, aShape, pr, TrackVSide, imgchf.handle.r); 
*/
		this.handles.tl.setAnchor(this.handles.br);
		this.handles.br.setAnchor(this.handles.tl);
		this.handles.tr.setAnchor(this.handles.bl);
		this.handles.bl.setAnchor(this.handles.tr);

    this.handles.tl.setCursor("nw-resize");
    this.handles.br.setCursor("se-resize");
    this.handles.tr.setCursor("ne-resize");
    this.handles.bl.setCursor("sw-resize");

/*
	this.handles["t"].setAnchor(this.handles["b"]);
	this.handles["b"].setAnchor(this.handles["t"]);
	this.handles["r"].setAnchor(this.handles["l"]);
	this.handles["l"].setAnchor(this.handles["r"]);
*/
  },
  remove: function() {
		for ( var i in this.handles ) {
			this.handles[i].removeShape();
		}
  },
  update: function() {
  	bbox = this.mRootShape.getBoundingBox();
//  	bbox = this.mBbox;
  	m = this.mRootShape.getGfxShape().getTransform();

		for ( var j in this.handles ) {
			this.handles[j].update(m, bbox);
		}
  }
});

dojo.declare("imgchf.handle.transformPoint", imgchf.rect, {
  initializer: function(id, aShape, p0, tranfcn, updatefcn) {
  	this.mRootShape = aShape;
  	this.setExtents(imgchf.handle.SIZE, imgchf.handle.SIZE);
 		this.setFill([255,255,255]);
	 	this.setStroke({color: [0, 0, 0], width: 1.0/imgchf.handle.SIZE});
  	this.transformfcn = tranfcn;
  	this.updatefcn = updatefcn;
  	this.p = p0;
  	
  	this.updatefcn(this, aShape.getTransform(), aShape.getBoundingBox());
  },
  createHandles: function() {
  	dojo.debug("transformPoint: createHandles returning false");
  	return false;
  },
  applyEffect: function(x, y) {
  	this.mRootShape.hidePoints();
  	this.transformfcn(this, x, y);
  },
  update: function(m, bbox) {
  	this.updatefcn(this, m, bbox);	
  },
  setAnchor: function(anchor) {
  	this.mAnchor = anchor;
  },
  getIndex: function() {
  	return -1;
  },
  delPoint: function() {
  }
});

dojo.declare("imgchf.handle.rotatePoint", imgchf.circle, {
  initializer: function(id, aShape, p0, tranfcn, updatefcn) {
  	this.mRootShape = aShape;
  	this.setRadius(imgchf.rotate.SIZE);
//	 	this.setStroke({color: [0, 0, 0], width: 2.0/imgchf.rotate.SIZE});
  	this.transformfcn = tranfcn;
  	this.updatefcn = updatefcn;
  	this.p = p0;
		this.rotateImage = surface.createImage({width:22, height:22, src: "/ic/symeditor/gfx_files/icon-rotate2.gif"});
		this.rotateImage.getEventSource().setAttribute('shapeid', id);
  	
  	this.updatefcn(this, aShape.getTransform(), aShape.getBoundingBox());
  },
  createHandles: function() {
  	dojo.debug("transformPoint: createHandles returning false");
  	return false;
  },
  applyEffect: function(x, y) {
  	this.mRootShape.hidePoints();
  	this.transformfcn(this, x, y);
  },
  update: function(m, bbox) {
  	this.updatefcn(this, m, bbox);	
  },
  setAnchor: function(anchor) {
  	this.mAnchor = anchor;
  },
  getIndex: function() {
  	return -1;
  },
  delPoint: function() {
  },
  removeShape: function() {
		surface.remove(this.mShape);
		surface.remove(this.rotateImage);
	}
  
});

dojo.declare("imgchf.handle.pointSelect", imgchf.circle, {
  initializer: function(id, aShape, p0, tranfcn, delfcn, updatefcn, aIndex) {
	 	this.mRootShape = aShape;
	 	this.setRadius(imgchf.handle.SIZE - 2);
	 	this.setFill([255,255,255]);
	 	this.setStroke({color: [0, 0, 0], width: 2.0/imgchf.handle.SIZE});
	 	this.transformfcn = tranfcn;
	 	this.deletefcn = delfcn;
	 	this.updatefcn = updatefcn;
	 	this.p = p0;
	 	this.mIndex = aIndex;
		this.setCursor("pointer");

//    dojo.debug("imgchf.handle.pointSelect created");
  	
//  	this.updatefcn(this, aShape.getTransform(), aShape.getGfxShape().getBoundingBox());
  },
  createHandles: function() {
  	dojo.debug("transformPoint: createHandles returning false");
  	return false;
  },
  applyEffect: function(x, y) {
  	this.transformfcn(this, x, y);
  },
  update: function(m, pt) {
  	this.updatefcn(this, m, pt);	
  },
  setAnchor: function(anchor) {
  	this.mAnchor = anchor;
  },
  setVisible: function() {
//	dojo.debug("in SetVisible");
    this.setFill([255,255,255,1.0]);
	 	this.setStroke({color: [0, 0, 0], width: 2.0/imgchf.handle.SIZE});
  },

  setInvisible: function() {
//	dojo.debug("in SetInvisible");
    this.setFill([255,255,255,0.001]);
   	this.setStroke();
  },
  delPoint: function() {
  	dojo.debug("del function called");
  	this.deletefcn(this);
  },
  setIndex: function(newI) {
  	this.mIndex = newI;
  },
  getIndex: function() {
  	return this.mIndex;
  }
});


