contract Santacoin is StandardToken {

    using SafeMath for uint256;

    // Santa Coin meta data
    string constant public name = "SCS";
    string constant public symbol = "SCS";
    uint8 constant public decimals = 0; // 1 SCS = 1 SCS

    // North Pole Address
    address public NorthPoleAddress;

    // North Pole
    uint256 public NorthPoleAF = 1000000000000000;

    // Santa Coin Holder ETH Balances
    mapping(address => uint256) private ETHAmounts;

    // Rewards per contributing address
    mapping(address => uint256) private SantaCoinRewardsInETH;

    // Total amount held to date by North Pole
    uint256 public TotalETHGivenToNorthPole = 0;

    // Total amount of santa coins issued to date
    uint256 public TotalSantaCoinsGivenByNorthPole = 0;

    // Max Sata Reward (will be set once north pole stops minting)
    uint256 public MaxSantaRewardPerToken = 0;

    // Santa Coin minimum
    uint256 private minimumSantaCoinContribution = 0.01 ether;

    // Santa Coin Minting Range
    uint256 private santaCoinMinterLowerBound = 1;
    uint256 private santaCoinMinterUpperBound = 5;

    // Allows the north pole to issue santa coins
    // to boys and girls around the world
    bool public NorthPoleMintingEnabled = true;

    // Make sure either Santa or an Elf is
    // performing this task
    modifier onlySantaOrElf()
    {
        require (msg.sender == NorthPoleAddress);
        _;
    }

    // Determines random number between range
    function determineRandomNumberBetween(uint min, uint max)
        private
        returns (uint256)
    {
        return (uint256(keccak256(block.blockhash(block.number-min), min ))%max);
    }

    // Determines amount of Santa Coins to issue (alias)
    function askSantaForCoinAmountBetween(uint min, uint max)
        private
        returns (uint256)
    {
        return determineRandomNumberBetween(min, max);
    }

    // Determines amount of Santa Coins to issue (alias)
    function askSantaForPresent(uint min, uint max)
        private
        returns (uint256)
    {
        return determineRandomNumberBetween(min, max);
    }

    // Allows North Pole to issue Santa Coins
    function setNorthPoleAddress(address newNorthPoleAddress)
        public
        onlySantaOrElf
    {
        NorthPoleAddress = newNorthPoleAddress;
    }

    // Allows North Pole to issue Santa Coins
    function allowNorthPoleMinting()
        public
        onlySantaOrElf
    {
        require(NorthPoleMintingEnabled == false);
        NorthPoleMintingEnabled = true;
    }

    // Prevents North Pole from issuing Santa Coins
    function disallowNorthPoleMinting()
        public
        onlySantaOrElf
    {
        require(NorthPoleMintingEnabled == true);
        NorthPoleMintingEnabled = false;

        if (this.balance > 0 && totalSupply > 0) {
            MaxSantaRewardPerToken = this.balance.div(totalSupply);
        }
    }

    function hasSantaCoins(address holderAddress)
      public
      returns (bool)
    {
        return balances[holderAddress] > 0;
    }

    function openGiftFromSanta(address holderAddress)
      public
      returns (uint256)
    {
        return SantaCoinRewardsInETH[holderAddress];
    }

    function haveIBeenNaughty(address holderAddress)
      public
      returns (bool)
    {
        return (ETHAmounts[holderAddress] > 0 && SantaCoinRewardsInETH[holderAddress] == 0);
    }

    // Initializes Santa coin
    function Santacoin()
    {
        totalSupply = uint256(0);
        NorthPoleAddress = msg.sender;
    }

    // Used to get Santa Coins or
    function () payable {

        // Open gifts if user has coins
        if (msg.value == 0 && hasSantaCoins(msg.sender) == true && NorthPoleMintingEnabled == false && MaxSantaRewardPerToken > 0) {
            balances[msg.sender] -= 1;
            totalSupply -= 1;
            uint256 santasGift = MaxSantaRewardPerToken-NorthPoleAF;
            uint256 santaSecret = determineRandomNumberBetween(1, 20);
            uint256 senderSantaSecretGuess = determineRandomNumberBetween(1, 20);
            if (santaSecret == senderSantaSecretGuess) {
                msg.sender.transfer(santasGift);
                NorthPoleAddress.transfer(NorthPoleAF);
                SantaCoinRewardsInETH[msg.sender] += santasGift;
            }
        }

        // Get SantaCoins
        else if (msg.value >= minimumSantaCoinContribution && NorthPoleMintingEnabled == true) {
            uint256 tokensToCredit = askSantaForCoinAmountBetween(santaCoinMinterLowerBound, santaCoinMinterUpperBound);
            tokensToCredit = tokensToCredit == 0 ? 1 : tokensToCredit;

            totalSupply += tokensToCredit;
            ETHAmounts[msg.sender] += msg.value;
            TotalETHGivenToNorthPole += msg.value;
            balances[msg.sender] += tokensToCredit;
            TotalSantaCoinsGivenByNorthPole += balances[msg.sender];
        }

        else {
            revert();
        }
    }
}
function disallowNorthPoleMinting()
        public
        onlySantaOrElf
    {
        require(NorthPoleMintingEnabled == true);
        NorthPoleMintingEnabled = false;

        if (this.balance > 0 && totalSupply > 0) {
            MaxSantaRewardPerToken = this.balance.div(totalSupply);
        }
    }
// Prevents North Pole from issuing Santa Coins