;; nft-simple
;; basic v with Setzeus and Rafa following thru the badgers skies

;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;  Cons, Vars & Maps ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Define NFT
(define-non-fungible-token simple-nft uint)

;; Adhere to SIP09
(impl-trait 'SP2PABAF9FTAJYNFZH93XENAJ8FVY99RRM50D2JG9.nft-trait.nft-trait)

;; Collection limit
(define-constant collection-limit u100)

;; Root URI
(define-constant collection-root-uri "ipfs://ipfs/QmYcrELFT5c9pjSygFFXk8jfVMHB5cBoWJDGaTvrP/")

;; nft price
(define-constant simple-nft-price u10000000)

;; Collection Index
(define-data-var collection-index uint u1)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;  SIP-09 Functions ;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Get last token id
(define-read-only (get-last-token-id) 
    (ok (var-get collection-index)) ;;why is it in an ok?
)

;; Get token uri

(define-read-only (get-token-uri (id uint)) 
    (ok 
        (some (concat collection-root-uri
                (concat 
                    (uint-to-ascii id)
                    ".json")
        ))
    )
)

;; get token owner
(define-read-only (get-token-owner (id uint))
    (ok (nft-get-owner? simple-nft id))
)

;; Transfer

(define-public (transfer (id uint) (sender principal) (receiver principal)) 
    (begin
        ;; (asserts! (and (is-eq (some sender) (nft-get-owner? simple-nft id)) (is-eq sender tx-sender)) (err "u1")) 
        (asserts! (is-eq tx-sender sender) (err u1));;errors should be put as constants in capital letters
        (nft-transfer? simple-nft id sender receiver)
    )
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;  Core Functions ;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Core minting function
(define-public (mint) 
    (let 
    
        (
            (current-index (var-get collection-index))
            (next-index (+ current-index u1))
        )

        ;; assert that current index lower than collection limit
        (asserts! (< current-index collection-limit) (err "minted out"))

        ;; charge tx-sender for simple-nft
        (unwrap! (stx-transfer? simple-nft-price tx-sender (as-contract tx-sender)) (err "err stx transfer"))

        ;; Mint simple nft
        (ok (unwrap! (nft-mint? simple-nft current-index tx-sender) (err "couldn't mint")))
    )

)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;  Helper Func ;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; @param value; the unit we're casting into a string to concatenate
;; thanks to Lnow for the guidance
(define-read-only (uint-to-ascii (value uint))
  (if (<= value u9)
    (unwrap-panic (element-at "0123456789" value))
    (get r (fold uint-to-ascii-inner
      0x000000000000000000000000000000000000000000000000000000000000000000000000000000
      {v: value, r: ""}
    ))
  )
)

(define-read-only (uint-to-ascii-inner (i (buff 1)) (d {v: uint, r: (string-ascii 39)}))
  (if (> (get v d) u0)
    {
      v: (/ (get v d) u10),
      r: (unwrap-panic (as-max-len? (concat (unwrap-panic (element-at "0123456789" (mod (get v d) u10))) (get r d)) u39))
    }
    d
  )
)