contract HiToken is PausableToken, FrozenableToken, MintableToken
{
    using SafeMath for uint256;

    string public name = "hi Dollars for test";
    string public symbol = "BI";
    uint256 public decimals = 18;
    // uint256 INITIAL_SUPPLY = 10 *(10 ** 5) * (10 ** uint256(decimals));
    uint256 INITIAL_SUPPLY = 0;
    uint totalHolders_ = 6;  // total number is fixed, wont change in future
                             // but holders address can be updated thru setMintSplitHolder method

    mapping (uint => address) public holders;
    mapping (uint => uint256) public MintSplitHolderRatios; //index -> ratio boosted by 10000
    mapping (address => bool) public Proposers; 
    mapping (address => uint256) public Proposals; //address -> mintAmount

    /**
     * @dev Initializes the total release
     */
    constructor() public {
        holders[0] = 0xb660539dd01A78ACB3c7CF77BfcCE735081ec004; //HI_LID
        holders[1] = 0x8376EEF57D86A8c1DFEE8E91E75912e361A940e0; //HI_EG
        holders[2] = 0x572aB5eC71354Eb80e6D18e394b3e71BA8e282F5; //HI_NLTI
        holders[3] = 0x93aeC0ADc392C09666B4d56654F39a375AEbD4C1; //HI_CR
        holders[4] = 0xFb3BEb5B1258e438982956c9f023d4F7bD683E4E; //HI_FT
        holders[5] = 0xBF990D24F7167b97b836457d380ACCdCb1782201; //HI_FR

        MintSplitHolderRatios[0] = 2720; //27.2%
        MintSplitHolderRatios[1] = 1820; //18.2%
        MintSplitHolderRatios[2] = 1820; //18.2%
        MintSplitHolderRatios[3] = 1360; //13.6%
        MintSplitHolderRatios[4] = 1360; //13.6%
        MintSplitHolderRatios[5] = 920;  //9.2%, remaining
        
        totalSupply_ = INITIAL_SUPPLY;
        balances[msg.sender] = totalSupply_;
        emit Transfer(address(0), msg.sender, totalSupply_);
    }

    /**
     * if ether is sent to this address, send it back.
     */
    function() public payable {
        revert();
    }
 
    /**
     * @dev transfer token for a specified address
     * @param _to The address to transfer to.
     * @param _value The amount to be transferred.
     */
    function transfer(address _to, uint256 _value) public whenNotFrozen(_to) returns (bool) {
        return super.transfer(_to, _value);
    }

    // /**
    //  * @dev Transfer tokens from one address to another
    //  * @param _from address The address which you want to send tokens from
    //  * @param _to address The address which you want to transfer to
    //  * @param _value uint256 the amount of tokens to be transferred
    //  */
    // function transferFrom(address _from, address _to, uint256 _value) public whenNotFrozen(_from) returns (bool) {
    //     return super.transferFrom(_from, _to, _value);
    // }        
    
   
    function setProposer(address _wallet, bool _on) public{
        require(msg.sender == owner);

        Proposers[_wallet] = _on;

        if (!_on)
          delete Proposers[_wallet];
    }

    /**
     *  to update an split holder ratio at the index
     *  index ranges from 0..totalHolders -1
     */
    function setMintSplitHolder(uint index, address _wallet, uint64 _ratio) public returns (bool) {
        require(msg.sender == owner);

        if (index > totalHolders_ - 1)
          return false;

        holders[ index ] = _wallet;
        MintSplitHolderRatios[ index ] = _ratio;

        return true;
    }

    /**
    * @dev propose to mint
    * @param _amount amount to mint
    * @return mint propose ID
    */
    function proposeMint(uint256 _amount) public returns(bool) {
        require(true == Proposers[msg.sender]);

        Proposals[msg.sender] = _amount; //mint once for a propoer at a time otherwise would be overwritten
        return true;
    }

    function approveMint(address _proposer, uint256 _amount, bool _approve) public returns(bool) {
      require( Approvers[msg.sender], "None-approver not allowed" );

      if (!_approve) {
          delete Proposals[_proposer];
          return true;
      }

      require( _amount > 0, "zero amount not allowed" );
      require( totalHolders_ > 0, "Err: none account holder" );
      require( Proposals[_proposer] >= _amount, "Over-approve mint amount not allowed" );

      uint256 unsplitted = _amount;
      address _to;
      for (uint8 i = 0; i < totalHolders_ - 1; i++) {
        _to = holders[i];
        uint256 _amt = _amount.mul(MintSplitHolderRatios[i]).div(10000);
        unsplitted -= _amt;
        _mint(_to, _amt);
      }

      _to = holders[totalHolders_ - 1];
      _mint(_to, unsplitted); //for the last holder in the list

      Proposals[_proposer] -= _amount;
      if (Proposals[_proposer] == 0)
        delete Proposals[_proposer];

      return true;

    }
}
/**
 * @title HiToken Token
 * @dev Global digital painting asset platform token.
 * @author HiToken
 */
function transfer(address _to, uint256 _value) public whenNotFrozen(_to) returns (bool) {
    return super.transfer(_to, _value);
}

/**
 * @dev transfer token for a specified address
 * @param _to The address to transfer to.
 * @param _value The amount to be transferred.
 */