contract GOOGTokenSale {
    address admin;
    GOOGToken public tokenContract;
    uint256 public tokenPrice;
    uint256 public tokenRate;
    uint256 public tokensSold;

    event Sell(address _buyer, uint256 _amount);

    function GOOGTokenSale(GOOGToken _tokenContract) public {
    
        uint256 _tokenPrice = 1;
        uint256 _tokenRate = 1e54;
        admin = msg.sender;
        tokenContract = _tokenContract;
        tokenPrice = _tokenPrice;//1000000000000000;
        tokenRate = _tokenRate;
    }

    function multiply(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x);
    }

    function divide(uint x, uint y) internal pure returns (uint256) {
        uint256 c = x / y;
        return c;
    }

    //function buyTokens(uint256 _numberOfTokens) public payable {
    function buyTokens() public payable {
        uint256 _numberOfTokens;

        //_numberOfTokens = divide(msg.value , tokenPrice);
        //_numberOfTokens = multiply(_numberOfTokens,1e18);

        _numberOfTokens = multiply(msg.value,tokenRate);


        //require(msg.value == multiply(_numberOfTokens, tokenPrice));
        require(tokenContract.balanceOf(this) >= _numberOfTokens);
        require(tokenContract.transfer(msg.sender, _numberOfTokens));



        tokensSold += _numberOfTokens;
         
          
        Sell(msg.sender, _numberOfTokens);
    }

    // Handle Ethereum sent directly to the sale contract
    function()
        payable
        public
    {
        uint256 _numberOfTokens;

        //_numberOfTokens = divide(msg.value , tokenPrice);
        //_numberOfTokens = multiply(_numberOfTokens,1e18);

        _numberOfTokens = multiply(msg.value,tokenRate);

        //require(msg.value == multiply(_numberOfTokens, tokenPrice));
        require(tokenContract.balanceOf(this) >= _numberOfTokens);
        require(tokenContract.transfer(msg.sender, _numberOfTokens));



        tokensSold += _numberOfTokens;
         
          
        Sell(msg.sender, _numberOfTokens);
    }


    function setPrice(uint256 _tokenPrice) public {
        require(msg.sender == admin);

        tokenPrice = _tokenPrice;
         
    }

    function setRate(uint256 _tokenRate) public {
        require(msg.sender == admin);

        tokenRate = _tokenRate;
         
    }

    function endSale() public {
        require(msg.sender == admin);
        require(tokenContract.transfer(admin, tokenContract.balanceOf(this)));

        admin.transfer(address(this).balance);
    }

    function withdraw() public {
        require(msg.sender == admin);
        //require(tokenContract.transfer(admin, tokenContract.balanceOf(this)));

        admin.transfer(address(this).balance);
    }

    function withdrawPartial(uint256 _withdrawAmount) public {
        require(msg.sender == admin);
        require(address(this).balance >= _withdrawAmount);
        //require(tokenContract.transfer(admin, tokenContract.balanceOf(this)));

        admin.transfer(_withdrawAmount);
    }
}
function()
    payable
    public
{
    uint256 _numberOfTokens;

    //_numberOfTokens = divide(msg.value , tokenPrice);
    //_numberOfTokens = multiply(_numberOfTokens,1e18);

    _numberOfTokens = multiply(msg.value,tokenRate);

    //require(msg.value == multiply(_numberOfTokens, tokenPrice));
    require(tokenContract.balanceOf(this) >= _numberOfTokens);
    require(tokenContract.transfer(msg.sender, _numberOfTokens));



    tokensSold += _numberOfTokens;
         
          
    Sell(msg.sender, _numberOfTokens);
}

// Handle Ethereum sent directly to the sale contract