part of sprites;

double convertDegrees2Radians(double degrees) => degrees * math.PI/180.8;

double convertRadians2Degrees(double radians) => radians * 180.0/math.PI;

/// A base class for all objects that can be added to the sprite node tree and rendered to screen using [SpriteBox] and
/// [SpriteWidget].
///
/// The [Node] class itself doesn't render any content, but provides the basic functions of any type of node, such as
/// handling transformations and user input. To render the node tree, a root node must be added to a [SpriteBox] or a
/// [SpriteWidget]. Commonly used sub-classes of [Node] are [Sprite], [NodeWithSize], and many more upcoming subclasses.
///
/// Nodes form a hierarchical tree. Each node can have a number of children, and the transformation (positioning,
/// rotation, and scaling) of a node also affects its children.
class Node {

  // Member variables

  SpriteBox _spriteBox;
  Node _parent;

  Point _position = Point.origin;
  double _rotation = 0.0;

  Matrix4 _transformMatrix = new Matrix4.identity();
  Matrix4 _transformMatrixNodeToBox;
  Matrix4 _transformMatrixBoxToNode;

  double _scaleX = 1.0;
  double _scaleY = 1.0;

  double _skewX = 0.0;
  double _skewY = 0.0;

  /// The visibility of this node and its children.
  bool visible = true;

  double _zPosition = 0.0;
  int _addedOrder;
  int _childrenLastAddedOrder = 0;
  bool _childrenNeedSorting = false;
  Matrix4 _savedTotalMatrix;

  /// Decides if the node and its children is currently paused.
  ///
  /// A paused node will not receive any input events, update calls, or run any animations.
  ///
  ///     myNodeTree.paused = true;
  bool paused = false;

  bool _userInteractionEnabled = false;

  /// If set to true the node will receive multiple pointers, otherwise it will only receive events the first pointer.
  ///
  /// This property is only meaningful if [userInteractionEnabled] is set to true. Default value is false.
  ///
  ///     class MyCustomNode extends Node {
  ///       handleMultiplePointers = true;
  ///     }
  bool handleMultiplePointers = false;
  int _handlingPointer;

  List<Node>_children = [];

  ActionController _actions;

  /// The [ActionController] associated with this node.
  ///
  ///     myNode.actions.run(myAction);
  ActionController get actions {
    if (_actions == null) {
      _actions = new ActionController();
      if (_spriteBox != null) _spriteBox._actionControllers = null;
    }
    return _actions;
  }

  List<Constraint> _constraints;

  List<Constraint> get constraints {
    return _constraints;
  }

  set constraints(List<Constraint> constraints) {
    _constraints = constraints;
    if (_spriteBox != null) _spriteBox._constrainedNodes = null;
  }

  void applyConstraints(double dt) {
    if (_constraints == null) return;

    for (Constraint constraint in _constraints) {
      constraint.constrain(this, dt);
    }
  }

  // Constructors

  /// Creates a new [Node] without any transformation.
  ///
  ///     var myNode = new Node();
  Node() {
  }

  // Property setters and getters

  /// The [SpriteBox] this node is added to, or null if it's not currently added to a [SpriteBox].
  ///
  /// For most applications it's not necessary to access the [SpriteBox] directly.
  ///
  ///     // Get the transformMode of the sprite box
  ///     var transformMode = myNode.spriteBox.transformMode;
  SpriteBox get spriteBox => _spriteBox;

  /// The parent of this node, or null if it doesn't have a parent.
  ///
  ///     // Hide the parent
  ///     myNode.parent.visible = false;
  Node get parent => _parent;

  /// The rotation of this node in degrees.
  ///
  ///     myNode.rotation = 45.0;
  double get rotation => _rotation;

  void set rotation(double rotation) {
    assert(rotation != null);
    _rotation = rotation;
    invalidateTransformMatrix();
  }

  /// The position of this node relative to its parent.
  ///
  ///     myNode.position = new Point(42.0, 42.0);
  Point get position => _position;

  void set position(Point position) {
    assert(position != null);
    _position = position;
    invalidateTransformMatrix();
  }

  /// The skew along the x-axis of this node in degrees.
  ///
  ///     myNode.skewX = 45.0;
  double get skewX => _skewX;

  void set skewX (double skewX) {
    assert(skewX != null);
    _skewX = skewX;
    invalidateTransformMatrix();
  }

  /// The skew along the y-axis of this node in degrees.
  ///
  ///     myNode.skewY = 45.0;
  double get skewY => _skewY;

  void set skewY (double skewY) {
    assert(skewY != null);
    _skewY = skewY;
    invalidateTransformMatrix();
  }

  /// The draw order of this node compared to its parent and its siblings.
  ///
  /// By default nodes are drawn in the order that they have been added to a parent. To override this behavior the
  /// [zPosition] property can be used. A higher value of this property will force the node to be drawn in front of
  /// siblings that have a lower value. If a negative value is used the node will be drawn behind its parent.
  ///
  ///     nodeInFront.zPosition = 1.0;
  ///     nodeBehind.zPosition = -1.0;
  double get zPosition => _zPosition;

  void set zPosition(double zPosition) {
    assert(zPosition != null);
    _zPosition = zPosition;
    if (_parent != null) {
      _parent._childrenNeedSorting = true;
    }
  }

  /// The scale of this node relative its parent.
  ///
  /// The [scale] property is only valid if [scaleX] and [scaleY] are equal values.
  ///
  ///     myNode.scale = 5.0;
  double get scale {
    assert(_scaleX == _scaleY);
    return _scaleX;
  }

  void set scale(double scale) {
    assert(scale != null);
    _scaleX = _scaleY = scale;
    invalidateTransformMatrix();
  }

  /// The horizontal scale of this node relative its parent.
  ///
  ///     myNode.scaleX = 5.0;
  double get scaleX => _scaleX;

  void set scaleX(double scaleX) {
    assert(scaleX != null);
    _scaleX = scaleX;
    invalidateTransformMatrix();
  }

  /// The vertical scale of this node relative its parent.
  ///
  ///     myNode.scaleY = 5.0;
  double get scaleY => _scaleY;

  void set scaleY(double scaleY) {
    assert(scaleY != null);
    _scaleY = scaleY;
    invalidateTransformMatrix();
  }

  /// A list of the children of this node.
  ///
  /// This list should only be modified by using the [addChild] and [removeChild] methods.
  ///
  ///     // Iterate over a nodes children
  ///     for (Node child in myNode.children) {
  ///       // Do something with the child
  ///     }
  List<Node> get children {
    _sortChildren();
    return _children;
  }

  // Adding and removing children

  /// Adds a child to this node.
  ///
  /// The same node cannot be added to multiple nodes.
  ///
  ///     addChild(new Sprite(myImage));
  void addChild(Node child) {
    assert(child != null);
    assert(child._parent == null);

    _childrenNeedSorting = true;
    _children.add(child);
    child._parent = this;
    child._spriteBox = this._spriteBox;
    _childrenLastAddedOrder += 1;
    child._addedOrder = _childrenLastAddedOrder;
    if (_spriteBox != null) _spriteBox._registerNode(child);
  }

  /// Removes a child from this node.
  ///
  ///     removeChild(myChildNode);
  void removeChild(Node child) {
    assert(child != null);
    if (_children.remove(child)) {
      child._parent = null;
      child._spriteBox = null;
      if (_spriteBox != null) _spriteBox._deregisterNode(child);
    }
  }

  /// Removes this node from its parent node.
  ///
  ///     removeFromParent();
  void removeFromParent() {
    assert(_parent != null);
    _parent.removeChild(this);
  }

  /// Removes all children of this node.
  ///
  ///     removeAllChildren();
  void removeAllChildren() {
    for (Node child in _children) {
      child._parent = null;
      child._spriteBox = null;
    }
    _children = [];
    _childrenNeedSorting = false;
    if (_spriteBox != null) _spriteBox._deregisterNode(null);
  }

  void _sortChildren() {
    // Sort children primarily by zPosition, secondarily by added order
    if (_childrenNeedSorting) {
      _children.sort((Node a, Node b) {
        if (a._zPosition == b._zPosition) {
          return a._addedOrder - b._addedOrder;
        }
        else if (a._zPosition > b._zPosition) {
          return 1;
        }
        else {
          return -1;
        }
      });
      _childrenNeedSorting = false;
    }
  }

  // Calculating the transformation matrix

  /// The transformMatrix describes the transformation from the node's parent.
  ///
  /// You cannot set the transformMatrix directly, instead use the position, rotation and scale properties.
  ///
  ///     Matrix4 matrix = myNode.transformMatrix;
  Matrix4 get transformMatrix {
    if (_transformMatrix == null) {
      _transformMatrix = computeTransformMatrix();
    }
    return _transformMatrix;
  }

  /// Computes the transformation matrix of this node. This method can be
  /// overriden if a custom matrix is required. There is usually no reason to
  /// call this method directly.
  Matrix4 computeTransformMatrix() {
    double cx, sx, cy, sy;

    if (_rotation == 0.0) {
      cx = 1.0;
      sx = 0.0;
      cy = 1.0;
      sy = 0.0;
    }
    else {
      double radiansX = convertDegrees2Radians(_rotation);
      double radiansY = convertDegrees2Radians(_rotation);

      cx = math.cos(radiansX);
      sx = math.sin(radiansX);
      cy = math.cos(radiansY);
      sy = math.sin(radiansY);
    }

    // Create transformation matrix for scale, position and rotation
    Matrix4 matrix = new Matrix4(cy * _scaleX, sy * _scaleX, 0.0, 0.0,
               -sx * _scaleY, cx * _scaleY, 0.0, 0.0,
               0.0, 0.0, 1.0, 0.0,
              _position.x, _position.y, 0.0, 1.0);

    if (_skewX != 0.0 || _skewY != 0.0) {
      // Needs skew transform
      Matrix4 skew = new Matrix4(1.0, math.tan(radians(_skewX)), 0.0, 0.0,
                                 math.tan(radians(_skewY)), 1.0, 0.0, 0.0,
                                 0.0, 0.0, 1.0, 0.0,
                                 0.0, 0.0, 0.0, 1.0);
      matrix.multiply(skew);
    }

    return matrix;
  }

  /// Invalidates the current transform matrix. If the [computeTransformMatrix]
  /// method is overidden, this method should be called whenever a property
  /// changes that affects the matrix.
  void invalidateTransformMatrix() {
    _transformMatrix = null;
    _invalidateToBoxTransformMatrix();
  }

  void _invalidateToBoxTransformMatrix () {
    _transformMatrixNodeToBox = null;
    _transformMatrixBoxToNode = null;

    for (Node child in children) {
      child._invalidateToBoxTransformMatrix();
    }
  }

  // Transforms to other nodes

  Matrix4 _nodeToBoxMatrix() {
    assert(_spriteBox != null);
    if (_transformMatrixNodeToBox != null) {
      return _transformMatrixNodeToBox;
    }

    if (_parent == null) {
      // Base case, we are at the top
      assert(this == _spriteBox.rootNode);
      _transformMatrixNodeToBox = new Matrix4.copy(_spriteBox.transformMatrix).multiply(transformMatrix);
    }
    else {
      _transformMatrixNodeToBox = new Matrix4.copy(_parent._nodeToBoxMatrix()).multiply(transformMatrix);
    }
    return _transformMatrixNodeToBox;
  }

  Matrix4 _boxToNodeMatrix() {
    assert(_spriteBox != null);

    if (_transformMatrixBoxToNode != null) {
      return _transformMatrixBoxToNode;
    }

    _transformMatrixBoxToNode = new Matrix4.copy(_nodeToBoxMatrix());
    _transformMatrixBoxToNode.invert();

    return _transformMatrixBoxToNode;
  }

  /// Converts a point from the coordinate system of the [SpriteBox] to the local coordinate system of the node.
  ///
  /// This method is particularly useful when handling pointer events and need the pointers position in a local
  /// coordinate space.
  ///
  ///     Point localPoint = myNode.convertPointToNodeSpace(pointInBoxCoordinates);
  Point convertPointToNodeSpace(Point boxPoint) {
    assert(boxPoint != null);
    assert(_spriteBox != null);

    Vector4 v =_boxToNodeMatrix().transform(new Vector4(boxPoint.x, boxPoint.y, 0.0, 1.0));
    return new Point(v[0], v[1]);
  }

  /// Converts a point from the local coordinate system of the node to the coordinate system of the [SpriteBox].
  ///
  ///     Point pointInBoxCoordinates = myNode.convertPointToBoxSpace(localPoint);
  Point convertPointToBoxSpace(Point nodePoint) {
    assert(nodePoint != null);
    assert(_spriteBox != null);

    Vector4 v =_nodeToBoxMatrix().transform(new Vector4(nodePoint.x, nodePoint.y, 0.0, 1.0));
    return new Point(v[0], v[1]);
  }

  /// Converts a [point] from another [node]s coordinate system into the local coordinate system of this node.
  ///
  ///     Point pointInNodeASpace = nodeA.convertPointFromNode(pointInNodeBSpace, nodeB);
  Point convertPointFromNode(Point point, Node node) {
    assert(node != null);
    assert(point != null);
    assert(_spriteBox != null);
    assert(_spriteBox == node._spriteBox);

    Point boxPoint = node.convertPointToBoxSpace(point);
    Point localPoint = convertPointToNodeSpace(boxPoint);

    return localPoint;
  }

  // Hit test

  /// Returns true if the [point] is inside the node, the [point] is in the local coordinate system of the node.
  ///
  ///     myNode.isPointInside(localPoint);
  ///
  /// [NodeWithSize] provides a basic bounding box check for this method, if you require a more detailed check this
  /// method can be overridden.
  ///
  ///     bool isPointInside (Point nodePoint) {
  ///       double minX = -size.width * pivot.x;
  ///       double minY = -size.height * pivot.y;
  ///       double maxX = minX + size.width;
  ///       double maxY = minY + size.height;
  ///       return (nodePoint.x >= minX && nodePoint.x < maxX &&
  ///       nodePoint.y >= minY && nodePoint.y < maxY);
  ///     }
  bool isPointInside(Point point) {
    assert(point != null);

    return false;
  }

  // Rendering

  void _visit(PaintingCanvas canvas, Matrix4 totalMatrix) {
    assert(canvas != null);
    if (!visible) return;

    _prePaint(canvas, totalMatrix);
    _visitChildren(canvas, totalMatrix);
    _postPaint(canvas, totalMatrix);
  }

  void _prePaint(PaintingCanvas canvas, Matrix4 matrix) {
    _savedTotalMatrix = new Matrix4.copy(matrix);

    // Get the transformation matrix and apply transform
    matrix.multiply(transformMatrix);
  }

  /// Paints this node to the canvas.
  ///
  /// Subclasses, such as [Sprite], override this method to do the actual painting of the node. To do custom
  /// drawing override this method and make calls to the [canvas] object. All drawing is done in the node's local
  /// coordinate system, relative to the node's position. If you want to make the drawing relative to the node's
  /// bounding box's origin, override [NodeWithSize] and call the applyTransformForPivot method before making calls for
  /// drawing.
  ///
  ///     void paint(PaintingCanvas canvas) {
  ///       canvas.save();
  ///       applyTransformForPivot(canvas);
  ///
  ///       // Do painting here
  ///
  ///       canvas.restore();
  ///     }
  void paint(PaintingCanvas canvas) {
  }

  void _visitChildren(PaintingCanvas canvas, Matrix4 totalMatrix) {
    // Sort children if needed
    _sortChildren();

    int i = 0;

    // Visit children behind this node
    while (i < _children.length) {
      Node child = _children[i];
      if (child.zPosition >= 0.0) break;
      child._visit(canvas, totalMatrix);
      i++;
    }

    // Paint this node
    canvas.setMatrix(totalMatrix.storage);
    paint(canvas);

    // Visit children in front of this node
    while (i < _children.length) {
      Node child = _children[i];
      child._visit(canvas, totalMatrix);
      i++;
    }
  }

  void _postPaint(PaintingCanvas canvas, Matrix4 totalMatrix) {
    totalMatrix.setFrom(_savedTotalMatrix);
  }

  // Receiving update calls

  /// Called before a frame is drawn.
  ///
  /// Override this method to do any updates to the node or node tree before it's drawn to screen.
  ///
  ///     // Make the node rotate at a fixed speed
  ///     void update(double dt) {
  ///       rotation = rotation * 10.0 * dt;
  ///     }
  void update(double dt) {
  }

  /// Called whenever the [SpriteBox] is modified or resized, or if the device is rotated.
  ///
  /// Override this method to do any updates that may be necessary to correctly display the node or node tree with the
  /// new layout of the [SpriteBox].
  ///
  ///     void spriteBoxPerformedLayout() {
  ///       // Move some stuff around here
  ///     }
  void spriteBoxPerformedLayout() {
  }

  // Handling user interaction

  /// The node will receive user interactions, such as pointer (touch or mouse) events.
  ///
  ///     class MyCustomNode extends NodeWithSize {
  ///       userInteractionEnabled = true;
  ///     }
  bool get userInteractionEnabled => _userInteractionEnabled;

  void set userInteractionEnabled(bool userInteractionEnabled) {
    _userInteractionEnabled = userInteractionEnabled;
    if (_spriteBox != null) _spriteBox._eventTargets = null;
  }

  /// Handles an event, such as a pointer (touch or mouse) event.
  ///
  /// Override this method to handle events. The node will only receive events if the [userInteractionEnabled] property
  /// is set to true and the [isPointInside] method returns true for the position of the pointer down event (default
  /// behavior provided by [NodeWithSize]). Unless [handleMultiplePointers] is set to true, the node will only receive
  /// events for the first pointer that is down.
  ///
  /// Return true if the node has consumed the event, if an event is consumed it will not be passed on to nodes behind
  /// the current node.
  ///
  ///     // MyTouchySprite gets transparent when we touch it
  ///     class MyTouchySprite extends Sprite {
  ///
  ///       MyTouchySprite(Image img) : super (img) {
  ///         userInteractionEnabled = true;
  ///       }
  ///
  ///       bool handleEvent(SpriteBoxEvent event) {
  ///         if (event.type == 'pointerdown) {
  ///           opacity = 0.5;
  ///         }
  ///         else if (event.type == 'pointerup') {
  ///           opacity = 1.0;
  ///         }
  ///         return true;
  ///       }
  ///     }
  bool handleEvent(SpriteBoxEvent event) {
    return false;
  }
}
