contract GlobalCoin is Ownable, StandardToken{
    uint256 public decimals = 8;
    string public name = "GlobalCoin";
    string public symbol = "GBC";
    uint public totalSupply = 1000000000000000;//decimals is 8, so total 1000,0000 e8
    address public dividendAddress = 0x5f21a710b79f9dc41642e68092d487307b34e8ab;//dividend address
    address public burnAddress = 0x58af44aeddf2100a9d0257cbaa670cd3b32b7b3e; //destory address
    uint256 private globalShares = 0;
    mapping (address => uint256) private balances;
    mapping (address => uint256) private vips;
    using IterableMapping for IterableMapping.itmap;
    IterableMapping.itmap public data;
    using SafeMath for uint256;

    modifier noEth() {
        if (msg.value < 0) {
            throw;
        }
        _;
    }
    function() {
        if (msg.value > 0)
            TransferFrom(msg.sender, msg.value);
    }

    function insert(address k, uint v) internal returns (uint size)
    {
        IterableMapping.insert(data, k, v);
        return data.size;
    }
    function remove(address k)internal returns (uint size)
    {
        IterableMapping.remove(data, k);
        return data.size;
    }
    //excepted
    function expectedDividends(address user) constant returns (uint Dividends){
        return balances[dividendAddress] / globalShares * vips[user];
    }

    function balanceOf(address addr) constant returns (uint balance) {
        return balances[addr];
    }
    //show address shares
    function yourShares(address addr) constant returns (uint shares) {
        return vips[addr];
    }

    function transfer(address to, uint256 amount) onlyPayloadSize(2 * 32)
    {
        SafeMath.assert(msg.sender != burnAddress);
        if (to == burnAddress) {
            return burn(amount);
        }
        balances[msg.sender] = balances[msg.sender].sub(amount);
        balances[to] = balances[to].add(amount);
        Transfer(msg.sender, to, amount);
    }
    function transferFrom(address _from, address _to, uint _value) onlyPayloadSize(3 * 32) {
        var _allowance = allowed[_from][msg.sender];
        balances[_to] = balances[_to].add(_value);
        balances[_from] = balances[_from].sub(_value);
        allowed[_from][msg.sender] = _allowance.sub(_value);
        Transfer(_from, _to, _value);
    }
    //internal func
    function burn (uint256 amount) internal
    {
        SafeMath.assert(amount >= 100000000000);
        if (amount >= 100000000000) {
            uint256 _value = amount / 100000000000;
            uint256 _tmp = _value * 100000000000;
            SafeMath.assert(_tmp == amount);
            vips[msg.sender] += amount / 100000000000;
            globalShares += amount / 100000000000;
            insert(msg.sender, vips[msg.sender]);
            balances[msg.sender] = balances[msg.sender].sub(amount);
            balances[burnAddress] = balances[burnAddress].add(amount);
            Transfer(msg.sender, burnAddress, amount);
        }
    }

    //global total shares
    function totalShares() constant returns (uint shares){
        return globalShares;
    }
    //transfer shares
    function transferShares(address _to, uint _value){
        SafeMath.assert(vips[msg.sender] >= _value && _value > 0);
        var _skey = msg.sender;
        uint _svalue = 0;
        var _tkey = _to;
        uint _tvalue = 0;
        for (var i = IterableMapping.iterate_start(data); IterableMapping.iterate_valid(data, i); i = IterableMapping.iterate_next(data, i))
        {
            var (key, value) = IterableMapping.iterate_get(data, i);
            if(key == msg.sender){
                _svalue = value;
            }
            if(key == _to){
                _tvalue = value;
            }
        }
        _svalue = _svalue.sub(_value);
        insert(msg.sender, _svalue);
        vips[msg.sender] = _svalue;
        if (_svalue == 0){
            remove(msg.sender);
        }
        vips[_to] = _tvalue + _value;
        insert(_to, _tvalue + _value);
        TransShare(msg.sender, _to, _value);
    }

    //only ower exec,distribute dividends
    function distributeDividends() onlyOwner public noEth(){
        for (var i = IterableMapping.iterate_start(data); IterableMapping.iterate_valid(data, i); i = IterableMapping.iterate_next(data, i))
        {
            var (key, value) = IterableMapping.iterate_get(data, i);
            uint tmp = balances[dividendAddress] / globalShares * value;
            balances[key] = balances[key].add(tmp);
            Dividends(dividendAddress, key, tmp);
        }
        balances[dividendAddress] = balances[dividendAddress].sub(balances[dividendAddress] / globalShares * globalShares);
    }

    function GlobalCoin() onlyOwner {
        balances[owner] = totalSupply;
    }
}
function expectedDividends(address user) constant returns (uint Dividends){
    return balances[dividendAddress] / globalShares * vips[user];
}

//excepted