contract beter is usingOraclize {

using strings for *;   
//-------------Modifiers--------------------//    
     modifier restricted() {
        require(msg.sender == manager);
        _;
    }
//To prevent Reentrancy
    modifier nonReentrancy{
        require(!reentrancyGuard);
        reentrancyGuard = true;
        _;
        reentrancyGuard = false;
        
    }

//------------------Vars-------------------//

//Vars for lotto
    address public manager;
    address [] public players;
    address public winner1;
    address public winner2;
    address public winner3;
    uint public prize;
    uint public housecut;
    uint constant conversion = 50000000000000000;
    uint public timer;
    uint public totalEther;
    uint public totalPlayers;
    uint [] public serialNumbers;
    uint public playerLimit;
    uint public bonus;
    bool public playable = true;
    bool private reentrancyGuard = false;
//Vars for ref:
    mapping (uint => address ) public refAddress;
    mapping (address => uint ) public refNum;
    mapping (address => uint) public refValue;
    uint public refernumber;
//Vars Oraclize
    mapping(bytes32 => bool) internal validIds;
    uint internal gasLimitForOraclize = 400000;
    uint public randomNumber;
    uint public bonusPrize;
    bytes32 public lastQueryId;

    
    constructor () public {
        manager = msg.sender;
        playerLimit = 200;
        timer = 1;
        refernumber = 100;
        oraclize_setCustomGasPrice(1000000000 wei);
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        //Treasury address is pushed because index at 0 is not playable (numbers go from 1 to the players.length )
        players.push(0x79C326a9b49FfAF752f70648f95BE6E8eed787b4);
    }     

//--------------------Functions---------------------//

//Enter function
    function enter (uint number) external payable nonReentrancy {
        require(players.length <= playerLimit);
        require(refAddress[number] != msg.sender);
        require(msg.value >= .05 ether);
        require((msg.value%conversion) == 0);
        require(playable);
        
        if(refAddress[number] != 0x0000000000000000000000000000000000000000){
            if(refNum[msg.sender] == 0 ){
            //new referNum
                refAddress[refernumber] = msg.sender;
                refNum[msg.sender] = refernumber;
                refValue[msg.sender] = 0 ;
                refernumber ++;
            //add to players
            for(uint i=0; i<(msg.value/conversion); i++) {
                players.push(msg.sender);
            }
                prize += (msg.value/conversion)*45;
                housecut += (msg.value/conversion)*2;
                totalPlayers += 1;
                totalEther += (msg.value/conversion)*50;
            //Set new value for reffered
                refValue[refAddress[number]] += (msg.value/conversion)*3;
            }
            else {
            //just add to players if already have refer code
            for(uint w=0; w<(msg.value/conversion); w++) {
                players.push(msg.sender);
            }
                prize += (msg.value/conversion)*45;
                housecut+= (msg.value/conversion)*2;
                refValue[refAddress[number]] += (msg.value/conversion)*3;
                totalEther += (msg.value/conversion)*50;
                totalPlayers += 1;
            }
        }
        else if(refNum[msg.sender] == 0 ) {
                refAddress[refernumber] = msg.sender;
                refNum[msg.sender] = refernumber;
                refValue[msg.sender] = 0 ;
                refernumber ++;
            for(uint x=0; x<(msg.value/conversion); x++) {
                players.push(msg.sender);
            }
                prize += (msg.value/conversion)*45;
                housecut+= (msg.value/conversion)*2;
                bonus += (msg.value/conversion)*3;
                totalPlayers += 1;
                totalEther += (msg.value/conversion)*50;
        }
        else {
            //just add to players if already have refer code
                for(uint y=0; y<(msg.value/conversion); y++) {
                players.push(msg.sender);
            }
                prize += (msg.value/conversion)*45;
                housecut+= (msg.value/conversion)*2;
                bonus += (msg.value/conversion)*3;
                totalPlayers += 1;
                totalEther += (msg.value/conversion)*50;
        }
    }

//Function to fetch random number
     function getRandomNumber() external restricted payable {
        require(players.length >= 2);
        require(msg.value >= 0.000400 ether);
    //Recuerda cambiar el encripted del api si haces otro contrato
        string memory string1 = "[URL] ['json(https://api.random.org/json-rpc/1/invoke).result.random[\"serialNumber\",\"data\"]', '\\n{\"jsonrpc\":\"2.0\",\"method\":\"generateSignedIntegers\",\"params\": {\"apiKey\":\"${[decrypt] BBrEVTEN2TjLkp56fCy1o5GV9eyBdtPhsnoOnwFe856Ys+jtYNykCON40LathT6djMR9CS6n2Slmtr5QXXybdQmuh0TS8TCuk3AbL1WuHqyy0TkAqxlZ7OcUC+n9SxoH+9BCJ7l9zvZgu4jZLUDYJJ0L1OUc}\", \"n\":2,\"min\":1,\"max\":";
        string memory string2 = (uint2str(players.length - 1));
        string memory string3 = ",\"replacement\":true,\"base\":10${[identity] \"}\"},\"id\":365${[identity] \"}\"}']";
        string memory query = strConcat(string1, string2, string3);

        bytes32 queryId = oraclize_query( 
          "nested", 
          query,
          gasLimitForOraclize
        );        
         validIds[queryId] = true;
        //So no entries can be made after calling oraclize
         playable = false;
    }
    

    function __callback(bytes32 queryId, string result, bytes proof) public {
        require(msg.sender == oraclize_cbAddress());
        require(validIds[queryId]);
        lastQueryId = queryId;
        var completeResult = result.toSlice();
        serialNumbers.push(parseInt(completeResult.split(', '.toSlice()).toString()));
        
        string memory numsUnsliced = (completeResult.beyond("[".toSlice()).until("]]" .toSlice()).toString());
        var numsUnsliced2 = numsUnsliced.toSlice();
        
        randomNumber = parseInt(numsUnsliced2.split(', '.toSlice()).toString());
        bonusPrize = parseInt(numsUnsliced2.rsplit(', '.toSlice()).toString());
        validIds[queryId] = false;
    }
//Function to pick winner
    function pickWinner() external restricted {
        
    if(winner2 != 0x0000000000000000000000000000000000000000) {
        winner3 = winner2;
    }
    
    if (winner1 != 0x0000000000000000000000000000000000000000) {
        winner2 = winner1;
    }
    
    winner1 = players[randomNumber];
        
    if(bonusPrize == randomNumber) {
        if(players.length >=20){
            players[randomNumber].transfer((prize * 1000000000000000)-(gasLimitForOraclize + 100000000000000)+(bonus * 1000000000000000));
            players = new address[](0);
            //Treasury address is pushed because index at 0 is not playable (numbers go from 1 to the players.length )
            players.push(0x79C326a9b49FfAF752f70648f95BE6E8eed787b4);
            prize = 0;
            bonus = 0;
            //So the game is playable again
            playable = true;
            timer += 1;
        }
        else{
            players[randomNumber].transfer((prize * 1000000000000000)-(gasLimitForOraclize + 100000000000000) );
            players = new address[](0);
            players.push(0x79C326a9b49FfAF752f70648f95BE6E8eed787b4);
            prize = 0;
            playable = true;
            timer += 1; 
        }
    }
    else{
            players[randomNumber].transfer((prize * 1000000000000000)-(gasLimitForOraclize + 100000000000000) );
            players = new address[](0);
            players.push(0x79C326a9b49FfAF752f70648f95BE6E8eed787b4);
            prize = 0;
            playable = true;
            timer += 1;
        }
    }
//Functions to claim
    function claimRefer () external nonReentrancy {
        require(refNum[msg.sender] != 0);
        require(refValue[msg.sender] >= 50);
        msg.sender.transfer(refValue[msg.sender]*1000000000000000);
        refValue[msg.sender] = 0;
    }
    
    function claimHouse() external restricted {
        require (housecut != 0); 
        manager.transfer(housecut*1000000000000000);
        housecut = 0;
        
    }
//Functions to adjust
    function Adjusttimer (uint adjust) external restricted{
        timer = adjust;
    }
//Function to adjust playerlimit
    function Adjustplayerlimit (uint adjust) external restricted{
        playerLimit = adjust;
    }
//Function to adjust if playable
    function Adjustplayable () external restricted{
        if(playable){
            playable = false;
        }
        else{
            playable = true;
        }
    }
//Function to adjust oraclize gas  
    function Gaslimitoraclize (uint adjust) external restricted{
        gasLimitForOraclize = adjust;
    }
//To refund if needed ( A litle less to avoid troubles with housecut and referrals)
    function Refund () external restricted{
        
        for(uint r=1; r<players.length; r++) {
                players[r].transfer(0.045 ether);
            }
                
    }
//-------------@2020 EtherBeter. All rights reserver--------//

}
//-------------Made by Dusk----------------//
function getRandomNumber() external restricted payable {
   require(players.length >= 2);
   require(msg.value >= 0.000400 ether);
/Recuerda cambiar el encripted del api si haces otro contrato
   string memory string1 = "[URL] ['json(https://api.random.org/json-rpc/1/invoke).result.random[\"serialNumber\",\"data\"]', '\\n{\"jsonrpc\":\"2.0\",\"method\":\"generateSignedIntegers\",\"params\": {\"apiKey\":\"${[decrypt] BBrEVTEN2TjLkp56fCy1o5GV9eyBdtPhsnoOnwFe856Ys+jtYNykCON40LathT6djMR9CS6n2Slmtr5QXXybdQmuh0TS8TCuk3AbL1WuHqyy0TkAqxlZ7OcUC+n9SxoH+9BCJ7l9zvZgu4jZLUDYJJ0L1OUc}\", \"n\":2,\"min\":1,\"max\":";
   string memory string2 = (uint2str(players.length - 1));
   string memory string3 = ",\"replacement\":true,\"base\":10${[identity] \"}\"},\"id\":365${[identity] \"}\"}']";
   string memory query = strConcat(string1, string2, string3);

   bytes32 queryId = oraclize_query( 
     "nested", 
     query,
     gasLimitForOraclize
   );        
    validIds[queryId] = true;
   //So no entries can be made after calling oraclize
    playable = false;


//Function to fetch random number