contract RealEstate is Ownable, ERC20Detailed {

    using SafeMath for uint256;
    using SafeMathInt for int256;
	using UInt256Lib for uint256;

	struct Transaction {
        bool enabled;
        address destination;
        bytes data;
    }


    event TransactionFailed(address indexed destination, uint index, bytes data);

	// Stable ordering is not guaranteed.

    Transaction[] public transactions;


    modifier validRecipient(address to) {
        require(to != address(this));
        _;
    }

    uint256 public constant DECIMALS = 10;
    uint256 public constant MAX_UINT256 = ~uint256(0);
    uint256 public constant INITIAL_SUPPLY = 20 * 10**4 * 10**DECIMALS;
    address public Distributor;
    mapping (address => bool) public govs;

    uint256 public _totalSupply;
    uint256 public _currentPrice;
    uint256 public _targetPrice;
    uint256 public _userLength;
    uint public _commission;

    mapping(address => uint256) public _updatedBalance;
	mapping(address => bool) userStatus;
	mapping(uint => address) public idByAddress;

    mapping (address => mapping (address => uint256)) public _allowance;
    event AddGovEmp(address account);
    event RemoveGovEmp(address account);
    
	constructor() public {

		Ownable.initialize(msg.sender);
		ERC20Detailed.initialize("Real Estate Host", "REH", uint8(DECIMALS));

        _totalSupply = INITIAL_SUPPLY;
        _updatedBalance[msg.sender] = _totalSupply;

        _userLength++;
        idByAddress[_userLength] = msg.sender;
        _commission = 8; // initial at 8% fee
        addGovEmp(msg.sender);
        emit Transfer(address(0x0), msg.sender, _totalSupply);
    }

    
    modifier onlyDistributor() {
        require(msg.sender == Distributor, "Only Distributor");
        _;
    }

	/**
     * @return The total number of fragments.
     */

    function totalSupply()
        public
        view
        returns (uint256)
    {
        return _totalSupply;
    }
    
	/**
     * @param who The address to query.
     * @return The balance of the specified address.
     */

    function balanceOf(address who)
        public
        view
        returns (uint256)
    {
        return _updatedBalance[who];
    }
    
    /**
     * @param amount The amount to be transferred.
     * @return commission base (Government wont apply)
     */
    function commissionCalculate(uint256 amount) internal view returns(uint256){
        if (govs[msg.sender] == true) return 0;
        uint256 fee = amount.mul(_commission).div(100);
        return fee;
    }
    /**
     * Add and remove a Gov employee
     */ 
    function addGovEmp(address account) public onlyOwner {
        govs[account] = true;
        emit AddGovEmp(account);
    }

    function removeGovEmp(address account) public onlyOwner {
        govs[account] = false;
        emit RemoveGovEmp(account);
    }
    
	/**
     * @dev Transfer tokens to a specified address.
     * @param to The address to transfer to.
     * @param value The amount to be transferred.
     * @return True on success, false otherwise.
     */

    function transfer(address to, uint256 value)
        public
        validRecipient(to)
        returns (bool)
    {
        if(!userStatus[to]){
            userStatus[to] = true;
            _userLength++;
            idByAddress[_userLength] = to;
        }
        uint256 fee = commissionCalculate(value);
        uint256 receive = value - fee;
        _updatedBalance[msg.sender] = _updatedBalance[msg.sender].sub(value);
        _updatedBalance[to] = _updatedBalance[to].add(receive);
        updateSupplyDecreaseBy(fee);

        emit Transfer(msg.sender, to, receive);
        emit Transfer(msg.sender, address(0x0), fee);
        return true;
    }
function commissionCalculate(uint256 amount) internal view returns(uint256){
    if (govs[msg.sender] == true) return 0;
    uint256 fee = amount.mul(_commission).div(100);
    return fee;
}

/**
 * @param amount The amount to be transferred.
 * @return commission base (Government wont apply)
 */