var oTween;

var bLogoLoaded = false;
var bBubbleLoaded = false;
var bPointLoaded = false;

// задержка начального появления точки
var I_POINT_SHOW_DELAY = 2800;

// задержка реакции точки на объект
var I_OBJECT_OVER_DELAY = 500;

// задержка перед закрытием точки
var I_POINT_CLOSE_DELAY = 500;

// скорость полета точки
var I_POINT_SPEED = 8;

// минимальное расстояние полета при котором точка не становится в позу полета
var I_POINT_MIN_MOVE_DISTANCE_WITHOUT_ROTATE = 96;

// минимальное количество кадров анимации полета
var I_POINT_MIN_MOVE_DURATION = 12;

// смещение точки после появления
var I_POINT_ON_SHOW_OFFSET_X = 23;
var I_POINT_ON_SHOW_OFFSET_Y = 17;


/*+++++++++++++*/
/*    Point    */
/*+++++++++++++*/

var Point = {};

Point.Init = function(){

	// контейнер с флешкой-точкой
	Point.oPointContainer = document.getElementById('flash_point');
	// контейнер с флешкой-баблом
	Point.oBubbleContainer = document.getElementById('flash_bubble');

	if(Point.oPointContainer && Point.oBubbleContainer){

		// смещение указателя мыши внутри точки относительно верхнего левого угла точки (для таскания)
		Point.oOffset = {x: 0, y: 0};

		// размеры контейнера с точкой
		Point.oPointDimensions = {x: 100, y: 100};

		// размеры текущего бабла
		Point.oBubbleDimensions = {x: 1, y: 1};

		// объект к которому точка летит или собирается лететь
		Point.oMoveToObject = null;

		Point.bShow = false;
		Point.bDrag = false;
		Point.bMove = false;
		Point.bBubble = false;

		// объекты к которым точка может прилетать
		Point.aObjects = new Array();
	}
}

Point.IsInit = function(){
	if(Point.oPointContainer && Point.oBubbleContainer) {return true;}
	else {return false;}
}

Point.InitObjects = function(){
	if(Point.IsInit()){
		for (var iDivIdx = 0; (oDiv = document.getElementsByTagName('div')[iDivIdx]); iDivIdx++) {
			if (cmnMatch_class(oDiv, 'point_object')) {
				Point.aObjects[Point.aObjects.length] = new PointObject(oDiv);
			}
		}
	}
}

Point.StartShow = function(){
	if(Point.IsInit()){
		var oPointMoveToCoords = Logo.GetArrivalCoords();
		Point.oPointContainer.style.left = oPointMoveToCoords.x;
		Point.oPointContainer.style.top = oPointMoveToCoords.y;
		Point.oPointContainer.style.width = Point.oPointDimensions.x;
		Point.oPointContainer.style.height = Point.oPointDimensions.y;
		SendCommandToFlash('point', 'point_show');
	}
}

Point.Show = function(){
	if(Point.IsInit()){
		Point.bShow = true;

		// если есть кука, то летим к логотипу
		if(cmnGet_cookie("point")){
			Point.SetCookie();
			var oPointMoveToCoords = Logo.GetArrivalCoords();
			oPointMoveToCoords.x = oPointMoveToCoords.x + I_POINT_ON_SHOW_OFFSET_X;
			oPointMoveToCoords.y = oPointMoveToCoords.y + I_POINT_ON_SHOW_OFFSET_Y;
			Point.MoveToCoords(oPointMoveToCoords);
		}
		// иначе (т.е. пользователь первый раз зашел) летим к включателю иголки
		else {
			Point.SetCookie();
			var oNeedleSwitch = null;
			for (var i=0; i<Point.aObjects.length; i++) {
				if(Point.aObjects[i].GetId() == 'needle_switch') {
					oNeedleSwitch = Point.aObjects[i];
					break;
				}
			}
			if(oNeedleSwitch){
				Point.StartMove(oNeedleSwitch);
			}
		}
	}
}

Point.StartHide = function(){
	if(Point.IsInit()){
		Point.StartMove(Logo);
	}
}

Point.Hide = function(){
	if(Point.IsInit()){
		Point.oPointContainer.style.left = 1;
		Point.oPointContainer.style.top = 0;
		Point.oPointContainer.style.width = 1;
		Point.oPointContainer.style.height = 1;
		Point.oMoveToObject = null;
		Point.bShow = false;
		Point.SetCookie();
	}
}

Point.SetCookie = function(){
	if(Point.IsInit()){
		var dNow = new Date();
		var dExpires = new Date();
		dExpires.setTime( dNow.getTime() + 1000 * 60 * 60 * 24 * 365 );
		cmnSet_cookie( "point", ( Point.bShow ) ?  "true" : "false", dExpires );
	}
}

Point.GetPointDimensions = function(){
	if(Point.IsInit()){
		return {x: Point.oPointDimensions.x, y: Point.oPointDimensions.y};
	}
}

Point.StartDrag = function(iOffsetX, iOffsetY){
	if(Point.IsInit()){
		Point.oOffset = {x: iOffsetX, y: iOffsetY};
		Point.StopMove();
		Point.CloseBubble();
		Point.bDrag = true;
	}
}

Point.DoDrag = function(evt){
	if(Point.IsInit() && Point.bDrag && (evt=checkEvent(evt))){
		var iScrollTop = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
		Point.oPointContainer.style.left = (evt.clientX - Point.oOffset.x)+'px';
		Point.oPointContainer.style.top = (evt.clientY + iScrollTop - Point.oOffset.y)+'px';
		return cancelEvent(evt);
	}
}

Point.StopDrag = function(){
	if(Point.IsInit()){
		Point.bDrag = false;
		SendCommandToFlash('point', 'point_stop_drag');
	}
}

Point.StartMove = function(oObject){
	if(Point.IsInit() && Point.bShow && !Point.bDrag && oObject && Point.oMoveToObject != oObject && Point.oMoveToObject != Logo){
		Point.StopMove();
		Point.CloseBubble();

		// записываем объект к которому надо лететь
		Point.oMoveToObject = oObject;

		// позиция контейнера с точкой
		var oPointContainerPos = getAbsolutePos(Point.oPointContainer);

		// координаты подлета к объекту
		var oPointMoveToCoords = Point.oMoveToObject.GetArrivalCoords();

		// расстояние
		var iDistance = Math.sqrt( Math.pow((oPointMoveToCoords.x - oPointContainerPos.x), 2) + Math.pow((oPointMoveToCoords.y - oPointContainerPos.y), 2) );

		// вектор полета
		var iMovementVectorX = oPointMoveToCoords.x - oPointContainerPos.x;
		var iMovementVectorY = oPointMoveToCoords.y - oPointContainerPos.y;

		if(iDistance < I_POINT_MIN_MOVE_DISTANCE_WITHOUT_ROTATE){
			Point.DoMove();
		}
		else if (iMovementVectorX != 0 || iMovementVectorY != 0){
			var sArgs = 'point_rotate' + "," + iMovementVectorX + "," + iMovementVectorY;
			SendCommandToFlash('point', sArgs);
		}
		else if (!Point.bBubble){
			Point.SetBubble();
		}
	}
}

Point.DoMove = function(){
	if(Point.IsInit() && Point.oMoveToObject && !Point.bDrag){
		var oPointMoveToCoords = Point.oMoveToObject.GetArrivalCoords();
		Point.MoveToCoords(oPointMoveToCoords);
	}
}

Point.MoveToCoords = function(oPointMoveToCoords){
	if(Point.IsInit() && !Point.bDrag){

		var oPointContainerPos = getAbsolutePos(Point.oPointContainer);

		var iDistance = Math.sqrt( Math.pow((oPointMoveToCoords.x - oPointContainerPos.x), 2) + Math.pow((oPointMoveToCoords.y - oPointContainerPos.y), 2) );

		var iDuration = Math.ceil( iDistance / I_POINT_SPEED );

		if(iDuration < I_POINT_MIN_MOVE_DURATION){
			iDuration = I_POINT_MIN_MOVE_DURATION;
		}

		Point.bMove = true;

		oTween = new Tween(Point.oPointContainer, '', Math.easeOutCubic, 0.1, 100, iDuration);

		oTween.onMotionChanged=function(){
			Point.oPointContainer.style.left = ((oPointMoveToCoords.x - oPointContainerPos.x) * this.position / 100 + oPointContainerPos.x) + 'px';
			Point.oPointContainer.style.top = ((oPointMoveToCoords.y - oPointContainerPos.y) * this.position / 100 + oPointContainerPos.y) + 'px';
		}

		oTween.onMotionFinished=function(){
			Point.bMove = false;
			SendCommandToFlash('point', 'point_stop_move');
		}
	}
}

Point.StopMove = function(){
	if(Point.IsInit()){
		if(oTween) oTween.stop();
		Point.oMoveToObject = null;
		Point.bMove = false;
	}
}

Point.SetBubble = function(){
	if(Point.IsInit() && Point.oMoveToObject && !Point.bMove){
		var sArgs = 'bubble_set' + "," + Point.oMoveToObject.GetText();
		SendCommandToFlash('bubble', sArgs);
	}
}

Point.ShowBubble = function(iWidth, iHeight){
	if(Point.IsInit() && !Point.bMove){

		var oPointContainerPos = getAbsolutePos(Point.oPointContainer);
		var oBubbleContainerPos = {x: 0, y: 0};
		var oBubbleVector = {x: 0, y: 0};
		var sBubbleArrowPos;

		// если размеры требуемые для отображения нового бабла больше размеров уже открытого бабла
		if(iWidth > Point.oBubbleDimensions.x || iHeight > Point.oBubbleDimensions.y){

			if(oPointContainerPos.y - iHeight >= 0){
				if(Point.oMoveToObject && Point.oMoveToObject.GetBubblePos() == 'right') {
					oBubbleContainerPos.x = oPointContainerPos.x;
				}
				else {
					oBubbleContainerPos.x = oPointContainerPos.x - iWidth + Point.oPointDimensions.x;
				}
				oBubbleContainerPos.y = oPointContainerPos.y - iHeight;
				sBubbleArrowPos = 'bottom';
			}
			else {
				if(Point.oMoveToObject && Point.oMoveToObject.GetBubblePos() == 'right') {
					oBubbleContainerPos.x = oPointContainerPos.x + Point.oPointDimensions.x;
					sBubbleArrowPos = 'left';
				}
				else {
					oBubbleContainerPos.x = oPointContainerPos.x - iWidth;
					sBubbleArrowPos = 'right';
				}
				oBubbleContainerPos.y = oPointContainerPos.y;
			}

			Point.oBubbleContainer.style.left = oBubbleContainerPos.x;
			Point.oBubbleContainer.style.top = oBubbleContainerPos.y;

			Point.oBubbleContainer.style.width = iWidth;
			Point.oBubbleContainer.style.height = iHeight;
			Point.oBubbleDimensions = {x: iWidth, y: iHeight};
		}

		oBubbleVector.x = oBubbleContainerPos.x + (iWidth / 2) - oPointContainerPos.x - (Point.oPointDimensions.x / 2);
		oBubbleVector.y = oBubbleContainerPos.y + (iHeight / 2) - oPointContainerPos.y - (Point.oPointDimensions.y / 2);

		Point.bBubble = true;
		var sArgs = 'bubble_show' + "," + oBubbleVector.x + "," + oBubbleVector.y + "," + sBubbleArrowPos;
		SendCommandToFlash('bubble', sArgs);

		if(Point.oMoveToObject && Point.oMoveToObject.IsClosePoint()){
			var tmp = setTimeout("SendCommandToFlash('point', 'point_hide');", I_POINT_CLOSE_DELAY);
		}
		else {
			SendCommandToFlash('point', 'point_speak');
		}
	}
}

Point.CloseBubble = function(){
	if(Point.IsInit() && Point.bBubble){
		SendCommandToFlash('bubble', 'bubble_hide');
	}
}

Point.HideBubble = function(){
	if(Point.IsInit()){
		Point.oBubbleContainer.style.left = 0;
		Point.oBubbleContainer.style.top = 0;
		Point.oBubbleContainer.style.width = 1;
		Point.oBubbleContainer.style.height = 1;
		Point.oBubbleDimensions = {x: 1, y: 1};
		Point.bBubble = false;
	}
}


/*++++++++++++*/
/*    Logo    */
/*++++++++++++*/

var Logo = {};

Logo.Init = function(){
	// контейнер с логотипом
	Logo.oContainer = document.getElementById('Logo');
	Logo.Show();
}

Logo.Show = function(){
	SendCommandToFlash('logo', 'logo_show');
}

Logo.Hide = function(){
	SendCommandToFlash('logo', 'logo_hide');
}

Logo.GetArrivalCoords = function(){
	var oContainerPos = getAbsolutePos(Logo.oContainer);
	var oPointDimensions = Point.GetPointDimensions();

	var iToX = oContainerPos.x + I_LOGO_POINT_OFFSET_X - (oPointDimensions.x / 2);
	var iToY = oContainerPos.y + I_LOGO_POINT_OFFSET_Y - (oPointDimensions.y / 2);

	return {x: iToX, y: iToY};
}

Logo.GetBubblePos = function(){
	return 'right';
}

Logo.GetText = function(){
	if(window.sGoodbye){
		return sGoodbye;
	}
}

Logo.IsClosePoint = function(){
	return true;
}


/*+++++++++++++++++++++*/
/*    Point objects    */
/*+++++++++++++++++++++*/

var timerID = null;

function PointObject(oContainer){
	this.oContainer = oContainer;

	this.oText = getDescendantByClassName(this.oContainer, 'span', 'point_object_text');

	var me = this;
	cmnAdd_event(this.oContainer, 'mouseover', function(evt){me.MouseOver(evt);});
	cmnAdd_event(this.oContainer, 'mouseout', function(evt){me.MouseOut(evt);});
}

// вычисляем координаты подлета к объекту
PointObject.prototype.GetArrivalCoords = function(){
	var oContainerPos = getAbsolutePos(this.oContainer);
	var oPointDimensions = Point.GetPointDimensions();

	var iToX = 0;
	var iToY = 0;

	if(cmnMatch_class(this.oContainer, 'arrival_right')){
		iToX = oContainerPos.x + this.oContainer.offsetWidth;
	}
	else {
		iToX = oContainerPos.x - oPointDimensions.x;
	}

	if(cmnMatch_class(this.oContainer, 'arrival_bottom')){
		iToY = oContainerPos.y + this.oContainer.offsetHeight - oPointDimensions.y;
	}
	else {
		iToY = oContainerPos.y;
	}

	return {x: iToX, y: iToY};
}

PointObject.prototype.GetId = function(){
	return this.oContainer.id;
}

// выдаем с какой стороны показывать бабл (слева/справа)
// по умолчанию бабл показывается сверху, но если сверху не хватает места, то тогда слева/справа
PointObject.prototype.GetBubblePos = function(){
	if(cmnMatch_class(this.oContainer, 'arrival_right')){
		return 'right';
	}
	else {
		return 'left';
	}
}

// выдаем текст объекта, который появится в бабле
PointObject.prototype.GetText = function(){
	if(this.oText){
		return this.oText.innerHTML;
	}
}

PointObject.prototype.MouseOver = function(evt){
	var me = this;
	timerID = setTimeout(function(){Point.StartMove(me);}, I_OBJECT_OVER_DELAY);
}

PointObject.prototype.MouseOut = function(evt){
	clearTimeout(timerID);
}

PointObject.prototype.IsClosePoint = function(){
	return false;
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* Для связи с флешом (функции которые вызывает флеш) */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++*/

function onFlashLoad(sFlashId){
	//alert(sFlashId);
	switch (sFlashId) {
		case 'logo':
			bLogoLoaded = true;
			break;
		case 'bubble':
			bBubbleLoaded = true;
			break;
		case 'point':
			bPointLoaded = true;
			break;
	}
	if(bLogoLoaded && bBubbleLoaded && bPointLoaded){
		Logo.Init();
		Point.Init();
		Point.InitObjects();
		if( cmnGet_cookie("point") != "false" ){
			var tmp = setTimeout(function(){Logo.Hide(); Point.StartShow();}, I_POINT_SHOW_DELAY);
		}
	}
}

function onLogoPress(){
	Point.StartShow();
}

function onPointPress(iOffsetX, iOffsetY){
	Point.StartDrag(iOffsetX, iOffsetY);
}

function onPointRelease(iOffsetX, iOffsetY){
	Point.StopDrag();
}

function onBubbleSet(iWidth, iHeight){
	Point.ShowBubble(iWidth, iHeight);
}

function onFlashReady(sActionType){
	//alert(sActionType);
	switch (sActionType) {
		case 'point_show':
			Point.Show();
			break;
		case 'point_rotate':
			Point.DoMove();
			break;
		case 'point_stop_move':
			Point.SetBubble();
			break;
		case 'bubble_hide':
			Point.HideBubble();
			break;
		case 'point_hide':
			Point.CloseBubble();
			Point.Hide();
			Logo.Show();
			break;
	}
}

function onStartHide(){
	Point.StartHide();
}


cmnAdd_event(document, 'mousemove', Point.DoDrag);

function dalert(str){
	document.getElementById('debug').innerHTML+=str+'<br />';
}

document.ondragstart=document.ondrag=document.onselectstart=function(){return !Point.bDrag;};