// Copyright 2016 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.

/// A token that composes an expression. There are several kinds of tokens
/// that represent arithmetic operation symbols, numbers and pieces of numbers.
/// We need to represent pieces of numbers because the user may have only
/// entered a partial expression so far.
class ExpressionToken {
  ExpressionToken(this.stringRep);

  final String stringRep;

  @override
  String toString() => stringRep;
}

/// A token that represents a number.
class NumberToken extends ExpressionToken {
  NumberToken(String stringRep, this.number) : super(stringRep);

  NumberToken.fromNumber(num number) : this('$number', number);

  final num number;
}

/// A token that represents an integer.
class IntToken extends NumberToken {
  IntToken(String stringRep) : super(stringRep, int.parse(stringRep));
}

/// A token that represents a floating point number.
class FloatToken extends NumberToken {
  FloatToken(String stringRep) : super(stringRep, _parse(stringRep));

  static double _parse(String stringRep) {
    String toParse = stringRep;
    if (toParse.startsWith('.'))
      toParse = '0' + toParse;
    if (toParse.endsWith('.'))
      toParse = toParse + '0';
    return double.parse(toParse);
  }
}

/// A token that represents a number that is the result of a computation.
class ResultToken extends NumberToken {
  ResultToken(num number) : super.fromNumber(round(number));

  /// rounds `number` to 14 digits of precision. A double precision
  /// floating point number is guaranteed to have at least this many
  /// decimal digits of precision.
  static num round(num number) {
    if (number is int)
      return number;
    return double.parse(number.toStringAsPrecision(14));
  }
}

/// A token that represents the unary minus prefix.
class LeadingNegToken extends ExpressionToken {
  LeadingNegToken() : super('-');
}

enum Operation { Addition, Subtraction, Multiplication, Division }

/// A token that represents an arithmetic operation symbol.
class OperationToken extends ExpressionToken {
  OperationToken(this.operation)
   : super(opString(operation));

  Operation operation;

  static String opString(Operation operation) {
    switch (operation) {
      case Operation.Addition:
        return ' + ';
      case Operation.Subtraction:
        return ' - ';
      case Operation.Multiplication:
        return '  \u00D7  ';
      case Operation.Division:
        return '  \u00F7  ';
    }
    assert(operation != null);
    return null;
  }
}

/// As the user taps different keys the current expression can be in one
/// of several states.
enum ExpressionState {
  /// The expression is empty or an operation symbol was just entered.
  /// A new number must be started now.
  Start,

  /// A minus sign was entered as a leading negative prefix.
  LeadingNeg,

  /// We are in the midst of a number without a point.
  Number,

  /// A point was just entered.
  Point,

  /// We are in the midst of a number with a point.
  NumberWithPoint,

  /// A result is being displayed
  Result,
}

/// An expression that can be displayed in a calculator. It is the result
/// of a sequence of user entries. It is represented by a sequence of tokens.
///
/// The tokens are not in one to one correspondence with the key taps because we
/// use one token per number, not one token per digit. A [CalcExpression] is
/// immutable. The `append*` methods return a new [CalcExpression] that
/// represents the appropriate expression when one additional key tap occurs.
class CalcExpression {
  CalcExpression(this._list, this.state);

  CalcExpression.empty()
    : this(<ExpressionToken>[], ExpressionState.Start);

  CalcExpression.result(FloatToken result)
    : _list = <ExpressionToken>[],
      state = ExpressionState.Result {
    _list.add(result);
  }

  /// The tokens comprising the expression.
  final List<ExpressionToken> _list;
  /// The state of the expression.
  final ExpressionState state;

  /// The string representation of the expression. This will be displayed
  /// in the calculator's display panel.
  @override
  String toString() {
    final StringBuffer buffer = StringBuffer('');
    buffer.writeAll(_list);
    return buffer.toString();
  }

  /// Append a digit to the current expression and return a new expression
  /// representing the result. Returns null to indicate that it is not legal
  /// to append a digit in the current state.
  CalcExpression appendDigit(int digit) {
    ExpressionState newState = ExpressionState.Number;
    ExpressionToken newToken;
    final List<ExpressionToken> outList = _list.toList();
    switch (state) {
      case ExpressionState.Start:
        // Start a new number with digit.
        newToken = IntToken('$digit');
        break;
      case ExpressionState.LeadingNeg:
        // Replace the leading neg with a negative number starting with digit.
        outList.removeLast();
        newToken = IntToken('-$digit');
        break;
      case ExpressionState.Number:
        final ExpressionToken last = outList.removeLast();
        newToken = IntToken('${last.stringRep}$digit');
        break;
      case ExpressionState.Point:
      case ExpressionState.NumberWithPoint:
        final ExpressionToken last = outList.removeLast();
        newState = ExpressionState.NumberWithPoint;
        newToken = FloatToken('${last.stringRep}$digit');
        break;
      case ExpressionState.Result:
        // Cannot enter a number now
        return null;
    }
    outList.add(newToken);
    return CalcExpression(outList, newState);
  }

  /// Append a point to the current expression and return a new expression
  /// representing the result. Returns null to indicate that it is not legal
  /// to append a point in the current state.
  CalcExpression appendPoint() {
    ExpressionToken newToken;
    final List<ExpressionToken> outList = _list.toList();
    switch (state) {
      case ExpressionState.Start:
        newToken = FloatToken('.');
        break;
      case ExpressionState.LeadingNeg:
      case ExpressionState.Number:
        final ExpressionToken last = outList.removeLast();
        newToken = FloatToken(last.stringRep + '.');
        break;
      case ExpressionState.Point:
      case ExpressionState.NumberWithPoint:
      case ExpressionState.Result:
        // Cannot enter a point now
        return null;
    }
    outList.add(newToken);
    return CalcExpression(outList, ExpressionState.Point);
  }

  /// Append an operation symbol to the current expression and return a new
  /// expression representing the result. Returns null to indicate that it is not
  /// legal to append an operation symbol in the current state.
  CalcExpression appendOperation(Operation op) {
    switch (state) {
      case ExpressionState.Start:
      case ExpressionState.LeadingNeg:
      case ExpressionState.Point:
        // Cannot enter operation now.
        return null;
      case ExpressionState.Number:
      case ExpressionState.NumberWithPoint:
      case ExpressionState.Result:
        break;
    }
    final List<ExpressionToken> outList = _list.toList();
    outList.add(OperationToken(op));
    return CalcExpression(outList, ExpressionState.Start);
  }

  /// Append a leading minus sign to the current expression and return a new
  /// expression representing the result. Returns null to indicate that it is not
  /// legal to append a leading minus sign in the current state.
  CalcExpression appendLeadingNeg() {
    switch (state) {
      case ExpressionState.Start:
        break;
      case ExpressionState.LeadingNeg:
      case ExpressionState.Point:
      case ExpressionState.Number:
      case ExpressionState.NumberWithPoint:
      case ExpressionState.Result:
        // Cannot enter leading neg now.
        return null;
    }
    final List<ExpressionToken> outList = _list.toList();
    outList.add(LeadingNegToken());
    return CalcExpression(outList, ExpressionState.LeadingNeg);
  }

  /// Append a minus sign to the current expression and return a new expression
  /// representing the result. Returns null to indicate that it is not legal
  /// to append a minus sign in the current state. Depending on the current
  /// state the minus sign will be interpreted as either a leading negative
  /// sign or a subtraction operation.
  CalcExpression appendMinus() {
    switch (state) {
      case ExpressionState.Start:
        return appendLeadingNeg();
      case ExpressionState.LeadingNeg:
      case ExpressionState.Point:
      case ExpressionState.Number:
      case ExpressionState.NumberWithPoint:
      case ExpressionState.Result:
        return appendOperation(Operation.Subtraction);
      default:
        return null;
    }
  }

  /// Computes the result of the current expression and returns a new
  /// ResultExpression containing the result. Returns null to indicate that
  /// it is not legal to compute a result in the current state.
  CalcExpression computeResult() {
    switch (state) {
      case ExpressionState.Start:
      case ExpressionState.LeadingNeg:
      case ExpressionState.Point:
      case ExpressionState.Result:
        // Cannot compute result now.
        return null;
      case ExpressionState.Number:
      case ExpressionState.NumberWithPoint:
        break;
    }

    // We make a copy of _list because CalcExpressions are supposed to
    // be immutable.
    final List<ExpressionToken> list = _list.toList();
    // We obey order-of-operations by computing the sum of the 'terms',
    // where a "term" is defined to be a sequence of numbers separated by
    // multiplication or division symbols.
    num currentTermValue = removeNextTerm(list);
    while (list.isNotEmpty) {
      final OperationToken opToken = list.removeAt(0);
      final num nextTermValue = removeNextTerm(list);
      switch (opToken.operation) {
        case Operation.Addition:
          currentTermValue += nextTermValue;
          break;
        case Operation.Subtraction:
          currentTermValue -= nextTermValue;
          break;
        case Operation.Multiplication:
        case Operation.Division:
          // Logic error.
          assert(false);
      }
    }
    final List<ExpressionToken> outList = <ExpressionToken>[];
    outList.add(ResultToken(currentTermValue));
    return CalcExpression(outList, ExpressionState.Result);
  }

  /// Removes the next "term" from `list` and returns its numeric value.
  /// A "term" is a sequence of number tokens separated by multiplication
  /// and division symbols.
  static num removeNextTerm(List<ExpressionToken> list) {
    assert(list != null && list.isNotEmpty);
    final NumberToken firstNumToken = list.removeAt(0);
    num currentValue = firstNumToken.number;
    while (list.isNotEmpty) {
      bool isDivision = false;
      final OperationToken nextOpToken = list.first;
      switch (nextOpToken.operation) {
        case Operation.Addition:
        case Operation.Subtraction:
          // We have reached the end of the current term
          return currentValue;
        case Operation.Multiplication:
          break;
        case Operation.Division:
          isDivision = true;
      }
      // Remove the operation token.
      list.removeAt(0);
      // Remove the next number token.
      final NumberToken nextNumToken = list.removeAt(0);
      final num nextNumber = nextNumToken.number;
      if (isDivision)
        currentValue /= nextNumber;
      else
        currentValue *= nextNumber;
    }
    return currentValue;
  }
}
