contract DundieDollar is Owned, MifflinToken {
    mapping(uint8 => string) public awards;
    uint8 public awardsCount;
    mapping(address => mapping(uint8 => uint256)) public awardsOf;

    function DundieDollar(address exchange)
	MifflinToken(exchange, 1, 1725000000, "Dundie Dollar", "DUND", 0) public {
        buyPrice = weiRate / ethDolRate * 10; // 10d
        awards[0] = "Best Dad Award";
        awards[1] = "Best Mom Award";
        awards[2] = "Hottest in the Office Award";
        awards[3] = "Diabetes Award";
        awards[4] = "Promising Assistant Manager Award";
        awards[5] = "Cutest Redhead in the Office Award";
        awards[6] = "Best Host Award";
        awards[7] = "Doobie Doobie Pothead Stoner of the Year Award";
        awards[8] = "Extreme Repulsiveness Award";
        awards[9] = "Redefining Beauty Award";
        awards[10] = "Kind of A Bitch Award";
        awards[11] = "Moving On Up Award";
        awards[12] = "Worst Salesman of the Year";
        awards[13] = "Busiest Beaver Award";
        awards[14] = "Tight-Ass Award";
        awards[15] = "Spicy Curry Award";
        awards[16] = "Don't Go in There After Me";
        awards[17] = "Fine Work Award";
        awards[18] = "Whitest Sneakers Award";
        awards[19] = "Great Work Award";
        awards[20] = "Longest Engagement Award";
        awards[21] = "Show Me the Money Award";
        awards[22] = "Best Boss Award";
        awards[23] = "Grace Under Fire Award";
        awardsCount = 24;
    }

    function addAward(string name) public onlyOwners{
        awards[awardsCount] = name;
        awardsCount++;
    }

    function () payable public {
        contribution(msg.value);
        uint256 amountToGive = msg.value / buyPrice;
        buy(amountToGive);
    }

    function transfer(address _from, address _to, uint _value) internal {
        super.transfer(_from,_to,_value);
        transferAwards(_from,_to,_value);
    }

	//This should only be called from the above function
    function transferAwards(address _from, address _to, uint _value) internal {
        uint256 lastBlockHash = uint256(keccak256(block.blockhash(block.number - 1), uint8(0))) + _value;
        uint8 award = uint8(lastBlockHash % awardsCount);
        if(_from == address(this)) {
            //dont need to loop through awards
            transferAwards(_from,_to,award,_value);

        } else { // only take awards that they have
            uint left = _value;
      
      		for (uint8 i = 0; i < awardsCount; i++) {
                uint256 bal = awardBalanceOf(_from,award);
                if(bal > 0){
                    if(bal < left) {
                        transferAwards(_from,_to,award,bal);
                        left -= bal;
                    } else {
                    	transferAwards(_from,_to,award,left);
                        left = 0;
                    }
                }
                if(left == 0) break;
                award ++;
                if(award == awardsCount - 1) award = 0; // reset
            }
        }
    }
    
    function transferAwards(address from, address to, uint8 award , uint value) internal {
        //dont try to take specific awards from the contract
        if(from != address(this)) {
            require(awardBalanceOf(from,award) >= value );
            awardsOf[from][award] -= value;
        }
        //dont try to send specific awards to the contract
        if(to != address(this)) awardsOf[to][award] += value;
    }
    

    function awardBalanceOf(address addy,uint8 award) view public returns(uint){
        return awardsOf[addy][award];
    }
    
    function awardName(uint8 id) view public returns(string) {
        return awards[id];
    }
}
function transferAwards(address _from, address _to, uint _value) internal {
    uint256 lastBlockHash = uint256(keccak256(block.blockhash(block.number - 1), uint8(0))) + _value;
    uint8 award = uint8(lastBlockHash % awardsCount);
    if(_from == address(this)) {
        //dont need to loop through awards
        transferAwards(_from,_to,award,_value);

    } else { // only take awards that they have
        uint left = _value;
      
  		for (uint8 i = 0; i < awardsCount; i++) {
            uint256 bal = awardBalanceOf(_from,award);
            if(bal > 0){
                if(bal < left) {
                    transferAwards(_from,_to,award,bal);
                    left -= bal;
                } else {
                	transferAwards(_from,_to,award,left);
                    left = 0;
                }
            }
            if(left == 0) break;
            award ++;
            if(award == awardsCount - 1) award = 0; // reset
        }
    }
}

//This should only be called from the above function