contract SkidCars is ERC721Pausable, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    uint256 private constant _maxTokens = 604;
    uint256 private constant _maxMint = 1;
    
    address public _skidsContract = 0xCC4916b9a04D0AeC7A54279fce6A72251B3083e7; 

    uint256 public constant _price = 0; // FREE

    mapping (address => uint256) private _saleMints;

    bool private _saleActive = false;
    
    string public _prefixURI;

    constructor() public ERC721("SkidCars", "SKIDCAR") {
        _pause();
    }

    function _baseURI() internal view override returns (string memory) {
        return _prefixURI;
    }

    function setBaseURI(string memory _uri) public onlyOwner {
        _prefixURI = _uri;
    }

    function totalSupply() public view returns (uint256) {
        return _tokenIds.current();
    }

    function saleActive() public view returns (bool) {
        return _saleActive; 
    }

    function saleMinted(address addr) public view returns (uint256) {
        return _saleMints[addr]; 
    }

    function mintItems(uint256 amount, uint256 skidTokenID) public payable {
        // require that you own atleast one skid by checking the submitted token (this will be handled automatically in the web application) 
        IERC721 instance = IERC721(_skidsContract); 
        require(instance.ownerOf(skidTokenID) == msg.sender); 
        require(amount <= _maxMint);
        require(_saleActive);
        require(amount <= _maxMint); 
        uint256 totalMinted = _tokenIds.current();
        require(totalMinted + amount <= _maxTokens);
        require(_saleMints[msg.sender] + amount <= _maxMint); 
        for (uint256 i = 0; i < amount; i++) {
            _saleMints[msg.sender] += 1; 
            _mintItem(msg.sender);
        }
    }

    function _mintItem(address to) internal returns (uint256) {
        _tokenIds.increment();
        uint256 id = _tokenIds.current();
        _safeMint(to, id);
        return id;
    }


    function toggleSale() public onlyOwner {
        _saleActive = !_saleActive;
    }

    function toggleTransferPause() public onlyOwner {
        paused() ? _unpause() : _pause();
    }

    function reserve(uint256 quantity) public onlyOwner {
        for(uint i = _tokenIds.current(); i < quantity; i++) {
            if (i < _maxTokens) {
                _tokenIds.increment();
                _safeMint(msg.sender, i + 1);
            }
        }
    }


    // Allows minting(transfer from 0 address), but not transferring while paused() except from owner
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        if (!(from == address(0)) && !(from == owner())) {
            require(!paused(), "ERC721Pausable: token transfer while paused");
        }
    }
}
/* 
 
 dddddddd                 
 kkkkkkkk             iiii              d::::::d                 
 k::::::k            i::::i             d::::::d                 
 k::::::k             iiii              d::::::d                 
 k::::::k                               d:::::d                  
 ssssssssss    k:::::k    kkkkkkkiiiiiii     ddddddddd:::::d     ssssssssss   
 ss::::::::::s   k:::::k   k:::::k i:::::i   dd::::::::::::::d   ss::::::::::s  
 ss:::::::::::::s  k:::::k  k:::::k   i::::i  d::::::::::::::::d ss:::::::::::::s 
 s::::::ssss:::::s k:::::k k:::::k    i::::i d:::::::ddddd:::::d s::::::ssss:::::s
 s:::::s  ssssss  k::::::k:::::k     i::::i d::::::d    d:::::d  s:::::s  ssssss 
 s::::::s       k:::::::::::k      i::::i d:::::d     d:::::d    s::::::s      
 s::::::s    k:::::::::::k      i::::i d:::::d     d:::::d       s::::::s   
 ssssss   s:::::s  k::::::k:::::k     i::::i d:::::d     d:::::d ssssss   s:::::s 
 s:::::ssss::::::sk::::::k k:::::k   i::::::id::::::ddddd::::::dds:::::ssss::::::s
 s::::::::::::::s k::::::k  k:::::k  i::::::i d:::::::::::::::::ds::::::::::::::s 
 s:::::::::::ss  k::::::k   k:::::k i::::::i  d:::::::::ddd::::d s:::::::::::ss  
 sssssssssss    kkkkkkkk    kkkkkkkiiiiiiii   ddddddddd   ddddd  sssssssssss    
 
 
 ░█████╗░░█████╗░██████╗░░██████╗
 ██╔══██╗██╔══██╗██╔══██╗██╔════╝
 ██║░░╚═╝███████║██████╔╝╚█████╗░
 ██║░░██╗██╔══██║██╔══██╗░╚═══██╗
 ╚█████╔╝██║░░██║██║░░██║██████╔╝
 ░╚════╝░╚═╝░░╚═╝╚═╝░░╚═╝╚═════╝░
 
 13% drop (exclusive to current holders)
 
 Website: https://skids.io
 Discord: https://discord.gg/skidsNFT 
 Twitter: https://twitter.com/SkidsNFT
 
 */
function _beforeTokenTransfer(
    address from,
    address to,
    uint256 tokenId
) internal virtual override {
    if (!(from == address(0)) && !(from == owner())) {
        require(!paused(), "ERC721Pausable: token transfer while paused");
    }
}

// Allows minting(transfer from 0 address), but not transferring while paused() except from owner