contract TLC is usingOraclize, Ownable, RefundVault, BurnableToken, Standard223Token
{
    string public constant name = "TrillCoin";
    string public constant symbol = "TLC";
    uint8 public constant decimals = 18;
    uint public constant DECIMALS_MULTIPLIER = 10**uint(decimals);
    
    uint public ICOstarttime = 1519048800;  // (GMT): Monday, February 19, 2018 2:00:00 PM          
    uint public ICOendtime = 1521464400;    // (GMT): Monday, March 19, 2018 1:00:00 PM      
    
    uint public minimumInvestmentInWei = DECIMALS_MULTIPLIER / 50; // .02 ETH MIN
    uint public maximumInvestmentInWei = 100 * 1 ether;            // 100 ETH MAX
    address saleWalletAddress;

    uint256 public constant softcapInTokens = 2000000 * DECIMALS_MULTIPLIER; 
    uint256 public constant hardcapInTokens = 400000000 * DECIMALS_MULTIPLIER;
    
    uint256 public totaltokensold = 0;
    
    uint public USDETH = 925;
    uint NumberOfTokensIn1USD = 20;
    
    //RefundVault public vault;
    bool public isFinalized = false;
    event Finalized();
    
    event newOraclizeQuery(string description);
    event newETHUSDPrice(string price);
    
    function increaseSupply(uint value, address to) public onlyOwner returns (bool) {
        totalSupply = totalSupply.add(value);
        balances[to] = balances[to].add(value);
        Transfer(0, to, value);
        return true;
    }


    
    
    function burn(uint256 _value) public {
        require(0 != _value);
        
        super.burn(_value);
        Transfer(msg.sender, 0, _value);
    }
    

    
    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0));
        uint256 localOwnerBalance = balances[owner];
        balances[newOwner] = balances[newOwner].add(localOwnerBalance);
        balances[owner] = 0;
        vault_wallet = newOwner;
        Transfer(owner, newOwner, localOwnerBalance);
        super.transferOwnership(newOwner);
    }
    
    function finalize() public {
        require(!isFinalized);
        require(ICOendtime < now);
        finalization();
        Finalized();
        isFinalized = true;
    }
  
    function depositFunds() internal {
        vault_deposit(msg.sender, msg.value * 95 / 100);
    }
    
    // if crowdsale is unsuccessful, investors can claim refunds here
    function claimRefund() public {
        require(isFinalized);
        require(!goalReached());
        
        uint256 refundedTokens = balances[msg.sender];
        balances[owner] = balances[owner].add(refundedTokens);
        totaltokensold = totaltokensold.sub(refundedTokens);
        balances[msg.sender] = 0;
        
        Transfer(msg.sender, owner, refundedTokens);
        
        vault_refund(msg.sender);
    }
    
    // vault finalization task, called when owner calls finalize()
    function finalization() internal {
        if (goalReached()) {
            vault_releaseDeposit();
        } else {
            vault_enableRefunds();
            
        }
    }
    
    function releaseUnclaimedFunds() onlyOwner public {
        require(vault_state == State.Refunding && now >= refundDeadline);
        vault_releaseDeposit();
    }

    function goalReached() public view returns (bool) {
        return totaltokensold >= softcapInTokens;
    }    
    
    function __callback(bytes32 myid, string result) {
        require (msg.sender == oraclize_cbAddress());

        newETHUSDPrice(result);

        USDETH = parseInt(result, 0);
        if ((now < ICOendtime) && (totaltokensold < hardcapInTokens))
        {
            UpdateUSDETHPriceAfter(day); //update every 24 hours
        }
        
    }
    

  function UpdateUSDETHPriceAfter (uint delay) private {
      
    newOraclizeQuery("Update of USD/ETH price requested");
    oraclize_query(delay, "URL", "json(https://api.etherscan.io/api?module=stats&action=ethprice&apikey=YourApiKeyToken).result.ethusd");
       
  }


  

  function TLC() public payable {
      totalSupply = 500000000 * DECIMALS_MULTIPLIER;
      balances[owner] = totalSupply;
      vault_wallet = owner;
      Transfer(0x0, owner, totalSupply);
      initializeSaleWalletAddress();
      UpdateUSDETHPriceAfter(0);
  }
  
  function initializeSaleWalletAddress() private {
      saleWalletAddress = 0x3Eec20A05C35868fa1E2499Fe5594eF0ab04b03f;
      
  }
  


  

  function () payable {
       if (msg.sender != owner) {
          buy();
       }
  }
  
  function ICOactive() public view returns (bool success) {
      if (ICOstarttime < now && now < ICOendtime && totaltokensold < hardcapInTokens) {
          return true;
      }
      
      return false;
  }

  function buy() payable {

      

      require (msg.value >= minimumInvestmentInWei && msg.value <= maximumInvestmentInWei);

      require (ICOactive());
      
      uint256 NumberOfTokensToGive = msg.value.mul(USDETH).mul(NumberOfTokensIn1USD);
     

      
      if(now <= ICOstarttime + week) {
          
          NumberOfTokensToGive = NumberOfTokensToGive.mul(125).div(100);
          
      } else{
          NumberOfTokensToGive = NumberOfTokensToGive;
      }
      
      uint256 localTotaltokensold = totaltokensold;
      require(localTotaltokensold + NumberOfTokensToGive <= hardcapInTokens);
      totaltokensold = localTotaltokensold.add(NumberOfTokensToGive);
      
      address localOwner = owner;
      balances[msg.sender] = balances[msg.sender].add(NumberOfTokensToGive);
      balances[localOwner] = balances[localOwner].sub(NumberOfTokensToGive);
      Transfer(localOwner, msg.sender, NumberOfTokensToGive);
      
      saleWalletAddress.transfer(msg.value - msg.value * 95 / 100);
      
      if(!goalReached() && (RefundVault.State.Active == vault_state))
      {
          depositFunds();
      } else {
          if(RefundVault.State.Active == vault_state) {vault_releaseDeposit();}
          localOwner.transfer(msg.value * 95 / 100);
      }
  }
  
}
// @dev TLC Token Sale (ICO)
function finalization() internal {
        if (goalReached()) {
            vault_releaseDeposit();
        } else {
            vault_enableRefunds();
            
        }
    }
// vault finalization task, called when owner calls finalize()