contract Cryptodraw is usingOraclize {
    address private contractOwner;
    address[] private playerList;

    // Oracle to query WolframAlpha
    string private wolframRandom;
    event newWolframRandom(string wolframRandom);
    
    // Public seed of the previous round
    string private previousSeed;
    bytes32 private previousHash;
    uint private previousHashUint;
    uint private previousWinner;
    
    // Winner variable
    uint private winner;
    // Ticketprice per entry
    uint constant ticketPrice = 0.01 ether;
    // Maximum of players to join
    uint constant maxPlayers = 25;
    // Maximum of players to join
    uint constant Fee = 4;
    // Track the poolround
    uint round = 1;
    //Declare owners address
    address poolOwner = msg.sender;
    // Declare timestamp 
    uint timestamp = now + 2 weeks;

    // Contructor to initiate the conatract
    function Cryptodraw() public {
        contractOwner = msg.sender;
        oraclize_setCustomGasPrice(5000000000 wei);
    }
    
    modifier restricted() {
        require(msg.sender == contractOwner);
        _;
    }

    function __callback(bytes32 myid, string result) {
        if (msg.sender != oraclize_cbAddress()) throw;
        wolframRandom = result;
        newWolframRandom(wolframRandom);
        uint ownerFee = address(this).balance / 100 * Fee;
        uint totalPayout = address(this).balance - ownerFee;
        // Pick the winner of the lottery
        winner = calculateHash() % playerList.length;
        // Send reward to the winner
        playerList[winner].transfer(totalPayout);
        // Send reward to the contractOwner
        poolOwner.transfer(ownerFee);
        
        // List the previous seed to verify results 
        previousSeed = wolframRandom;
        previousHash = keccak256(wolframRandom);
        previousHashUint = uint(keccak256(wolframRandom));
        previousWinner = winner;
        
        // Clear the current addresses so pool can restart
        playerList = new address[](0);

        // Set some round specific stuff
        round += 1;      
        timestamp = now + 2 weeks;
    }
    
    function joinLottery() public payable {
        if (playerList.length < maxPlayers) {
            require(msg.value == ticketPrice);
            playerList.push(msg.sender);
        }
        else {
            revert();
        }
    }

    // Calculating hash with a oracilize seed (Wolfram)
    function calculateHash() internal returns (uint) {
        return uint(keccak256(wolframRandom));
    }
    
    function update() payable {
        if (playerList.length == maxPlayers || now > timestamp) {
            if (oraclize_getPrice("URL") > this.balance) {
            // "Oraclize query was NOT sent, please add some ETH to cover for the query fee
            } 
            else {
            // Oraclize can be queried
            oraclize_query("WolframAlpha", "Give me 20 random words", 700000);
            }
        }
        else {
            revert();
        }
    }
    
    function notSameSeed (string a, string b) private view returns (bool) {
       return keccak256(a) != keccak256(b);
   }
    
    function getPreviousSeed() public view returns (string) {
        return previousSeed;
    }
    
    function getHash() public view returns (bytes32) {
        return previousHash;
    }
    
    function getPreviousHashUint() public view returns (uint) {
        return previousHashUint;
    }
    
    function getPlayerLength() public view returns (uint) {
        return playerList.length;
    }
    
    function getPreviousWinner() public view returns (uint) {
        return previousWinner;
    }
    
    
     // Return list of players
    function getPlayers() public view returns (address[]) {
        return playerList;
    }
    
    // Return list of players
    function getTime() public view returns (uint) {
        return timestamp;
    }
    

    //Return max entries
    function getMaxTickets() public view returns (uint) {
        return maxPlayers;
    }
    
        //Return max entries
    function getRound() public view returns (uint) {
        return round;
    }
    
        //Return tickets left in the contract
    function getTicketsLeft() public view returns (uint) {
        return maxPlayers - playerList.length;
    }
    
        //Get total lottery amount
    function getLotteryBalance() public view returns (uint) {
        return address(this).balance;
    }
    
            //Get total lottery amount
    function getTicketPrice() public view returns (uint) {
        return ticketPrice;
    }
    
}
function getMaxTickets() public view returns (uint) {
    return maxPlayers;
}

//Return max entries