;;blockpres.lsp
;;
;;Routine for block presentation in a file. It sorts the selected blocks in alphabetical order, and align them to a nice grid. 
;;
;; Created by Peter Gyetvai
;; gyetpet@gmail.com
;; gyetvai-peter.hu


(defun C:blockpres (/ i imax j jmax ss goodsel colnr il jl distance currSel currElem newElem currTyp currPos currName currColNr currRowNr nameList nameListOrder currOrder)
    ;variables:
    (setq i 0);counter to zero
    (setq imax 1);while variable

    (setq j 0);counter to zero
    (setq jmax 1);while variable

    (setq currColNr 0)
    (setq currRowNr 0)

    (setq nameList ())
    (setq goodsel (ssadd))
    
    (vl-load-com)
    (graphscr)

    (prompt "\nSelect blocks: [All]")
    (setq ss (ssget));asks for selection
    (setq jl (sslength ss));length of selection
    (setq distance (getdist "\nDistance between blocks? "))
    (setq colnr (getint "\nNumber of columns? "))

    ;; gets the blocks name
    (while jmax
        (print )
        (princ "Checking element ")
        (princ (1+ j))
        (princ "/")
        (princ jl)
        
        (setq currSel (ssname ss j))
        (setq currElem (entget currSel))
        (setq currName (cdr (assoc 2 currElem)))
        (setq currTyp (cdr (assoc 0 currElem)))
        (princ " - type: ")
        (princ currTyp)

        ;; checks if it's a block
        (cond
            (
                (= currTyp "INSERT");if block
                (progn 
                    (princ " - name: ")
                    (princ currName)
                    
                    (setq nameList (append nameList (list (strcase currName))))
                    ;; (print nameList)
                    (ssadd currSel goodsel)
                )
            )
            (
                (not (= currTyp "INSERT"));if not block
                (progn
                    (princ ": This is not a block")
                )
            )
        )
        ;while specific: 
        (setq j (1+ j));increments j
        (if (= j jl) (setq jmax nil));finish function if j equals jl
    )

    
    ;; sorts the block names
    (setq nameListOrder (vl-sort-i nameList '<))

    ;; length of new selection set
    (setq il (sslength goodsel))
    (print )

    ;; Modify coordinates
    (while imax
        (print )
        (princ "Moving element ")
        (princ (1+ i))
        (princ "/")
        (princ il)

        (setq currOrder (nth i nameListOrder))

        
        (setq currElem (entget (ssname goodsel currOrder) ))
        (setq currPos (assoc 10 currElem))

        (princ " - block name: ")
        (princ (cdr (assoc 2 currElem)))
        (print )

        (setq newPos (list 10 (* currColNr distance) (* currRowNr distance) 0))
        
        (setq newElem (subst newPos currPos currElem))
        (entmod newElem)

        ;; ATTSYNC
        (command "._ATTSYNC" "N" (cdr (assoc 2 currElem)))

        ;; change col and row numbers
        (setq currColNr (1+ currColNr))
        (if (= currColNr colnr)
            (progn
                (setq currRowNr (1+ currRowNr))
                (setq currColNr 0)
            )
        )

        ;while specific: 
        (setq i (1+ i));increments i
        (if (= i il) (setq imax nil));finish function if i equals il
    )

    (setq ss nil)
    (princ)
)
