//
//キャラクター
//

function StageObject(ownerStage, args){
	this.ownerStage = ownerStage;
	//左上隅の座標
	this.origin = new Point2D(10, 10);
	//左上から右下までのサイズ
	this.size = new Point2D(32, 32);
	this.attribute = {};
	this.constructorArgs = args;
	this.opacity = 1.0; 		// 透明度　(透明) 0.0 〜 1.0 (不透明)
	this.ownerUID = 0;
	this.objectID = 0;
	// PCDSLなどから利用できるID
	this.id = "";
	//0以外の場合、ネットワーク同期時にアイテムは全体でただ一つだけ!!(ネットワーク同期無効なら無視される)
	this.extObjectId = 0;
	
	this.isPhantom = false;
	//当たり判定のマージンの指定
	this.collisionMargin = new OffsetBox(0, 0, 0, 0);
	this.collidingRange  = 6;
	//衝突方向フラグは、移動するオブジェクトなら移動時に定期的にチェックをかけて設定します。
	//それ以外の場合は任意のタイミングでchecktouchingDirectionを呼び出すべし。
	this.touchingDirection = 0;
	this.collidedObjects = new Array();
	
	this.forceTopMost = false;
}
StageObject.prototype = {
	className:"StageObject",
	tick: function(){
		//再描画のタイミングごとに呼ばれる。
	},
	draw: function(x, y){
		//実際の描画のみを行う。計算はtickで行う。
		//ユーザー名を表示
		if(this.ownerUID != 0){
			var c = this.ownerStage.mainContext;
			c.save();
			c.font = "normal 12px sans-serif";
			drawText(c, this.ownerStage.manager.userManager.getUserNameByUID(this.ownerUID), x, y - 20);
			c.restore();
		}
	},
	debugDraw: function(x, y){
		//衝突マップに描画
		var c = this.ownerStage.collisionMapContext;
		c.save();
		c.beginPath();
		c.moveTo(x + this.collisionMargin.left, y + this.collisionMargin.top);
		c.lineTo(x + this.collisionMargin.left, y + this.size.y - this.collisionMargin.bottom);
		c.lineTo(x + this.size.x - this.collisionMargin.right, y + this.size.y - this.collisionMargin.bottom);
		c.lineTo(x + this.size.x - this.collisionMargin.right, y + this.collisionMargin.top);
		c.closePath();
		c.stroke();
		c.restore();
	},
	bindAttribute: function(attr)
	{
		//更新データを準備するときに呼ばれる
		this.attribute["sX"] = this.size.x;
		this.attribute["sY"] = this.size.y;
	},
	updateAttribute: function()
	{
		//更新データが来たときに呼ばれる
		if(this.attribute.sX){
			this.size.x = this.attribute.sX;
		}
		if(this.attribute.sY){
			this.size.y = this.attribute.sY;
		}
	},
	// 1 - - +
	// |     |
	// |     |
	// + - - 2
	isOverlappedWith: function(x1, y1, x2, y2){
		//オブジェクト本体部分に重なるかどうかを調べる
		//この関数がfalseを返した時の引数の範囲へはオブジェクトが移動できる。
		//trueかつisPhantom==falseの時は衝突する。
		var o = this.origin;
		var c = this.collisionMargin;
		var s = this.size;
		return (x2 >= (o.x + c.left)) && (x1 < (o.x + s.x - c.right)) && (y2 >= (o.y + c.top)) && (y1 < (o.y + s.y - c.bottom));
	},
	isOverlappedWithLocatedObject: function(obj, x, y){
		//(x, y)にobjがあるときのオブジェクト本体範囲に、自分のオブジェクト本体部分に重なるかどうかを調べる
		//この関数がfalseを返した時の引数の範囲へはオブジェクトが移動できる。]
		var c = obj.collisionMargin;
		var s = obj.size;
		return this.isOverlappedWith(x + c.left, y + c.top, x + s.x - c.right - 1, y + s.y - c.bottom - 1);
	},
	//     + - - +
	//     |     |
	// + - 0 - - + - +
	// |   |     |   |
	// |   |     |   |
	// + - + - - 1 - +
	//     |     |
	//     + - - +
	checkTouchingDirection: function(){
		//衝突方向を調べる。
		this.touchingDirection = 0;
		this.collidedObjects = new Array();
		var d = this.ownerStage.stageObjectLinearList;
		for(var i = 0, i_max = d.length; i < i_max; i++){
			var obj = d[i];
			var c = this.collisionMargin;
			var r = this.collidingRange;
			// CollisonBody
			var cbx0 = this.origin.x + c.left;
			var cby0 = this.origin.y + c.top;
			var cbx1 = this.origin.x + this.size.x - 1 - c.right;
			var cby1 = this.origin.y + this.size.y - 1 - c.bottom;
			// CollisionFrame範囲内か確認
			if(obj.isOverlappedWith(cbx0 - r, cby0 - r, cbx1 + r, cby1 + r) && obj !== this && !obj.isPhantom){
				//衝突の可能性があるので確認
				if(obj.isOverlappedWith(cbx0, cby0, cbx1, cby1)){
					//body
					this.touchingDirection |= CollideBody;
				}
				if(obj.isOverlappedWith(cbx0, cby0 - r, cbx1, cby0 - 1)){
					//top
					this.touchingDirection |= CollideTop;
				}
				if(obj.isOverlappedWith(cbx0, cby1 + 1, cbx1, cby1 + r)){
					//bottom
					this.touchingDirection |= CollideBottom;
				}
				if(obj.isOverlappedWith(cbx0 - r, cby0, cbx0 - 1, cby1)){
					//left
					this.touchingDirection |= CollideLeft;
				}
				if(obj.isOverlappedWith(cbx1 + 1, cby0, cbx1 + r, cby1)){
					//right
					this.touchingDirection |= CollideRight;
				}
				
			}
		}
	},
	getSyncData: function(){
		this.bindAttribute();
		return this.origin.x.toString() + "|" + 
			this.origin.y.toString() + "|" + 
			this.movingSpeed.x.toString() + "|" +  
			this.movingSpeed.y.toString() + "|" + 
			this.className + "|" + 
			parseArrayToStringSource(this.attribute) + "|" + 
			parseArrayToStringSource(this.constructorArgs);
	},
};

