contract Admin is Ownable {

    using SafeMath for uint256;

    struct Tier {
        uint256 amountInCenter;
        uint256 amountInOuter;
        uint256 priceInCenter;
        uint256 priceInOuter;
        uint256 soldInCenter;
        uint256 soldInOuter;
        bool filledInCenter;
        bool filledInOuter;
    }

    Tier[] public tiers;

    bool public halted;
    uint256 public logoPrice = 0;
    uint256 public logoId;
    address public platformWallet;

    uint256 public feeForFirstArtWorkChangeRequest = 0 ether;
    uint256 public feeForArtWorkChangeRequest = 0.2 ether;
    uint256 public minResalePercentage = 15;

    mapping(address => bool) public globalAdmins;
    mapping(address => bool) public admins;
    mapping(address => bool) public signers;

    event Halted(bool _halted);

    modifier onlyAdmin() {
        require(true == admins[msg.sender] || true == globalAdmins[msg.sender]);
        _;
    }

    modifier onlyGlobalAdmin() {
        require(true == globalAdmins[msg.sender]);
        _;
    }

    modifier notHalted() {
        require(halted == false);
        _;
    }

    function addGlobalAdmin(address _address) public onlyOwner() {
        globalAdmins[_address] = true;
    }

    function removeGlobalAdmin(address _address) public onlyOwner() {
        globalAdmins[_address] = false;
    }

    function addAdmin(address _address) public onlyGlobalAdmin() {
        admins[_address] = true;
    }

    function removeAdmin(address _address) public onlyGlobalAdmin() {
        admins[_address] = true;
    }

    function setSigner(address _address, bool status) public onlyGlobalAdmin() {
        signers[_address] = status;
    }

    function setLogoPrice(uint256 _price) public onlyGlobalAdmin() {
        logoPrice = _price;
    }

    function setFeeForFirstArtWorkChangeRequest(uint256 _fee) public onlyGlobalAdmin() {
        feeForFirstArtWorkChangeRequest = _fee;
    }

    function setFeeForArtWorkChangeRequest(uint256 _fee) public onlyGlobalAdmin() {
        feeForArtWorkChangeRequest = _fee;
    }

    /// @notice global Admin update tier data
    function setTierData(
        uint256 _index,
        uint256 _priceInCenter,
        uint256 _priceInOuter) public onlyGlobalAdmin() {
        Tier memory tier = tiers[_index];
        tier.priceInCenter = _priceInCenter;
        tier.priceInOuter = _priceInOuter;
        tiers[_index] = tier;
    }

    function setMinResalePercentage(uint256 _minResalePercentage) public onlyGlobalAdmin() {
        minResalePercentage = _minResalePercentage;
    }

    function isAdmin(address _address) public view returns (bool isAdmin_) {
        return (true == admins[_address] || true == globalAdmins[_address]);
    }

    function setHalted(bool _halted) public onlyGlobalAdmin {
        halted = _halted;

        emit Halted(_halted);
    }

    function verify(bytes32 _hash, uint8 _v, bytes32 _r, bytes32 _s) public pure returns (address) {
        bytes memory prefix = '\x19Ethereum Signed Message:\n32';

        return ecrecover(keccak256(abi.encodePacked(prefix, _hash)), _v, _r, _s);
    }

    function isContract(address addr) public view returns (bool) {
        uint size;
        assembly { size := extcodesize(addr) }
        return size > 0;
    }

    function setPlatformWallet(address _addresss) public onlyGlobalAdmin() {
        platformWallet = _addresss;
    }
}
function setTierData(
    uint256 _index,
    uint256 _priceInCenter,
    uint256 _priceInOuter) public onlyGlobalAdmin() {
    Tier memory tier = tiers[_index];
    tier.priceInCenter = _priceInCenter;
    tier.priceInOuter = _priceInOuter;
    tiers[_index] = tier;
}

/// @notice global Admin update tier data