contract PathPublicCrowdsale is RateConfigurable, BurnableCrowdsale, ReallocatableCrowdsale, SafePercent {
  using SafeMath for uint256;

  address public pathAdvisorVault;
  address public privatePresaleWallet;

  function PathPublicCrowdsale (
    uint256 _startTime,
    uint256 _endTime,
    uint256 _rate,
    address _wallet,
    address _pathAdvisorVault,
    PATH _token,
    address _privatePresaleWallet
  )
    BurnableCrowdsale()
    StandardCrowdsale(_startTime, _endTime, _rate, _wallet, _token)
    public
  {
    pathAdvisorVault = _pathAdvisorVault;
    privatePresaleWallet = _privatePresaleWallet;
  }

  function finalization() internal {
    // First Burn the Crowdsale and then the advisors
    super.finalization();
    uint256 amountToBurn = calculateBurnAmount();
    TokenVault(pathAdvisorVault).approve(
      address(this),
      token,
      amountToBurn
    );
    token.burnFrom(pathAdvisorVault, amountToBurn);
    TokenVault(pathAdvisorVault).open();
  }

  function calculateBurnAmount()
    internal
    view
    returns (uint256)
  {
    // @TODO(shrugs) - remove 0.6 constant (ideally)
    // 0.6 is the percent of the tokens that are handled by the sale
    // and therefore the only tokens that affect advisor burning
    uint256 maxPossibleRaised = token.initialSupply().mul(3).div(5); // 60%
    uint256 actuallyRaised = token.totalSupply().sub(
      token.initialSupply().mul(2).div(5) // 40%
    );

    uint256 precision = 4; // decimal places of precision
    uint256 raisedRatio = percent(actuallyRaised, maxPossibleRaised, precision);
    // ^ [00000, 10000]
    uint256 burnRatio = (10 ** precision).sub(raisedRatio);
    // 10000 is for the 4 decimals of precision
    uint256 amountToBurnWithPrecision = token.balanceOf(pathAdvisorVault).mul(burnRatio);
    // balance * burnRatio = amountToBurn, but *10^4

    return amountToBurnWithPrecision.div(10 ** precision);
  }

  /**
   * @dev Implements tiered token amount based on number of weeks since startTime
   * @dev Overrides getTokenAmount method from StandardCrowdsale.sol
   */
  function getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
    var timeSinceStart = now - startTime;

    uint256 discountMultiplier;
    if (timeSinceStart <= 1 weeks) {
      discountMultiplier = 70;
    } else if (timeSinceStart <= 2 weeks) {
      discountMultiplier = 80;
    } else if (timeSinceStart <= 3 weeks) {
      discountMultiplier = 90;
    } else {
      discountMultiplier = 100;
    }

    return weiAmount.mul(rate).mul(100).div(discountMultiplier);
  }

  function reallocation(uint256 _value)
    internal
  {
    require(token.transfer(privatePresaleWallet, _value));
  }
}
function getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
  var timeSinceStart = now - startTime;

  uint256 discountMultiplier;
  if (timeSinceStart <= 1 weeks) {
    discountMultiplier = 70;
  } else if (timeSinceStart <= 2 weeks) {
    discountMultiplier = 80;
  } else if (timeSinceStart <= 3 weeks) {
    discountMultiplier = 90;
  } else {
    discountMultiplier = 100;
  }

  return weiAmount.mul(rate).mul(100).div(discountMultiplier);
}

/**
 * @dev Implements tiered token amount based on number of weeks since startTime
 * @dev Overrides getTokenAmount method from StandardCrowdsale.sol
 */