contract RC is ICOEngineInterface, KYCBase {
    using SafeMath for uint256;
    TokenSale tokenSaleContract;
    uint256 public startTime;
    uint256 public endTime;
    
    uint256 public soldTokens;
    uint256 public remainingTokens;
    
    uint256 public oneTokenInUsdWei;
	
	mapping(address => uint256) public balanceUser; // address => token amount
	uint256[] public tokenThreshold; // array of token threshold reached in wei of token
    uint256[] public bonusThreshold; // array of bonus of each tokenThreshold reached - 20% = 20

    function RC(address _tokenSaleContract, uint256 _oneTokenInUsdWei, uint256 _remainingTokens,  uint256 _startTime , uint256 _endTime, address [] kycSigner, uint256[] _tokenThreshold, uint256[] _bonusThreshold ) public KYCBase(kycSigner) {
        require ( _tokenSaleContract != 0 );
        require ( _oneTokenInUsdWei != 0 );
        require( _remainingTokens != 0 );
        require ( _tokenThreshold.length != 0 );
        require ( _tokenThreshold.length == _bonusThreshold.length );
        bonusThreshold = _bonusThreshold;
        tokenThreshold = _tokenThreshold;
        
        
        tokenSaleContract = TokenSale(_tokenSaleContract);
        
        tokenSaleContract.addMeByRC();
        
        soldTokens = 0;
        remainingTokens = _remainingTokens;
        oneTokenInUsdWei = _oneTokenInUsdWei;
        
        setTimeRC( _startTime, _endTime );
    }
    
    function setTimeRC(uint256 _startTime, uint256 _endTime ) internal {
        if( _startTime == 0 ) {
            startTime = tokenSaleContract.startTime();
        } else {
            startTime = _startTime;
        }
        if( _endTime == 0 ) {
            endTime = tokenSaleContract.endTime();
        } else {
            endTime = _endTime;
        }
    }
    
    modifier onlyTokenSaleOwner() {
        require(msg.sender == tokenSaleContract.owner() );
        _;
    }
    
    function setTime(uint256 _newStart, uint256 _newEnd) public onlyTokenSaleOwner {
        if ( _newStart != 0 ) startTime = _newStart;
        if ( _newEnd != 0 ) endTime = _newEnd;
    }
    
    event BuyRC(address indexed buyer, bytes trackID, uint256 value, uint256 soldToken, uint256 valueTokenInUsdWei );
    
    function releaseTokensTo(address buyer) internal returns(bool) {
        require( now > startTime );
        require( now < endTime );
        //require( msg.value >= 1*10**18); //1 Ether
        require( remainingTokens > 0 );
        
        uint256 tokenAmount = tokenSaleContract.buyFromRC.value(msg.value)(buyer, oneTokenInUsdWei, remainingTokens);
        
		balanceUser[msg.sender] = balanceUser[msg.sender].add(tokenAmount);		
        remainingTokens = remainingTokens.sub(tokenAmount);
        soldTokens = soldTokens.add(tokenAmount);
        
        emit BuyRC( msg.sender, msg.data, msg.value, tokenAmount, oneTokenInUsdWei );
        return true;
    }
    
    function started() public view returns(bool) {
        return now > startTime || remainingTokens == 0;
    }
    
    function ended() public view returns(bool) {
        return now > endTime || remainingTokens == 0;
    }
    
    function startTime() public view returns(uint) {
        return startTime;
    }
    
    function endTime() public view returns(uint) {
        return endTime;
    }
    
    function totalTokens() public view returns(uint) {
        return remainingTokens.add(soldTokens);
    }
    
    function remainingTokens() public view returns(uint) {
        return remainingTokens;
    }
    
    function price() public view returns(uint) {
        uint256 oneEther = 10**18;
        return oneEther.mul(10**18).div( tokenSaleContract.tokenValueInEther(oneTokenInUsdWei) );
    }
	
	function () public {
        require( now > endTime );
        require( balanceUser[msg.sender] > 0 );
        uint256 bonusApplied = 0;
        for (uint i = 0; i < tokenThreshold.length; i++) {
            if ( soldTokens > tokenThreshold[i] ) {
                bonusApplied = bonusThreshold[i];
			}
		}    
		require( bonusApplied > 0 );
		
		uint256 addTokenAmount = balanceUser[msg.sender].mul( bonusApplied ).div(10**2);
		balanceUser[msg.sender] = 0; 
		
		tokenSaleContract.claim(msg.sender, addTokenAmount);
	}
}
function RC(address _tokenSaleContract, uint256 _oneTokenInUsdWei, uint256 _remainingTokens,  uint256 _startTime , uint256 _endTime, address [] kycSigner, uint256[] _tokenThreshold, uint256[] _bonusThreshold ) public KYCBase(kycSigner) {
    require ( _tokenSaleContract != 0 );
    require ( _oneTokenInUsdWei != 0 );
    require( _remainingTokens != 0 );
    require ( _tokenThreshold.length != 0 );
    require ( _tokenThreshold.length == _bonusThreshold.length );
    bonusThreshold = _bonusThreshold;
    tokenThreshold = _tokenThreshold;
        
        
    tokenSaleContract = TokenSale(_tokenSaleContract);
        
    tokenSaleContract.addMeByRC();
        
    soldTokens = 0;
    remainingTokens = _remainingTokens;
    oneTokenInUsdWei = _oneTokenInUsdWei;
        
    setTimeRC( _startTime, _endTime );
}

// array of bonus of each tokenThreshold reached - 20% = 20