contract FontcoinToken is MintableToken, PausableToken {
    string public constant version = "1.0";
    string public  name = "Fontcoin";
    string public  symbol = "FTC";//FTC
    uint8 public constant decimals = 18;

    event MintMasterTransferred(address indexed previousMaster, address indexed newMaster);
     event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value);

    modifier onlyMintMasterOrOwner() {
        require(msg.sender == mintMaster || msg.sender == owner);
        _;
    }

    /**
     * init Genesis block
    *
    */
    constructor() public {
        mintMaster = msg.sender;
        //Initial foundation data
        fundWallet=0x861c70B7E2122209D26FecF3Ed25b2C1758Cd869;
        uint256 _amount = 150000000*10**18;
        balances[fundWallet]=_amount;
        lockValues[fundWallet]=_amount;
        mintNums_ = mintNums_.add(_amount);
        //End initial foundation data
        
    }


    function transferMintMaster(address newMaster) onlyOwner public {
        require(newMaster != address(0));
        emit MintMasterTransferred(mintMaster, newMaster);
        mintMaster = newMaster;
    }

    function mintToAddresses(address[] addresses, uint256 amount) public onlyMintMasterOrOwner canMint {
        for (uint i = 0; i < addresses.length; i++) {
            require(mint(addresses[i], amount));
        }
    }

    function mintToAddressesAndAmounts(address[] addresses, uint256[] amounts) public onlyMintMasterOrOwner canMint {
        require(addresses.length == amounts.length);
        for (uint i = 0; i < addresses.length; i++) {
            require(mint(addresses[i], amounts[i]));
        }
    }
    /**
     * @dev Function to mint tokens 
     * @param _to The address that will receive the minted tokens.
     * @param _amount The amount of tokens to mint.
     * @return A boolean that indicates if the operation was successful.
     */
    function mint(address _to, uint256 _amount) onlyMintMasterOrOwner canMint public returns (bool) {

        mintNums_ = mintNums_.add(_amount);
        require(mintNums_<=totalSupply_);
        owner = msg.sender;
        bool result = super.mint(_to, _amount);
        return result;
    }
    
    
    
    function () payable public  {
        buyTokens(msg.sender);
    }

    function buyTokens(address beneficiary)  payable public returns (bool){
       require(beneficiary != 0x0,"ERC20: transfer from the zero address");
  
       uint256 weiAmount = msg.value;
       uint256 ftcTokens = weiAmount.mul(ethExchangeFtcRate);
       uint256 balnaceofpri = balances[privateWallet];
       require(balnaceofpri >= ftcTokens, "ERC20: transfer from the balnaceofpri Amount false");
       
       balances[beneficiary]=balances[beneficiary].add(ftcTokens);
       balances[privateWallet]=balances[privateWallet].sub(ftcTokens);
        emit Transfer(privateWallet, beneficiary, ftcTokens);
       
       privateWallet.transfer(msg.value);
  
       
       emit TokenPurchase(privateWallet, beneficiary, msg.value);
       
       return true;
       
       
       
       
    }

   // reset name and symbol
    function setNameSymbol(string newName, string newSymbol) public onlyMintMasterOrOwner {
        name=newName;
        symbol=newSymbol;
  }
  
 
   function addLockValues(address _to, uint256 _amount) public onlyMintMasterOrOwner{
       require(_to != address(0));
       require(_amount >=0);
       lockValues[_to]=lockValues[_to].add(_amount);
   }
    
   function releaseLockValues(address _to, uint256 _amount) public onlyMintMasterOrOwner returns (bool){
        bool ret =false;
       require(_to != address(0));
       require(_amount >=0);
       uint256 lockAmount = lockValues[_to];
       require(lockAmount>=_amount);
       lockValues[_to]=lockValues[_to].sub(_amount);
       ret=true;
       return ret;
       
   }
   /**
    *  
    *  udpate  FTC's Rate of exchange for eth
    */
   function changeEthRoFtcRate(uint256 _amount) public onlyMintMasterOrOwner returns (bool) {
         bool ret =false;
         require(_amount >=0);
         ethExchangeFtcRate = _amount;
         ret=true;
         return ret;
   }
   
    /**
    *  
    *  udpate  crowd（Private placement） address
    */
   function changePrivateWallet(address _newAddress) public onlyMintMasterOrOwner returns (bool) {
         bool ret =false;
         require(_newAddress != address(0));
         privateWallet = _newAddress;
         ret=true;
         return ret;
   }
 
   

   
   
  

}
/**
 * @dev FTC token ERC20 contract
 */
function changePrivateWallet(address _newAddress) public onlyMintMasterOrOwner returns (bool) {
      bool ret =false;
      require(_newAddress != address(0));
      privateWallet = _newAddress;
      ret=true;
      return ret;
}

/**
 *  
 *  udpate  crowd（Private placement） address
 */