contract TokenICO is PersianToken {

    uint256 public icoStartBlock;
    uint256 public icoEndBlock;
    uint256 public totalContributions;
    mapping (address => uint256) public contributions;

    // At max 300.000 Persian (with 18 decimals) will be ever generated from this ICO
    uint256 public constant maxTotalSupply = 300000 * 10**18;

    event Contributed(address indexed _contributor, uint256 _value, uint256 _estimatedTotalTokenBalance);
    event Claimed(address indexed _contributor, uint256 _value);

    function contribute() onlyDuringICO payable external returns (bool success) {
        totalContributions = safeAdd(totalContributions, msg.value);
        contributions[msg.sender] = safeAdd(contributions[msg.sender], msg.value);
        Contributed(msg.sender, msg.value, estimateBalanceOf(msg.sender));
        return true;
    }

    function claimToken() onlyAfterICO external returns (bool success) {
        uint256 balance = estimateBalanceOf(msg.sender);
        contributions[msg.sender] = 0;
        balances[msg.sender] = safeAdd(balances[msg.sender], balance);
        totalSupply = safeAdd(totalSupply, balance);
        require(totalSupply <= maxTotalSupply);
        Claimed(msg.sender, balance);
        return true;
    }

    function redeemEther() onlyAfterICO onlyOwner external  {
        owner.transfer(this.balance);
    }

    function estimateBalanceOf(address _owner) constant returns (uint256 estimatedTokens) {
        return contributions[_owner] > 0 ? safeMul( maxTotalSupply / totalContributions, contributions[_owner]) : 0;
    }

    // This check is an helper function for ÐApp to check the effect of the NEXT tx, NOT simply the current state of the contract
    function isICOOpen() constant returns (bool _open) {
        return block.number >= (icoStartBlock - 1) && !isICOEnded();
    }

    // This check is an helper function for ÐApp to check the effect of the NEXT tx, NOT simply the current state of the contract
    function isICOEnded() constant returns (bool _ended) {
        return block.number >= icoEndBlock;
    }

    modifier onlyDuringICO {
        require(block.number >= icoStartBlock && block.number <= icoEndBlock); _;
    }

    modifier onlyAfterICO {
        require(block.number > icoEndBlock); _;
    }
}
function isICOEnded() constant returns (bool _ended) {
    return block.number >= icoEndBlock;
}

// This check is an helper function for ÐApp to check the effect of the NEXT tx, NOT simply the current state of the contract