void EditorBodyControl::InitMoving(const Vector2 & point)
{
	//init planeNormal
	ArrowsNode* arrowsNode = GetArrowsNode(false);
	if (!arrowsNode) return;
	switch (arrowsNode->GetModAxis())
	{
		case ArrowsNode::AXIS_X:
		case ArrowsNode::AXIS_Y:
		case ArrowsNode::AXIS_XY:
			planeNormal = Vector3(0,0,1);
			break;
		case ArrowsNode::AXIS_Z:
		case ArrowsNode::AXIS_YZ:
			planeNormal = Vector3(1,0,0);
			break;
		case ArrowsNode::AXIS_XZ:
			planeNormal = Vector3(0,1,0);
			break;
		default:
			break;
	}

	Vector3 from, dir;
	GetCursorVectors(&from, &dir, point);
    GetIntersectionVectorWithPlane(from, dir, planeNormal, rotationCenter, startDragPoint);
}	
void EditorBodyControl::PrepareModMatrix(const Vector2 & point)
{
	float32 winx = point.x - touchStart.x;
	float32 winy = point.y - touchStart.y;
	
	Matrix4 modification;
	modification.Identity();

	ArrowsNode* arrowsNode = GetArrowsNode(false);
	if (!arrowsNode)
		return;

	if (GetModificationMode() == ResourceEditor::MODIFY_MOVE)
	{
		Vector3 from, dir;
		GetCursorVectors(&from, &dir, point);
		
		Vector3 currPoint;
		bool result = GetIntersectionVectorWithPlane(from, dir, planeNormal, rotationCenter, currPoint);
		
		if (result)
		{
			
			if (arrowsNode)
			{
				switch (arrowsNode->GetModAxis())
				{
					case ArrowsNode::AXIS_X:
						currPoint.y = startDragPoint.y;
						currPoint.z = startDragPoint.z;
						break;
					case ArrowsNode::AXIS_Y:
						currPoint.x = startDragPoint.x;
						currPoint.z = startDragPoint.z;
						break;
					case ArrowsNode::AXIS_Z:
						currPoint.x = startDragPoint.x;
						currPoint.y = startDragPoint.y;
						break;
                    
					default:
						break;
				}
				modification.CreateTranslation(currPoint - startDragPoint);
			}
		}
	}
	else if (GetModificationMode() == ResourceEditor::MODIFY_ROTATE)
	{
		Matrix4 d;
		switch (arrowsNode->GetModAxis())
		{
			case ArrowsNode::AXIS_X:
			case ArrowsNode::AXIS_Y:
				modification.CreateRotation(vect[arrowsNode->GetModAxis()], winy / 100.0f);
				break;
			case ArrowsNode::AXIS_Z:
				modification.CreateRotation(vect[arrowsNode->GetModAxis()], winx / 100.0f);
				break;
			case ArrowsNode::AXIS_XY:
				modification.CreateRotation(vect[ArrowsNode::AXIS_X], winx / 100.0f);
				d.CreateRotation(vect[ArrowsNode::AXIS_Y], winy / 100.0f);
				modification *= d;
				break;
			case ArrowsNode::AXIS_YZ:
				modification.CreateRotation(vect[ArrowsNode::AXIS_Y], winx / 100.0f);
				d.CreateRotation(vect[ArrowsNode::AXIS_Z], winy / 100.0f);
				modification *= d;
				break;
			case ArrowsNode::AXIS_XZ:
				modification.CreateRotation(vect[ArrowsNode::AXIS_X], winx / 100.0f);
				d.CreateRotation(vect[ArrowsNode::AXIS_Z], winy / 100.0f);
				modification *= d;
				break;
			default:
				break;
		}
		modification = (translate1 * modification) * translate2;
		
	}
	else if (GetModificationMode() == ResourceEditor::MODIFY_SCALE)
	{
		float kf = winx / 100.0f;
		if (kf < -1.0)
			kf = - kf - 2.0;
		modification.CreateScale(Vector3(1,1,1) + Vector3(1,1,1) * kf);
		modification = (translate1 * modification) * translate2;
	}
	currTransform = startTransform * modification;
}
bool EditorBodyControl::ProcessMouse(UIEvent *event)
{
	Entity * selection = scene->GetProxy();
	//selection with second mouse button
    
	if (event->tid == UIEvent::BUTTON_1)
	{
		if (event->phase == UIEvent::PHASE_BEGAN)
		{
			isDrag = false;
			inTouch = true;
			touchStart = event->point;

			if (selection)
			{
				modifiedNode = selection;
				transformBeforeModification = selection->GetLocalTransform();
			}
		}
		else if (event->phase == UIEvent::PHASE_DRAG)
		{
			if (!isDrag)
			{
				Vector2 d = event->point - touchStart;
				
				if (selection && d.Length() > 5 && InModificationMode())
				{
					ArrowsNode* arrowsNode = GetArrowsNode(false);
					if (arrowsNode && arrowsNode->GetModAxis() != ArrowsNode::AXIS_NONE)
					{
						isDrag = true;
						if (InputSystem::Instance()->GetKeyboard()->IsKeyPressed(DVKEY_SHIFT))
						{
							originalNode = scene->GetProxy();

							//create temporary node to calculate transform
							modifiedNode = originalNode->Clone();
							originalNode->GetParent()->AddNode(modifiedNode);
							SelectNode(modifiedNode);
							selection = modifiedNode;

							//store original transform
							transformBeforeModification = modifiedNode->GetLocalTransform();
						}

						if (selection)
						{
							scene->SetBulletUpdate(selection, false);

							inTouch = true;
							touchStart = event->point;
						
							startTransform = selection->GetLocalTransform();
						
							InitMoving(event->point);
						
							translate1.CreateTranslation(-rotationCenter);
							translate2.CreateTranslation(rotationCenter);
						
							//calculate koefficient for moving
							Camera * cam = scene->GetCurrentCamera();
							const Vector3 & camPos = cam->GetPosition();
							const Matrix4 & wt = selection->GetWorldTransform();
							Vector3 objPos = Vector3(0,0,0) * wt;
							Vector3 dir = objPos - camPos;
							moveKf = (dir.Length() - cam->GetZNear()) * 0.003;
						}
					}
				}
			}
			else
			{
				if (selection && InModificationMode())
				{
                    Landscape *landscape = dynamic_cast<Landscape *>(selection);
                    if(!landscape)
                    {
                        PrepareModMatrix(event->point);

						if (IsLandscapeRelative())
						{
							currTransform = currTransform * GetLandscapeOffset(currTransform);
						}

						selection->SetLocalTransform(currTransform);

                        if(currentGraph)
                        {
                            currentGraph->UpdateMatricesForCurrentNode();
                        }
                    }
				}
			}
		}
		else if (event->phase == UIEvent::PHASE_ENDED)
		{
			inTouch = false;
			if (isDrag)
			{
				// originalNode should be non-zero only when clone node
				if (originalNode)
				{
					// Get final transform from temporary node
					Matrix4 transform = modifiedNode->GetLocalTransform();

					// Remove temporary node
					RemoveSelectedSGNode();
					SafeRelease(modifiedNode);
					
					CommandCloneAndTransform* cmd = new CommandCloneAndTransform(originalNode,
																				 transform,
																				 this,
																				 scene->collisionWorld);
					CommandsManager::Instance()->ExecuteAndRelease(cmd, scene);
					originalNode = NULL;

					// update selection to newly created node
					selection = scene->GetProxy();
				}
				else
				{
					CommandsManager::Instance()->ExecuteAndRelease(new CommandTransformObject(modifiedNode,
																							  transformBeforeModification,
																							  modifiedNode->GetLocalTransform()),
																   scene);
				}

				if (selection)
				{
					scene->SetBulletUpdate(selection, true);
				}
			}
			else
			{
				Vector3 from, dir;
				GetCursorVectors(&from, &dir, event->point);
				Vector3 to = from + dir * 1000.0f;
				scene->TrySelection(from, to);
				selection = scene->GetProxy();
				SelectNodeAtTree(selection);
			}
		}
	}
	else
	{
		cameraController->SetSelection(selection);
        
        if (event->phase == UIEvent::PHASE_KEYCHAR)
        {
            UITextField *tf = dynamic_cast<UITextField *>(UIControlSystem::Instance()->GetFocusedControl());
            if(!tf)
            {
                cameraController->Input(event);
            }
        }
        else
        {
            cameraController->Input(event);
        }
	}

	ArrowsNode* arrowsNode = GetArrowsNode(false);
	if (arrowsNode && arrowsNode->GetVisible() && !inTouch && event->phase != UIEvent::PHASE_KEYCHAR)
	{
		Vector3 from, dir;
		GetCursorVectors(&from, &dir, event->point);
		Vector3 to = from + dir * 1000.0f;
		arrowsNode->ProcessMouse(event, from, dir);
	}
	
    return true;
}