;Libreria per la gestione dei blocchi
;
;Versione : 0.1
;Autore : Roberto Rossi
;Web : http://www.redchar.net
;
;Questa libreria consente di trattare i blocchi e gli attributi in essi contenuti
;
;TODO : Funzionalitą da implementare
;       - Inserimento blocchi
;       - Selezione blocchi in base a caratteristiche o attributi (nomi e/o contenuti)
;       - Lettura valore attributo in base a nome
;       - Lettura elenco nomi attributi contenuti
;       - Lettura entitą attributo dato nome o indice
;       - Lettura numero attributi (blk_getAttCount)
;       - Lettura lista entitą attributo contenute in blocco (blk_getAttList)
;       - Scrittura valore attributo in base a nome o posizione
;       - 
;       - 

;ritorna la lista con i nomi delle entitą relative a tutti gli attributi trovati
;partendo dall'entitą blocco inserito
(defun blk_getAttList ( blEnt / ent sixsix att attList blk)
(setq blk (entget blEnt))
(setq ent blEnt)
(setq sixsix (cdr(assoc 66 blk)))
  (if (= sixsix 1)
    (progn ;ci sono attributi
      (setq ent (entnext ent));primo attributo
      (setq att (entget ent))
      (while (/= (cdr(assoc 0 att)) "SEQEND")
        (setq attList (cons (cdr (assoc -1 att)) attList))
        (setq ent (entnext ent));primo attributo
        (setq att (entget ent))
      )
      (setq attList (reverse attList))
    );endp
  );endif
attList
);enddef

;ritorna il numero di attributi contenuto in un blocco inserito
(defun blk_getAttCount ( blEnt / attLst attCount)
  (if blEnt
    (progn
      (setq attCount 0)
      (setq attLst (blk_getAttList blEnt))
      (if attLst
        (setq attCount (length attLst))
      )
    );endp
  );endif
attCount
);enddef

;ritorna l'entitą attributo che corrisponde al nome specificato o indice
(defun blk_getAttEName ( blEnt attName / ent entDef att i name continue result
                                         selectByIndex)
  (if blEnt
    (progn
      (setq attLst (blk_getAttList blEnt))
      (if attLst
        (progn
          
          (if (= (type attName) 'STR)
            (progn
              (setq selectByIndex nil)
            )
            (progn
              (if (= (type attName) 'INT)
                (setq selectByIndex t)
                (progn
                  (print "blk_getAttEName : Require integer value!")
                  (exit)
                )
              );endif
            )
          )
        
          (if selectByIndex
            (progn ;selezione attributo per indice (da 0 a n-1)
              (setq result (nth attName attLst))
            )
            (progn ;selezione per nome attributo
              (setq i 0)
              (setq continue t)
              (while (and (setq att (nth i attLst)) continue)
                (setq name (strcase (cdr (assoc 2 (entget att)))))
                (if (= (strcase attName) name)
                  (progn
                    (setq result (nth i attLst))
                    (setq continue nil)
                  )
                );endif
                (setq i (1+ i))
              );endw            
            );endp
          );endif

        );endp
      );endif
    );endp
  );endif
result
);enddef

;ritorna il valore associato ad un attributo in base al suo nome o tramite indice
(defun blk_getAttValue ( blEnt attName / ent result)
  (if blEnt
    (progn
      (setq ent (blk_getAttEName blEnt attName))
      (if ent
        (setq result (cdr (assoc 1 (entget ent))))
      );endif      
    );endp
  );endif
result
);enddef

;ritorna il valore associato ad un attributo in base al suo nome o usando un indice
(defun blk_setAttValue ( blEnt attName attValue / ent def oldValue newValue result)
  (if blEnt
    (progn
      (setq ent (blk_getAttEName blEnt attName))
      (if ent
        (progn
          (setq def (entget ent))
          (setq oldValue (assoc 1 def))
          (setq newValue (cons 1 attValue))
          (setq def (subst newValue oldValue def))
          (entmod def)
          (entupd ent)
          (setq result t)
        );endp
      );endif      
    );endp
  );endif
result
);enddef

;stampa la definzione di un blocco
(defun printBlockDef ( nameBl / ent defent nextOk)
(setq ent (tblsearch "BLOCK" nameBl))
    (if ent
        (progn
            (princ "\nDefinizione blocco \"")
            (princ nameBl)
            (princ "\"")
            (setq nextOk t)
            (setq ent (cdr (assoc -2 ent)))
            (setq defent (entget ent))
            (print defent)
            (while nextOk
                (setq ent (entnext ent))            
                (if ent
                    (setq defent (entget ent))
                    (setq nextOk nil)
                )
                (print defent)
            )
        )
    )
(prin1)
)

;stampa tutta l'entitą INSERT indicata
;partendo dall'entitą INSERT
(defun blk_printInsertEntity ( blEnt / ent sixsix att blk)
(setq blk (entget blEnt))
(print blk)
(setq ent blEnt)
(setq sixsix (cdr(assoc 66 blk)))
  (if (= sixsix 1)
    (progn ;ci sono attributi
      (setq ent (entnext ent));primo attributo
      (setq att (entget ent))
      (print att)
      (while (/= (cdr(assoc 0 att)) "SEQEND")
        (setq ent (entnext ent));primo attributo
        (setq att (entget ent))
        (print att)
      )
    );endp
  );endif
(prin1)
);enddef


;inserisce il blocco e lo compila con le coordinate
(defun blk_drawPoint ( pointBase pointBlock / blkName pt val)

nil
)

;nuovo comando per inserimento blocco con punto
(defun c:blkInsPoint ( / pt pt2 ptBlk 
                        atq eBlk entBlk 
                        x y xStr yStr 
                        ang)

    (setq atq (getvar "ATTREQ"))
    (setvar "ATTREQ" 0)
    (setq pt (getpoint "\nSpecifica il punto da cui leggere le coordinate:"))
    (if pt
        (progn
            (setq ptBlk (getpoint pt "\nSpecifica il punto dove inserire i dati letti:"))
            (if ptBlk
                (progn
                    (command "_insert" "blk-point-signal" ptBlk "" "" "")
                    (setq eBlk (entlast))
                    (setq entBlk (entget eBlk))
                    (setq x (car pt))
                    (setq y (cadr pt))
                    (blk_setAttValue eBlk "X" (rtos x))
                    (blk_setAttValue eBlk "Y" (rtos y))
                    
                    (setq ang (angle pt ptBlk))
                    (setq pt2 (polar ptBlk ang -10))
                    (command "_line" pt pt2 "")
                )
            )
        )
    )
    (setvar "ATTREQ" atq)
    (prin1)
)

