// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

/*
                  ////////////////////////////////////                                                          
                 ///////////////////////////////////////                                                        
                 //#&&&//////////////////&&&///////////////                                                     
              &&&&&&&&&/////////////////&&&&&&&&&&%///////////                                                  
            &&&&////////////////////////////////&&&&&&//////////                                                
              .           //////////////         /////&&///////////                                             
                     &&&    //////////   &&&        ///////////////                                             
                   &&&&&&    ////////   &&&&&&       //////////////                                             
           /        &&&&    /////////    &&&&        //////////////                                             
         ////           &&&&&&&&&&&&&&//             //////////////                                             
         //////////////&&&&&&&&&&&&&&&&/////////////////////////////                                            
         /////////////&&&@@@&&&&&&@@@&&&&///////////////////////////                                            
         ////////&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&////////////////////                                            
         ////&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/////////////                                            
         &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&%//////                                            
          &&&&&&&&&&&&&&&&&&&///&&&&&&&&&&&&&&&&&&&&&&&&&&&/////////                                            
             ///&&&&&  ///////////////&&&&&&&&&&&&&&&&&&////////////                                            
              ///      //////////////////       ////////////////////                                            
             ////      //////////////////       ////////////////////                                            
             ////     ////////////////////      ////////////////////                                            
            /////.    ////////////////////      ////////////////////                                            
            //////   //////////////////////     ////////////////////                                            
           ///////   //////////////////////     ////////////////////                                            
          ////////   ///////////////////////    ////////////////////                                            
          ////////  ////////////////////////   /////////////////////                                            
         /////////  /////////////////////////  //////////////////////                                           
         ///////// ////////////////////////// ////////////////////////                                         
        ////////////////////////////////////////////////////////////////                                        
        //////////////////////////////////////////////////////////////////                                      
       /////////////////////////////////////////////////////////////////////                                    
       ///////////////////////////////////////////////////////////////////////                                  
       ////////////////////////////////////////////////////////////////////////                                 
      ///////////////////////////////////////////////////////////////////////////                               
      /////////////////////////////////////////////////////////////////////////////                             
     ///////////////////////////////////////////////////////////////////////////////                            
     /////////////////////////////////////////////////////////////////////////////////                          
     ///////////////////////////////////////////////////////////////////////////////////                        
    //////////////////////////////////////////////////////////////////////////////////////                      
    ///////////////////////////////////////////////////////////////////////////////////////
*/

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract TheAcidWalrus is ERC721URIStorage, Ownable {
  using Counters for Counters.Counter;
  using SafeMath for uint256;

  uint public constant MAX_SUPPLY = 10000;
  uint public constant NUMBER_RESERVED_WALRUS = 100;
  uint public constant MAX_WALRUS_PRE_SALE = 1000;

  uint256 public PRICE = 0.123 ether;

  bool public preSaleIsActive = false;
  bool public saleIsActive = false;

  Counters.Counter public mintedWalrus;
  uint public reservedWalrusMinted = 0;

  string public baseURI;

  constructor () ERC721("The Acid Walrus", "TAW") {
    mintedWalrus.increment(); // Making sure we start at token ID 1
  }

  function mintWalrus(uint256 amount) external payable {
    require(msg.sender == tx.origin, "No transaction from smart contracts!");
    require(saleIsActive, "Sale must be active to mint");
    require(amount > 0 && amount <= 15, "Max 15 NFTs per transaction");
    require(mintedWalrus.current() + amount <= MAX_SUPPLY, "Max Supply Reached");
    require(msg.value >= PRICE * amount, "Not enough ETH for transaction");

    for (uint i = 0; i < amount; i++) {
      _safeMint(msg.sender, mintedWalrus.current());
      mintedWalrus.increment();
    }
  }

  function mintPreSaleWalrus(uint256 amount) external payable {
    require(msg.sender == tx.origin, "No transaction from smart contracts!");
    require(preSaleIsActive, "Pre-sale must be active to mint");
    require(amount > 0 && amount <= 15, "Max 15 NFTs per transaction");
    require(mintedWalrus.current() + amount <= MAX_WALRUS_PRE_SALE - (NUMBER_RESERVED_WALRUS - reservedWalrusMinted), "Purchase would exceed max supply");
    require(msg.value >= PRICE * amount, "Not enough ETH for transaction");

    for (uint i = 0; i < amount; i++) {
      _safeMint(msg.sender, mintedWalrus.current());
      mintedWalrus.increment();
    }
  }

  function mintReservedWalrus(address to, uint256 amount) external onlyOwner {
    require(reservedWalrusMinted + amount <= NUMBER_RESERVED_WALRUS, "This amount is more than max allowed");

    for (uint i = 0; i < amount; i++) {
      _safeMint(to, mintedWalrus.current());
      mintedWalrus.increment();
      reservedWalrusMinted++;
    }
  }

  function changeSaleState() external onlyOwner {
    saleIsActive = !saleIsActive;
  }

  function changePreSaleState() external onlyOwner {
    preSaleIsActive = !preSaleIsActive;
  }

  function withdraw() external onlyOwner {
    address t1 = 0x6607AaA027413a9ccD7f244340A87Ba7b5e7dbAd;
    address t2 = 0x36585EA020d8B39a6FE75c81e74Fe9cc38599A3C;

    uint256 _balance = address(this).balance;
    uint256 _split = _balance.mul(50).div(100);

    require(payable(t2).send(_split));
    require(payable(t1).send(_balance.sub(_split)));
  }

  function setPrice(uint256 newPrice) external onlyOwner {
    PRICE = newPrice;
  }

  function setBaseURI(string memory uri) public onlyOwner {
    baseURI = uri;
  }

  function _baseURI() internal view override returns (string memory) {
    return baseURI;
  }
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_WALRUS_PRE_SALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NUMBER_RESERVED_WALRUS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"changePreSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"changeSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintPreSaleWalrus","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintReservedWalrus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintWalrus","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintedWalrus","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preSaleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservedWalrusMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]