// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:sky' as sky;

import 'package:sky/painting/text_style.dart';
import 'package:sky/rendering/box.dart';
import 'package:sky/rendering/object.dart';

abstract class InlineBase {
  sky.Node _toDOM(sky.Document owner);
  String toString([String prefix = '']);

  void _applyStyleToContainer(sky.Element container) {
  }
}

class InlineText extends InlineBase {
  InlineText(this.text) {
    assert(text != null);
  }

  final String text;

  sky.Node _toDOM(sky.Document owner) {
    return owner.createText(text);
  }

  bool operator ==(other) => other is InlineText && text == other.text;
  int get hashCode => text.hashCode;

  String toString([String prefix = '']) => '${prefix}InlineText: "${text}"';
}

class InlineStyle extends InlineBase {
  InlineStyle(this.style, this.children) {
    assert(style != null);
    assert(children != null);
  }

  final TextStyle style;
  final List<InlineBase> children;

  sky.Node _toDOM(sky.Document owner) {
    sky.Element parent = owner.createElement('t');
    style.applyToCSSStyle(parent.style);
    for (InlineBase child in children) {
      parent.appendChild(child._toDOM(owner));
    }
    return parent;
  }

  void _applyStyleToContainer(sky.Element container) {
    style.applyToContainerCSSStyle(container.style);
  }

  bool operator ==(other) {
    if (identical(this, other))
      return true;
    if (other is! InlineStyle
        || style != other.style
        || children.length != other.children.length)
      return false;
    for (int i = 0; i < children.length; ++i) {
      if (children[i] != other.children[i])
        return false;
    }
    return true;
  }

  int get hashCode {
    int value = 373;
    value = 37 * value + style.hashCode;
    for (InlineBase child in children)
      value = 37 * value + child.hashCode;
    return value;
  }

  String toString([String prefix = '']) {
    List<String> result = [];
    result.add('${prefix}InlineStyle:');
    var indent = '${prefix}  ';
    result.add('${style.toString(indent)}');
    for (InlineBase child in children) {
      result.add(child.toString(indent));
    }
    return result.join('\n');
  }
}

// Unfortunately, using full precision floating point here causes bad layouts
// because floating point math isn't associative. If we add and subtract
// padding, for example, we'll get different values when we estimate sizes and
// when we actually compute layout because the operations will end up associated
// differently. To work around this problem for now, we round fractional pixel
// values up to the nearest whole pixel value. The right long-term fix is to do
// layout using fixed precision arithmetic.
double _applyFloatingPointHack(double layoutValue) {
  return layoutValue.ceilToDouble();
}

class RenderParagraph extends RenderBox {

  RenderParagraph(InlineBase inlineValue) {
    _layoutRoot.rootElement = _document.createElement('p');
    inline = inlineValue;
  }

  final sky.Document _document = new sky.Document();
  final sky.LayoutRoot _layoutRoot = new sky.LayoutRoot();

  BoxConstraints _constraintsForCurrentLayout; // when null, we don't have a current layout

  InlineBase _inline;
  InlineBase get inline => _inline;
  void set inline (InlineBase value) {
    if (_inline == value)
      return;
    _inline = value;
    _layoutRoot.rootElement.setChild(_inline._toDOM(_document));
    _layoutRoot.rootElement.removeAttribute('style');
    _inline._applyStyleToContainer(_layoutRoot.rootElement);
    _constraintsForCurrentLayout = null;
    markNeedsLayout();
  }

  void _layout(BoxConstraints constraints) {
    assert(constraints != null);
    if (_constraintsForCurrentLayout == constraints)
      return; // already cached this layout
    _layoutRoot.maxWidth = constraints.maxWidth;
    _layoutRoot.minWidth = constraints.minWidth;
    _layoutRoot.minHeight = constraints.minHeight;
    _layoutRoot.maxHeight = constraints.maxHeight;
    _layoutRoot.layout();
    _constraintsForCurrentLayout = constraints;
  }

  double getMinIntrinsicWidth(BoxConstraints constraints) {
    _layout(constraints);
    return constraints.constrainWidth(
        _applyFloatingPointHack(_layoutRoot.rootElement.minContentWidth));
  }

  double getMaxIntrinsicWidth(BoxConstraints constraints) {
    _layout(constraints);
    return constraints.constrainWidth(
        _applyFloatingPointHack(_layoutRoot.rootElement.maxContentWidth));
  }

  double _getIntrinsicHeight(BoxConstraints constraints) {
    _layout(constraints);
    return constraints.constrainHeight(
        _applyFloatingPointHack(_layoutRoot.rootElement.height));
  }

  double getMinIntrinsicHeight(BoxConstraints constraints) {
    return _getIntrinsicHeight(constraints);
  }

  double getMaxIntrinsicHeight(BoxConstraints constraints) {
    return _getIntrinsicHeight(constraints);
  }

  double computeDistanceToActualBaseline(TextBaseline baseline) {
    assert(!needsLayout);
    _layout(constraints);
    sky.Element root = _layoutRoot.rootElement;
    switch (baseline) {
      case TextBaseline.alphabetic: return root.alphabeticBaseline;
      case TextBaseline.ideographic: return root.ideographicBaseline;
    }
  }

  void performLayout() {
    _layout(constraints);
    sky.Element root = _layoutRoot.rootElement;
    // rootElement.width always expands to fill, use maxContentWidth instead.
    size = constraints.constrain(new Size(_applyFloatingPointHack(root.maxContentWidth),
                                          _applyFloatingPointHack(root.height)));
  }

  void paint(PaintingCanvas canvas, Offset offset) {
    // Ideally we could compute the min/max intrinsic width/height with a
    // non-destructive operation. However, currently, computing these values
    // will destroy state inside the layout root. If that happens, we need to
    // get back the correct state by calling _layout again.
    //
    // TODO(abarth): Make computing the min/max intrinsic width/height
    // a non-destructive operation.
    // TODO(ianh): Make LayoutRoot support a paint offset so we don't
    // need to translate for each span of text.
    _layout(constraints);
    canvas.translate(offset.dx, offset.dy);
    _layoutRoot.paint(canvas);
    canvas.translate(-offset.dx, -offset.dy);
  }

  // we should probably expose a way to do precise (inter-glpyh) hit testing

  String debugDescribeSettings(String prefix) {
    String result = '${super.debugDescribeSettings(prefix)}';
    result += '${prefix}inline:\n${inline.toString("$prefix  ")}\n';
    return result;
  }
}
