function setupRace(uint delay, uint  locking_duration) onlyOwner beforeBetting public payable returns(bool) {
        
        if (oraclize_getPrice("URL")*3 + oraclize_getPrice("URL", horses.customGasLimit)*3  > address(this).balance) {
            emit newOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee");
            return false;
        } else {
            chronus.starting_time = uint32(block.timestamp);
            chronus.betting_open = true;
            bytes32 temp_ID; 
            emit newOraclizeQuery("Oraclize query was sent, standing by for the answer..");
            
            chronus.betting_duration = uint32(delay);
            temp_ID = oraclize_query(delay, "URL", "json(https:
            oraclizeIndex[temp_ID] = horses.ETH;
            coinIndex[horses.ETH].preOraclizeId = temp_ID;

            temp_ID = oraclize_query(delay, "URL", "json(https:
            oraclizeIndex[temp_ID] = horses.LTC;
            coinIndex[horses.LTC].preOraclizeId = temp_ID;

            temp_ID = oraclize_query(delay, "URL", "json(https:
            oraclizeIndex[temp_ID] = horses.BTC;
            coinIndex[horses.BTC].preOraclizeId = temp_ID;

            
            delay = delay.add(locking_duration);

            temp_ID = oraclize_query(delay, "URL", "json(https:
            oraclizeIndex[temp_ID] = horses.ETH;
            coinIndex[horses.ETH].postOraclizeId = temp_ID;

            temp_ID = oraclize_query(delay, "URL", "json(https:
            oraclizeIndex[temp_ID] = horses.LTC;
            coinIndex[horses.LTC].postOraclizeId = temp_ID;

            temp_ID = oraclize_query(delay, "URL", "json(https:
            oraclizeIndex[temp_ID] = horses.BTC;
            coinIndex[horses.BTC].postOraclizeId = temp_ID;

            chronus.race_duration = uint32(delay);
            return true;
        }
    }

    
    function reward() internal {
        
        horses.BTC_delta = int32(coinIndex[horses.BTC].post - coinIndex[horses.BTC].pre)*100000/int32(coinIndex[horses.BTC].pre);
        horses.ETH_delta = int32(coinIndex[horses.ETH].post - coinIndex[horses.ETH].pre)*100000/int32(coinIndex[horses.ETH].pre);
        horses.LTC_delta = int32(coinIndex[horses.LTC].post - coinIndex[horses.LTC].pre)*100000/int32(coinIndex[horses.LTC].pre);
        
        total_reward = (coinIndex[horses.BTC].total) + (coinIndex[horses.ETH].total) + (coinIndex[horses.LTC].total);
        if (total_bettors <= 1) {
            forceVoidRace();
        } else {
            uint house_fee = total_reward.mul(5).div(100);
            require(house_fee < address(this).balance);
            total_reward = total_reward.sub(house_fee); 
            bettingControllerInstance.depositHouseTakeout.value(house_fee)();
        }
        
        if (horses.BTC_delta > horses.ETH_delta) {
            if (horses.BTC_delta > horses.LTC_delta) {
                winner_horse[horses.BTC] = true;
                winnerPoolTotal = coinIndex[horses.BTC].total;
            }
            else if(horses.LTC_delta > horses.BTC_delta) {
                winner_horse[horses.LTC] = true;
                winnerPoolTotal = coinIndex[horses.LTC].total;
            } else {
                winner_horse[horses.BTC] = true;
                winner_horse[horses.LTC] = true;
                winnerPoolTotal = coinIndex[horses.BTC].total + (coinIndex[horses.LTC].total);
            }
        } else if(horses.ETH_delta > horses.BTC_delta) {
            if (horses.ETH_delta > horses.LTC_delta) {
                winner_horse[horses.ETH] = true;
                winnerPoolTotal = coinIndex[horses.ETH].total;
            }
            else if (horses.LTC_delta > horses.ETH_delta) {
                winner_horse[horses.LTC] = true;
                winnerPoolTotal = coinIndex[horses.LTC].total;
            } else {
                winner_horse[horses.ETH] = true;
                winner_horse[horses.LTC] = true;
                winnerPoolTotal = coinIndex[horses.ETH].total + (coinIndex[horses.LTC].total);
            }
        } else {
            if (horses.LTC_delta > horses.ETH_delta) {
                winner_horse[horses.LTC] = true;
                winnerPoolTotal = coinIndex[horses.LTC].total;
            } else if(horses.LTC_delta < horses.ETH_delta){
                winner_horse[horses.ETH] = true;
                winner_horse[horses.BTC] = true;
                winnerPoolTotal = coinIndex[horses.ETH].total + (coinIndex[horses.BTC].total);
            } else {
                winner_horse[horses.LTC] = true;
                winner_horse[horses.ETH] = true;
                winner_horse[horses.BTC] = true;
                winnerPoolTotal = coinIndex[horses.ETH].total + (coinIndex[horses.BTC].total) + (coinIndex[horses.LTC].total);
            }
        }
        chronus.race_end = true;
    }

    
    function calculateReward(address candidate) internal afterRace constant returns(uint winner_reward) {
        voter_info storage bettor = voterIndex[candidate];
        if(chronus.voided_bet) {
            winner_reward = bettor.total_bet;
        } else {
            uint winning_bet_total;
            if(winner_horse[horses.BTC]) {
                winning_bet_total += bettor.bets[horses.BTC];
            } if(winner_horse[horses.ETH]) {
                winning_bet_total += bettor.bets[horses.ETH];
            } if(winner_horse[horses.LTC]) {
                winning_bet_total += bettor.bets[horses.LTC];
            }
            winner_reward += (((total_reward.mul(10000000)).div(winnerPoolTotal)).mul(winning_bet_total)).div(10000000);
        } 
    }

    
    function checkReward() afterRace external constant returns (uint) {
        require(!voterIndex[msg.sender].rewarded);
        return calculateReward(msg.sender);
    }

    
    function claim_reward() afterRace external {
        require(!voterIndex[msg.sender].rewarded);
        uint transfer_amount = calculateReward(msg.sender);
        require(address(this).balance >= transfer_amount);
        voterIndex[msg.sender].rewarded = true;
        msg.sender.transfer(transfer_amount);
        emit Withdraw(msg.sender, transfer_amount);
    }
    
    function forceVoidRace() internal {
        chronus.voided_bet=true;
        chronus.race_end = true;
        chronus.voided_timestamp=uint32(now);
    }

    
    function stringToUintNormalize(string s) internal pure returns (uint result) {
        uint p =2;
        bool precision=false;
        bytes memory b = bytes(s);
        uint i;
        result = 0;
        for (i = 0; i < b.length; i++) {
            if (precision) {p = p-1;}
            if (uint(b[i]) == 46){precision = true;}
            uint c = uint(b[i]);
            if (c >= 48 && c <= 57) {result = result * 10 + (c - 48);}
            if (precision && p == 0){return result;}
        }
        while (p!=0) {
            result = result*10;
            p=p-1;
        }
    }


    
    function getCoinIndex(bytes32 index, address candidate) external constant returns (uint, uint, uint, bool, uint) {
        return (coinIndex[index].total, coinIndex[index].pre, coinIndex[index].post, coinIndex[index].price_check, voterIndex[candidate].bets[index]);
    }

    
    function reward_total() external constant returns (uint) {
        return ((coinIndex[horses.BTC].total) + (coinIndex[horses.ETH].total) + (coinIndex[horses.LTC].total));
    }
    
    
    function refund() external onlyOwner {
        require(now > chronus.starting_time + chronus.race_duration);
        require((chronus.betting_open && !chronus.race_start)
            || (chronus.race_start && !chronus.race_end));
        chronus.voided_bet = true;
        chronus.race_end = true;
        chronus.voided_timestamp=uint32(now);
        bettingControllerInstance.remoteBettingClose();
    }

    
    function recovery() external onlyOwner{
        require((chronus.race_end && now > chronus.starting_time + chronus.race_duration + (30 days))
            || (chronus.voided_bet && now > chronus.voided_timestamp + (30 days)));
        bettingControllerInstance.depositHouseTakeout.value(address(this).balance)();
    }
}