; not a bool
(defun not (x) (if x nil 1))

(defun is-pos? (n) (> n nil))
(defun is-neg? (n) (< n nil))

(defun neg (n) (- 0 n))
(defun dec (n) (- n 1))
(defun inc (n) (+ n 1))


(defun string-ltrim (str) 
    (string-rltrim str " \n\r\t" "ltrim"))
(defun string-rtrim (str) 
    (string-rltrim str " \n\r\t" "rtrim"))
(defun string-trim (str) 
    (string-rltrim str " \n\r\t" "trim"))

(defun string-rpad (str length pad_char)
    (string-pad str length pad_char "rpad"))
(defun string-lpad (str length pad_char)
    (string-pad str length pad_char "lpad"))

(defun string-upcase (str) 
    (string-case str "upper"))
(defun string-downcase (str) 
    (string-case str "lower"))


(defun string-join (lst sep)
(do
	(define rslt "")
	(define i 0)
	(for e lst
        (if (= i 0)
			(do (define rslt (display e)) (define i 1))
			(define rslt (+ rslt (display sep) (display e)))
            ))
	rslt
	))

(defun itok (ascii) (sprintf "%c" (list ascii)))
(defun ktoi (char) (int (sprintf "%d" (list char))))

; pause for interval of seconds
(defun sleep (time) 
  (system-cmd (+ "sleep " (string time))))

(defun get-env (var) 
    (second (system-cmd (+ "echo ${" var "} | tr -d \"\n\""))))


(defun second (l) (index l 1))
(defun third (l) (index l 2))
(defun fourth (l) (index l 3))
(defun fifth (l) (index l 4))
(defun nth (i l) (index l (- i 1)))

; return 1 when list contains item otherwise 0
(defun member (lst itm) 
    (do
        ; TODO check if is empty list
        (define found_index -1)
        (define i 0)
        (define lst_len (len lst))

        (while (and (< i lst_len) (= found_index -1))
            (if (= itm (index lst i))
                (define found_index i)
                (define i (+ i 1))
                ))

        ; TODO when nil will be implemented itm / nil
        (if (!= -1 found_index)
            1
            nil)
    ))

(defun make-list-of (size val)
    (do
        (define lst '())
        (define i 0)
        (while (< i size)
            (define lst (push lst val))
            (define i (inc i)))
        lst
    ))

(defun make-list (size)
    (make-list-of size nil))

(defun empty-list? (lst) (and (= (type lst) "list") (= (len lst) 0)))

(defun uniq (lst)
    (do
        (define rslt '())    
        (define i 0)
        (define lst_len (len lst))
        (while (< i lst_len)
            (define e (index lst i))
            (if (not (member rslt e)) 
                (define rslt (push rslt e)))

                (define i (inc i)))                

        rslt
    ))

(defun flatten(lst)
    (do 
        (define rslt '())
        (for e lst
            (if (= (type e) "list")
                (do 
                    (for ee (flatten e)
                        (define rslt (push rslt ee))))
                (define rslt (push rslt e))
            ))
        rslt
    ))
    
(defun quick-sort-by (l cmp)
    (if (<= (len l) 1)
        l
        (do
            (define pivot (first l))
            (+
                (quick-sort-by (filter (lambda (n) (cmp pivot n)) l) cmp)
                (list pivot)
                (quick-sort-by (tail (filter (lambda (n) (not (cmp pivot n))) l)) cmp)
            ))
    ))

(defun quick-sort (l)
    (quick-sort-by l (lambda (a b) (> a b))))

(defun quick-sort-reverse (l)
    (quick-sort-by l (lambda (a b) (> b a))))


(defun start-of-day (datetime) (str-to-date (+ (date-to-str datetime "%Y-%m-%d") " " "00:00:00") "%Y-%m-%d %H:%M:%S"))
(defun end-of-day (datetime) (str-to-date (+ (date-to-str datetime "%Y-%m-%d") " " "23:59:59") "%Y-%m-%d %H:%M:%S"))
(defun start-of-month (datetime) (str-to-date (+ (date-to-str datetime "%Y-%m") "-01 00:00:00") "%Y-%m-%d %H:%M:%S"))
(defun start-of-next-month (datetime) (date-add (start-of-month datetime) 1 "month"))
(defun end-of-next-month (datetime) (date-add (end-of-month datetime) 1 "month"))
(defun end-of-month (datetime) (date-add (date-add (start-of-month datetime) 1 "month") -1 "second"))
(defun start-of-prev-month (datetime) (date-add (start-of-month datetime) -1 "month"))
(defun end-of-prev-month (datetime) (date-add (end-of-month datetime) -1 "month"))
(defun start-of-year (datetime) (str-to-date (+ (date-to-str datetime "%Y") "-01-01 00:00:00") "%Y-%m-%d %H:%M:%S"))
(defun end-of-year (datetime) (str-to-date (+ (date-to-str datetime "%Y") "-12-31 23:59:59") "%Y-%m-%d %H:%M:%S"))


; from list of lists creates csv string
; (print (make-csv '(("r1c1" "r1c2") ("r2c1" "r2c2"))))
(defun make-csv (csv_list)
    (do
        (define rows_str "")
        (define r 0)
        (for row csv_list
            (define cols_str "")
            (define c 0)
            (for col row
                (if (= c 0)
                    (define cols_str col)
                    (define cols_str (+ cols_str "," (display col)))) 
                (define c (inc c)))
            (if (= r 0)
                (define rows_str cols_str)
                (define rows_str (+ rows_str "\n" cols_str))) 
            (define r (inc r)))

        rows_str
    ))
