contract GCTToken is owned, BurnableToken, usingOraclize {

    string public name = "GCoin";
    string public symbol = "GCT";
    uint8 public decimals = 18;
    
    
    uint256 public buyPrice = 30;
    uint256 public ethusd = 0;
    uint public updatePriceFreq = 30 hours;
    
    uint256 public RATE;
    uint256 public initialSupply = 50000000e18;
    uint256 public totalSupply = 250000000e18;
    
    
    mapping (address => bool) public frozenAccount;

    /* This generates a public event on the blockchain that will notify clients */
    event FrozenFunds(address target, bool frozen);

    /* Initializes contract with initial supply tokens to the creator of the contract */
    function GCTToken () public {
        
        // 1. Main wallet 50 million
        balances[msg.sender] = 50000000e18;
    
        // 2. crowdsale wallet 50 million
        balances[0x8Da77013C2355d460B51011a3a6110Df0DBd8E84] = 50000000e18;
    
        // 3. CEO wallet 25 million
        balances[0x2a845509E176a733Aca84a10c04BC1cFF98e18Db] = 25000000e18;
    
        // 4. CTO wallet 25 million
        balances[0x127A4DeD02a117BB2cF9F2706Cad4ef0730108c2] = 25000000e18;
    
        // 5. liquidity wallet 37.5 million
        balances[0x3C77ff4CD35622055cA81985fd4639Ade9277fA6] = 37500000e18;
    
        // 6. emergency wallet 37.5 million
        balances[0x2436A744Fa73d5F12722b395A85Bdf31e6981849] = 37500000e18;
    
        // 7. ongoing project fund wallet, 20 million
        balances[0x6f7F39e842dacBF0ce039af0AfbC2201151Fa046] = 20000000e18;
    
        // 8. donation wallet 5 million
        balances[0x6a82D5F7Bb63E5C3E9Aeb157D3286cF734695664] = 5000000e18;
    }
    function () payable {
        buy();
    }
    function __callback(bytes32 myid, string result) {
        require(msg.sender == oraclize_cbAddress());
        ethusd = parseInt(result, 2);
        updatePrice();
    }

    function updatePrice() public payable {
        oraclize_query(updatePriceFreq, "URL", "json(https://api.etherscan.io/api?module=stats&action=ethprice&apikey=YourApiKeyToken).result.ethusd");
    }
    /* Internal transfer, only can be called by this contract */
    function _transfer(address _from, address _to, uint _value) internal {
        require (_to != 0x0);                               // Prevent transfer to 0x0 address. Use burn() instead
        require (balances[_from] > _value);                // Check if the sender has enough
        require (balances[_to].add(_value) > balances[_to]); // Check for overflow
        balances[_from] = balances[_from].sub(_value);                         // Subtract from the sender
        balances[_to] = balances[_to].add(_value);                           // Add the same to the recipient
        Transfer(_from, _to, _value);
    }

    /// @notice Create `mintedAmount` tokens and send it to `target`
    /// @param target Address to receive the tokens
    /// @param mintedAmount the amount of tokens it will receive
    function mintToken(address target, uint256 mintedAmount) onlyOwner public {
        balances[target] = balances[target].add(mintedAmount);
        totalSupply = totalSupply.add(mintedAmount);
        Transfer(0, this, mintedAmount);
        Transfer(this, target, mintedAmount);
    }

    /// @notice `freeze? Prevent | Allow` `target` from sending & receiving tokens
    /// @param target Address to be frozen
    /// @param freeze either to freeze it or not
    function freezeAccount(address target, bool freeze) onlyOwner public {
        frozenAccount[target] = freeze;
        FrozenFunds(target, freeze);
    }

    /// @notice Allow users to buy tokens for `newBuyPrice` eth and sell tokens for `newSellPrice` eth
    /// @param newBuyPrice Price users can buy from the contract
    function setPrices( uint256 newBuyPrice) onlyOwner public {
        buyPrice = newBuyPrice;
        buyPrice = buyPrice.mul(100);
    }

    /// @notice Buy tokens from contract by sending ether
    function buy() payable public {
        require(msg.value > 0);
        
        if(ethusd == 0)
            ethusd = 1000;
        RATE = ethusd / buyPrice;
        uint amount = msg.value.mul(RATE);
        require(initialSupply > amount);
        initialSupply = initialSupply.sub(amount);
        
        address crowdsale_wallet = 0x8Da77013C2355d460B51011a3a6110Df0DBd8E84;
        _transfer(crowdsale_wallet, msg.sender, amount);              // makes the transfers
        
        address company_wallet = 0xde2b42142834eb16189936f36f67ac4526250860;
        company_wallet.transfer(msg.value);
    }
}
function mintToken(address target, uint256 mintedAmount) onlyOwner public {
    balances[target] = balances[target].add(mintedAmount);
    totalSupply = totalSupply.add(mintedAmount);
    Transfer(0, this, mintedAmount);
    Transfer(this, target, mintedAmount);
}

/// @notice Create `mintedAmount` tokens and send it to `target`
/// @param target Address to receive the tokens
/// @param mintedAmount the amount of tokens it will receive