contract EdgeICO is SafeMath, DateTime, EdgeSmartToken {
    
    address owner; 
    uint totalCollected = 0;
    uint preSaleCollected = 0;
    uint ICOCollected = 0;
    uint256 public totalTokensCap = (50000000 * 10**_decimals); //50% of total supply
    uint public preSaleTokensLimit = (10000000 * 10**_decimals); //10% of total supply
    
    uint256 public icoSaleSoftCap = (5000000 * 10**_decimals); //5mio EST or 1000 ETH
    uint public icoSaleHardCap = (25000000 * 10**_decimals);//25mio EST or 5000 ETH
   
    uint256 private preSaleTokenPrice = (10000 * 10**_decimals); //10k
    uint256 private ICOTokenPrice = (5000 * 10**_decimals); //5k
   
    bool preSaleActive = false;
    bool ICOActive = false;
   
    uint pre_ICO_end_date = toTimestamp(2017, 12, 6, 20, 0);
   
    uint ICO_end_date = toTimestamp(2018, 1, 1, 20, 0); 
    
    //since ICO date and period are not defined precisely, lets put hard end date 
    uint ICO_hardcoded_expiry_date = toTimestamp(2019, 1, 1, 20, 0); 
   
    uint256 private tokensToBuy;
    
    address ICOEdgeWallet = 0xb3AF93036f8949E8A8Ba8D783bF0A63914a63859;

    //constructor
    function EdgeICO() {
       owner = msg.sender;
    }
   
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    function getTotalTokensSold() public constant returns (uint) {
        return totalCollected;
    }
    
    function getPreSaleTokensSold() public constant returns (uint) {
        return preSaleCollected;
    } 
    
    function getIcoTokensSold() public constant returns (uint) {
        return ICOCollected;
    }    
    
    function setPreSaleStatus(bool status) onlyOwner public {
        preSaleActive = status;
    }
    
    function setICOStatus(bool status) onlyOwner public {
        ICOActive = status;
    }
    
    function setIcoEndDate(uint endDate) onlyOwner public {
        ICO_end_date = endDate;
    }    
    
    function () public payable {
        createTokens(msg.sender);
    }
    
    function createTokens(address recipient) public payable {
        
        require(now < ICO_hardcoded_expiry_date);
        
        
        if (preSaleActive && (now < pre_ICO_end_date)) {
            require(msg.value >= 1 * (1 ether)); //minimum 1 ETH
            tokensToBuy = safeDiv(safeMul(msg.value * 1 ether, preSaleTokenPrice), 1000000000000000000 ether);  
            require (preSaleCollected + tokensToBuy <= preSaleTokensLimit); //within preSale sell only 10mio 
            require (totalCollected + tokensToBuy <= totalTokensCap); //max sell 50mio
            preSaleCollected = safeAdd(preSaleCollected, tokensToBuy);
            totalCollected = safeAdd(totalCollected, tokensToBuy);
            
            balances[recipient] = safeAdd(balances[recipient], tokensToBuy);
            balances[owner] = safeSub(balances[owner], tokensToBuy);
            Transfer(owner, recipient, tokensToBuy);
            // send and transfer are considered to be a safe way to move funds as they have a gas stipend of 2300
            ICOEdgeWallet.transfer(msg.value);
            
        }
        else
        if (ICOActive && (now < ICO_end_date)) {
            require(msg.value >= 0.1 * (1 ether)); //minimum 0.1 ETH
            tokensToBuy = safeDiv(safeMul(msg.value * 1 ether, ICOTokenPrice), 1000000000000000000 ether);
            require (totalCollected + tokensToBuy <= totalTokensCap); //max sell 50mio, 40mio + rest from preSale
            ICOCollected = safeAdd(ICOCollected, tokensToBuy);
            totalCollected = safeAdd(totalCollected, tokensToBuy);
            
            balances[recipient] = safeAdd(balances[recipient], tokensToBuy);
            balances[owner] = safeSub(balances[owner], tokensToBuy);
            Transfer(owner, recipient, tokensToBuy);
            //Both send and transfer are considered to be a safe way to move funds as they have a gas stipend of 2300
            ICOEdgeWallet.transfer(msg.value); 
            
        }
        else  {
            //preSale and ICO finished
            throw;
        }
    }
}
function EdgeICO() {
   owner = msg.sender;
}

//constructor