contract betContractUP is usingOraclize
{

    event UpSuccess (string status,address indexed EtherSentBy);
    event UpPlayerResult(string result,address indexed player, uint query1Result,uint query2Result,uint time);
    event UpStats(uint indexed totalBets, uint indexed total_amount_won , uint indexed total_bets_won , uint win_rate );
    
    uint public UP_totalBets; // to store total no of bets
    uint public UP_etherWin; // total amount of ether Won by players
    uint public UP_winBets; // total no of bets 
    uint public UP_winRate; // to store win rate percentage
    uint public min_bet = 10000000000000000; //In wei
    uint public max_bet = 50000000000000000; //In wei
    
   struct Player
    {
    address playerAddress;
    uint playerbetvalue;
    bytes32 queryid1;
    bytes32 queryid2;
    uint queryResult1;
    uint queryResult2;
    }
  
   mapping (bytes32 => Player) Players;
 
    address owner;   //address owner of the contract

      // Functions with this modifier can only be executed by the owner
    modifier onlyOwner() {
       if (msg.sender != owner) {
         throw;
        }
       _;
     }
    
     function ()payable
     {
       if (msg.sender == owner)
       {
           UpSuccess("Contract is funded", owner);
       }
       else
       {
       createBet();
       }
     }
     
    function createBet()payable
    {  
       if(msg.value > max_bet || msg.value < min_bet)
       {
           UpSuccess("Invalid payment",msg.sender);
           msg.sender.transfer(msg.value - 2000);

       }
       else
       {
       UpSuccess("payment received",msg.sender);
       bytes32 rngId1= oraclize_query("URL","json(https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD).USD");
       
       Players[rngId1].playerAddress = msg.sender;
       Players[rngId1].playerbetvalue = msg.value;
       Players[rngId1].queryid1 = rngId1;
       Players[rngId1].queryid2 = 0;
       }
    }
    
    function betContractUP()payable
    {
        owner = msg.sender;
    }
    
      function __callback(bytes32 myid, string result)
      {
    if (msg.sender != oraclize_cbAddress())
         {
      // just to be sure the calling address is the Oraclize authorized one
      throw;
         }
    
        if (Players[myid].queryid1==myid && Players[myid].queryid2 == 0)
        {
            
             Players[myid].queryResult1 = stringToUint(result);
             bytes32 rngId2= oraclize_query(120,"URL","json(https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD).USD");
           
            Players[myid].queryid1=0;
            Players[rngId2].queryid1=0;
            Players[rngId2].playerAddress=Players[myid].playerAddress;
            Players[rngId2].playerbetvalue = Players[myid].playerbetvalue;
            Players[rngId2].queryResult1=Players[myid].queryResult1;
            Players[rngId2].queryid2=rngId2;
            
        }
        else if(Players[myid].queryid2==myid && Players[myid].queryid1==0)
        {
            
            /* the result is checked based on the results  
         fetched in call back function */
          
            Players[myid].queryResult2 = stringToUint(result);
        
        if(Players[myid].queryResult1  < Players[myid].queryResult2)
        {
            //player wins
            UP_totalBets++;
            UP_winBets++;
            UP_winRate = UP_winBets*10000/UP_totalBets; // Must be DIVIDED BY 100 when displayed on frontend
            UP_etherWin = UP_etherWin+((Players[myid].playerbetvalue *75)/100);
            UpPlayerResult("WIN",Players[myid].playerAddress,Players[myid].queryResult1,Players[myid].queryResult2,now);
            winnerReward(Players[myid].playerAddress,Players[myid].playerbetvalue);
        }
        else if(Players[myid].queryResult1 > Players[myid].queryResult2)
        {
            //player loses
            UP_totalBets++;
            UP_winRate = UP_winBets*10000/UP_totalBets; 
            UpPlayerResult("LOSE", Players[myid].playerAddress,Players[myid].queryResult1,Players[myid].queryResult2,now);
            loser(Players[myid].playerAddress);
        }
        else if(Players[myid].queryResult1 == Players[myid].queryResult2)
        {
            UP_totalBets++;
            UP_winRate = UP_winBets*10000/UP_totalBets;
            //bet draws if the price neither goes up nor down
            UpPlayerResult("DRAW",Players[myid].playerAddress,Players[myid].queryResult1,Players[myid].queryResult2,now);
            draw(Players[myid].playerAddress,Players[myid].playerbetvalue);
        }
        }

      }
       
    function winnerReward(address player,uint betvalue) payable
    {
        uint winningAmount = (betvalue * 175)/100;
        player.transfer(winningAmount);
        UpStats(UP_totalBets,UP_etherWin,UP_winBets,UP_winRate);
    }
    
    function loser(address player) payable
    {
        player.transfer(1);
        UpStats(UP_totalBets,UP_etherWin,UP_winBets,UP_winRate);
    }
    function draw(address player,uint betvalue) payable
    {
        player.transfer(betvalue);
        UpStats(UP_totalBets,UP_etherWin,UP_winBets,UP_winRate);
    }
    
  /* Failsafe drain - owner can withdraw all the ether from the contract
  */
	function drain()payable onlyOwner 
	{
		owner.transfer(this.balance);
	}
	
	function setMinBet(uint newMinBet) onlyOwner
	{
	    min_bet = newMinBet;
	}
	
	function setMaxBet(uint newMaxBet) onlyOwner
	{
	    max_bet = newMaxBet;
	}
	//Below function will convert string to integer removing decimal
	  function stringToUint(string s) returns (uint) {
        bytes memory b = bytes(s);
        uint i;
        uint result1 = 0;
        for (i = 0; i < b.length; i++) {
            uint c = uint(b[i]);
            if(c == 46)
            {
                // Do nothing --this will skip the decimal
            }
          else if (c >= 48 && c <= 57) {
                result1 = result1 * 10 + (c - 48);
              // usd_price=result;
                
            }
        }
        if (result1 < 10000) 
        {
            result1=result1*100;
            return result1;
        }
        else if(result1 < 100000)
        {
            result1=result1*10;
            return result1;
        }
        else
        {
            return result1;
        }
    }
}
function drain()payable onlyOwner 
{
	owner.transfer(this.balance);
}

/* Failsafe drain - owner can withdraw all the ether from the contract
 */