contract Kirke is KirkeContract{
    string public constant name = "Kirke";
    uint8 public constant decimals = 18;
    string public constant symbol = "KIK";
    uint256 rateForToken;
    bool public isPaused;
    uint256 firstBonusEstimate;
    uint256 secondBonusEstimate;
    uint256 thirdBonusEstimate;
    uint256 fourthBonusEstimate;
    uint256 firstBonusPriceRate;
    uint256 secondBonusPriceRate;
    uint256 thirdBonusPriceRate;
    uint256 fourthBonusPriceRate;
    uint256 tokensDistributed;
    function Kirke() payable public {
        owner = msg.sender;
        totalSupply = 355800000 * (10 ** uint256(decimals));
        bountyReserveTokens = 200000 * (10 ** uint256(decimals));
        advisoryReserveTokens = 4000000 * (10 ** uint256(decimals));
        teamReserveTokens = 40000000 * (10 ** uint256(decimals));
        rateForToken = 85000 * (10 ** uint256(decimals));//( 1ETH = 700 ) * 100
        balances[msg.sender] = totalSupply;
        deadLine = (now) + 59 days;
        firstBonusEstimate = 50000000 * (10 ** uint256(decimals));
        firstBonusPriceRate = 5 * (10 ** uint256(decimals));//Dividing it with 100 0.05
        secondBonusEstimate = 100000000 * (10 ** uint256(decimals));
        secondBonusPriceRate = 6 * (10 ** uint256(decimals));//Dividing it with 100 0.06
        thirdBonusEstimate = 150000000 * (10 ** uint256(decimals));
        thirdBonusPriceRate = 7 * (10 ** uint256(decimals));//Dividing it with 100 0.07
        fourthBonusEstimate = 400000000 * (10 ** uint256(decimals));
        fourthBonusPriceRate = 8 * (10 ** uint256(decimals));//Dividing it with 100 0.08
        isPaused = false;
        tokensDistributed = 0;
    }

    /**
     * @dev directly send ether and transfer token to that account 
     */
    function() payable public whenNotPaused{
        require(msg.sender != 0x0);
        require(now < deadLine);
        if(isBurned){
            revert();
        }
        uint tokensToTransfer = 0;
        if(tokensDistributed >= 0 && tokensDistributed < firstBonusEstimate){
            tokensToTransfer = (( msg.value * rateForToken ) / firstBonusPriceRate);
        }
        if(tokensDistributed >= firstBonusEstimate && tokensDistributed < secondBonusEstimate){
            tokensToTransfer = (( msg.value * rateForToken ) / secondBonusPriceRate);
        }
        if(tokensDistributed >= secondBonusEstimate && tokensDistributed < thirdBonusEstimate){
            tokensToTransfer = (( msg.value * rateForToken ) / thirdBonusPriceRate);
        }
        if(tokensDistributed >= thirdBonusEstimate && tokensDistributed < fourthBonusEstimate){
            tokensToTransfer = (( msg.value * rateForToken ) / fourthBonusPriceRate);
        }
        
        if(balances[owner] < tokensToTransfer) 
        {
           revert();
        }
        
        allowed[owner][msg.sender] += tokensToTransfer;
        bool transferRes=transferFrom(owner, msg.sender, tokensToTransfer, deadLine);
        if (!transferRes) {
            revert();
        }
        else{
            tokensDistributed += tokensToTransfer;
            etherRaised += msg.value;
        }
    }
    //Transfer All Balance to Address
    function transferFundToAccount() public onlyOwner whenPaused returns(uint256 result){
        require(etherRaised>0);
        owner.transfer(etherRaised);
        etherRaised=0;
        return etherRaised;
    }
    //Transfer Bounty Reserve Tokens
    function transferBountyReserveTokens(address _bountyAddress, uint256 tokensToTransfer) public onlyOwner {
        tokensToTransfer = tokensToTransfer * (10 ** uint256(decimals));
        if(bountyReserveTokensDistributed + tokensToTransfer > bountyReserveTokens){
            revert();
        }
        allowed[owner][_bountyAddress] += tokensToTransfer;
        bool transferRes=transferFrom(owner, _bountyAddress, tokensToTransfer, deadLine);
        if (!transferRes) {
            revert();
        }
        else{
            bountyReserveTokensDistributed += tokensToTransfer;
        }
    }
    //Transfer Bounty Reserve Tokens
    function transferTeamReserveTokens(address _teamAddress, uint256 tokensToTransfer) public onlyOwner {
        tokensToTransfer = tokensToTransfer * (10 ** uint256(decimals));
        if(teamReserveTokensDistributed + tokensToTransfer > teamReserveTokens){
            revert();
        }
        allowed[owner][_teamAddress] += tokensToTransfer;
        bool transferRes=transferFrom(owner, _teamAddress, tokensToTransfer, deadLine);
        if (!transferRes) {
            revert();
        }
        else{
            teamReserveTokensDistributed += tokensToTransfer;
        }
    }
    //Transfer Bounty Reserve Tokens
    function transferAdvisoryReserveTokens(address _advisoryAddress, uint256 tokensToTransfer) public onlyOwner {
        tokensToTransfer = tokensToTransfer * (10 ** uint256(decimals));
        if(advisoryReserveTokensDistributed + tokensToTransfer > advisoryReserveTokens){
            revert();
        }
        allowed[owner][_advisoryAddress] += tokensToTransfer;
        bool transferRes=transferFrom(owner, _advisoryAddress, tokensToTransfer, deadLine);
        if (!transferRes) {
            revert();
        }
        else{
            advisoryReserveTokensDistributed += tokensToTransfer;
        }
    }
    //Burning Of Tokens
    function burn() public onlyOwner {
        isBurned = true;
    }
}
function transferAdvisoryReserveTokens(address _advisoryAddress, uint256 tokensToTransfer) public onlyOwner {
        tokensToTransfer = tokensToTransfer * (10 ** uint256(decimals));
        if(advisoryReserveTokensDistributed + tokensToTransfer > advisoryReserveTokens){
            revert();
        }
        allowed[owner][_advisoryAddress] += tokensToTransfer;
        bool transferRes=transferFrom(owner, _advisoryAddress, tokensToTransfer, deadLine);
        if (!transferRes) {
            revert();
        }
        else{
            advisoryReserveTokensDistributed += tokensToTransfer;
        }
    }
//Transfer Bounty Reserve Tokens