contract PowerEtherHelper is PowerEtherBase {
    
    using SafeMath for *;
    using strings for *;
    
    /**
     *
     * 
     *      ╦ ╦╔═╗╦  ╔═╗╔═╗╦═╗  ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
     *      ╠═╣║╣ ║  ╠═╝║╣ ╠╦╝  ╠╣ ║ ║║║║║   ║ ║║ ║║║║╚═╗
     *      ╩ ╩╚═╝╩═╝╩  ╚═╝╩╚═  ╚  ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
     *
     * 
     */
    
    /**
     * @dev Activates the contract.
     */
    function activate() 
        external 
        onlyCEO {
            
            require(msg.sender != address(0));
        
            activated_ = !activated_;
        }
    
    /**
     * @dev Deactivates the contract.
     */    
    function deactivate() 
        external 
        onlyCEO {
            
            require(msg.sender != address(0));
        
            activated_ = false;
        }
    
    /**
     * @dev Sets the new CEO address. Only available to the current CFO. 
     */
    function setCEO(address _newCEO) 
        external 
        onlyCEO 
        isHuman {
            
            require(_newCEO != address(0));

            ceoAddress = _newCEO;
        }
    
    /**
     * @dev Sets the Bid price for the PowerOne game. Only available to the 
     * current CEO. 
     */
    function setPowerOneBidPrice(uint256 _newBid) 
        external 
        onlyCEO 
        isHuman 
        isWithinLimits(_newBid) {
            
            powerOneBid = _newBid;
        }
    
    /**
     * @dev Sets the Fee price for the PowerOne game. Only available to the
     * current CEO. 
     */
    function setPowerOneFeePrice(uint256 _newFee) 
        external 
        onlyCEO 
        isHuman 
        isWithinLimits(_newFee) {
            
            powerOneFee = _newFee;
        }
    
    /**
     * @dev Sets the Bid price for the PowerTwo game. Only available to the 
     * current CEO. 
     */
    function setPowerTwoBidPrice(uint256 _newBid) 
        external 
        onlyCEO 
        isHuman 
        isWithinLimits(_newBid) {
            
            powerTwoBid = _newBid;
        }
    
    /**
     * @dev Sets the Fee price for the PowerTwo game. Only available to the
     * current CEO. 
     */
    function setPowerTwoFeePrice(uint256 _newFee) 
        external 
        onlyCEO 
        isHuman 
        isWithinLimits(_newFee) {
            
            powerTwoFee = _newFee;
        }
    
    /**
     * @dev Sets the Bid price for the PowerFour game. Only available to the 
     * current CEO. 
     */
    function setPowerFourBidPrice(uint256 _newBid) 
        external 
        onlyCEO 
        isHuman 
        isWithinLimits(_newBid) {
            
            powerFourBid = _newBid;
        }
    
    /**
     * @dev Sets the Fee price for the PowerFour game. Only available to the
     * current CEO. 
     */
    function setPowerFourFeePrice(uint256 _newFee) 
        external 
        onlyCEO 
        isHuman 
        isWithinLimits(_newFee) {
            
            powerFourFee = _newFee;
        }
    
    /**
     * @dev Sets the platform cut denumenator percentage. 
     * Only available to the current CEO. 
     */
    function setPlatformCut(uint256 _newPlatformCut)
        external
        onlyCEO
        isHuman {
            
            platformCut = _newPlatformCut;
            
        }
    
    /**
     * @dev Sets the new limit for the megaJackpotCap. Only available to the
     * current CEO.
     */
    function setMegaJackpotCap(uint256 _newCap)
        external
        onlyCEO
        isHuman {
            
            megaJackpotCap = _newCap;
            
        }
        
    /**
     * @dev Sets the new MegaJackpot fee.
     */
    function setMegaJackpotFee(uint256 _newMegaJackpotFee)
        external
        onlyCEO
        isHuman {
            
            megaJackpotFee = _newMegaJackpotFee;
            
        }
        
    /**
     * @dev Sets the gas limit for Oraclize Query.
     */
    function setGasForOraclize(uint32 _newGasLimit)
        external
        onlyCEO
        isHuman {
            
            gasForOraclize = _newGasLimit;
            
        }
        
    /**
     * @dev Sets the new minNumber.
     */
    function setMinNumber(uint256 _newMinNumber)
        external
        onlyCEO
        isHuman {
            
            minNumber = _newMinNumber;
            
        }
    
    /**
     * @dev Sets the new maxNumber.
     */
    function setMaxNumber(uint256 _newMaxNumber)
        external
        onlyCEO
        isHuman {
            
            maxNumber = _newMaxNumber;
            
        }
    
    /**
     * @dev Internal function to check the PowerNumbers of PowerTwo Game.
     */
    function _checkTwo(
        uint256 _resultNumberOne,
        uint256 _resultNumberTwo,
        uint256 _powerNumberOne,
        uint256 _powerNumberTwo
        ) 
        internal 
        returns (bool) {
            if ((_resultNumberOne == _powerNumberOne ||
                _resultNumberOne == _powerNumberTwo) &&
                (_resultNumberTwo == _powerNumberOne ||
                _resultNumberTwo == _powerNumberTwo)
                ) {
                    return (true);
                } else {
                    return (false);
                }
        }
    
    /**
     * @dev Internal function to check the PowerNumbers of PowerFour Game.
     */
    function _checkFour(
        uint256 _resultNumberOne,
        uint256 _resultNumberTwo,
        uint256 _resultNumberThree,
        uint256 _resultNumberFour,
        uint256 _powerNumberOne,
        uint256 _powerNumberTwo,
        uint256 _powerNumberThree,
        uint256 _powerNumberFour
        )
        internal
        returns (bool) {
            if ((_resultNumberOne == _powerNumberOne ||
                _resultNumberOne == _powerNumberTwo ||
                _resultNumberOne == _powerNumberThree ||
                _resultNumberOne == _powerNumberFour) &&
                (_resultNumberTwo == _powerNumberOne ||
                _resultNumberTwo == _powerNumberTwo ||
                _resultNumberTwo == _powerNumberThree ||
                _resultNumberTwo == _powerNumberFour) &&
                (_resultNumberThree == _powerNumberOne ||
                _resultNumberThree == _powerNumberTwo ||
                _resultNumberThree == _powerNumberThree ||
                _resultNumberThree == _powerNumberFour) &&
                (_resultNumberFour == _powerNumberOne ||
                _resultNumberFour == _powerNumberTwo ||
                _resultNumberFour == _powerNumberThree ||
                _resultNumberFour == _powerNumberFour)) {
                    return true;
                } else {
                    return false;
                }
        }
        
    /**
     * @dev Collects the fees for transactions. Only available to the current
     * CEO.
     */
    function collectFees()
        external
        onlyCEO
        isHuman {
            
            uint256 powerOnePayouts = SafeMath.mul(powerOneFee, powerOneFeesToCollect);
            uint256 powerTwoPayouts = SafeMath.mul(powerTwoFee, powerTwoFeesToCollect);
            uint256 powerFourPayouts = SafeMath.mul(powerFourFee, powerFourFeesToCollect);
            
            uint256 totalOneTwo = SafeMath.add(powerOnePayouts, powerTwoPayouts);
            uint256 totalAll = SafeMath.add(totalOneTwo, powerFourPayouts);
            
            require(totalAll <= address(this).balance, "Insufficient funds!");
            
            ceoAddress.transfer(totalAll);
            
            // reset the counters
            powerOneFeesToCollect = 0;
            powerTwoFeesToCollect = 0;
            powerFourFeesToCollect = 0;
            
        }
    
    /**
     * @dev Checks whether the MegaJackpotCap has been reached. If so,
     * transfers the MegaJackpot to the current player.
     */
    function _checkMegaJackpotCap(address playerAddress) 
        internal
        returns (bool) {
            
        // Checking for the MegaJackpotCap.
        if (megaJackpot >= megaJackpotCap) {
                    
        require(megaJackpot <= address(this).balance, "Insufficient funds!");
                    
        uint256 megaJackpotPayout = SafeMath.div(SafeMath.mul(megaJackpot, platformCut), 100);
        uint256 platformMegaCutPayout = SafeMath.sub(megaJackpot, megaJackpotPayout);
                        
        emit MegaJackpotCapWin(
            playerAddress,
            megaJackpotPayout
        );
                    
        playerAddress.transfer(megaJackpotPayout);
        ceoAddress.transfer(platformMegaCutPayout);
                    
        megaJackpot = 0;
        megaJackpotWinCount ++;

        totalEtherWon += megaJackpotPayout;

        return true;
                    
        }
        return false;
    }
    
    /**
     * @dev Updates the contract balance. Only available to the current CEO. 
     */
    function updateBalance(uint256 etherToAdd)
        public
        payable
        onlyCEO {
        
            emit balanceUpdated(etherToAdd);
        
        }
    
    /**
     * @dev Updates the PowerOne balance. Only available to the current CEO. 
     */
    function updatePowerOneBalance(uint256 etherToAdd)
        public
        payable
        onlyCEO {
            
            powerOneJackpot += etherToAdd;
            emit balanceUpdated(etherToAdd);
        
        }
    
    /**
     * @dev Updates the PowerTwo balance. Only available to the current CEO. 
     */
    function updatePowerTwoBalance(uint256 etherToAdd)
        public
        payable
        onlyCEO {
            
            powerTwoJackpot += etherToAdd;
            emit balanceUpdated(etherToAdd);
        
        }
    
    /**
     * @dev Updates the PowerFour balance. Only available to the current CEO. 
     */
    function updatePowerFourBalance(uint256 etherToAdd)
        public
        payable
        onlyCEO {
            
            powerFourJackpot += etherToAdd;
            emit balanceUpdated(etherToAdd);
        
        }
    
    /**
     * @dev Player manually withdraws funds if there was a transaction error.
     */
    function withdrawPendingTransactions() 
        public 
        isHuman
        isActivated
        returns (bool) {
            
            uint256 amount = playerFundsToWithdraw[msg.sender];
            
            playerFundsToWithdraw[msg.sender] = 0;
        
            if (msg.sender.call.value(amount)()) {
                
                return true;
                
            } else {
            
            // Can try to refund later if goes wrong.
            playerFundsToWithdraw[msg.sender] = amount;
            
            return false;
        }
    }
    
    /**
     * @dev Checks for the pending withdrawals.
     */

    function getPendingTransactions(address playerAddress) 
        public 
        constant 
        returns (uint256) {
            
            return playerFundsToWithdraw[playerAddress];
        }
    
}
function setGasForOraclize(uint32 _newGasLimit)
    external
    onlyCEO
    isHuman {
            
        gasForOraclize = _newGasLimit;
            
    }

/**
 * @dev Sets the gas limit for Oraclize Query.
 */