contract VcgERC721TokenWithRoyalty is IVcgERC721TokenWithRoyalty,VcgERC721Token{

    struct CreatorRight{
        address creator;
        uint32 royalty;
    }
    uint256 public _scaling_factor = 100000;//5 decimals
    event CreatorChanged(uint256 indexed _id, address indexed _creator);
    event DefultRoyaltyChanged(uint256 _royalty);

    // Mapping from Token ID to Creater whith royalty rate.
    mapping(uint256 => CreatorRight) private _royaltyInfos;

    modifier creatorOnly(uint256 _tokenId) {
        require(
            _royaltyInfos[_tokenId].creator == msg.sender, 
            "MintTLToken: ONLY_CREATOR_ALLOWED"
        );
        _;
    }

    /**
    * @dev get baseTokenURI
    * @param tokenId uint256 ID of the token to query
    * @return string of TokenURI
    */
    function tokenURI(uint256 tokenId) override(IVcgERC721Token,VcgERC721Token) public view returns (string memory) {
        return super.tokenURI(tokenId);
    }

    /**
    * @dev Mints a token to an address with a tokenURI.
    * @param to address of the future owner of the token
    */
  function mintToWithRoyalty(address to,uint32 value) public onlyOwner  returns (uint256){
    require(to != address(0), 'Royalties: Invalid recipient');
    require(value == 0 ||
        (value <= _scaling_factor && value>=_scaling_factor/100), 'Royalties: Abnormal');
    uint256 newTokenId = super._getNextTokenId();
    _mint(to, newTokenId);
    CreatorRight memory cr = CreatorRight(to,value);
    _royaltyInfos[newTokenId] = cr;
    //2021-10-08  , return New TokenID
    return newTokenId;
  }

  function royaltyInfo(
        uint256 _tokenId,
        uint256 _salePrice
    ) external view override returns (
        address receiver,
        uint256 royaltyAmount
    ){
      CreatorRight memory cr = _royaltyInfos[_tokenId];
      if (cr.creator == address(0) || cr.royalty == 0){
          return (cr.creator,0);
      } 
      royaltyAmount = SafeMath.div(SafeMath.mul(_salePrice, cr.royalty),_scaling_factor);

      return (cr.creator,royaltyAmount);
  }

    function modifyRoyalty(uint256 _tokenId ,uint32 amount) external creatorOnly(_tokenId) {
        _royaltyInfos[_tokenId].royalty = amount;
    }

    function setCreator(uint256 _tokenId, address _to) public creatorOnly(_tokenId) {
        require(
            _to != address(0),
            "MintTLToken: INVALID_ADDRESS."
        );
        _royaltyInfos[_tokenId].creator = _to;
        emit CreatorChanged(_tokenId, _to);
    }

    function royaltyInfo(uint256 _tokenId) external view override returns (address receiver, uint256 amount) {
        receiver = _royaltyInfos[_tokenId].creator;
        amount = _royaltyInfos[_tokenId].royalty;
    }

    function onRoyaltiesReceived(address _royaltyRecipient, address _buyer, uint256 _tokenId, address _tokenPaid, uint256 _amount, bytes32 _metadata) external override returns (bytes4) {
        emit RoyaltiesReceived(_royaltyRecipient, _buyer, _tokenId, _tokenPaid, _amount, _metadata);    
        return bytes4(keccak256("onRoyaltiesReceived(address,address,uint256,address,uint256,bytes32)"));
    }
}
/**
 * @title VcgERC721TokenWithRoyalty
 * 
 */
function tokenURI(uint256 tokenId) override(IVcgERC721Token,VcgERC721Token) public view returns (string memory) {
    return super.tokenURI(tokenId);
}

/**
 * @dev get baseTokenURI
 * @param tokenId uint256 ID of the token to query
 * @return string of TokenURI
 */