;;; ±¸¸§¸¶Å© - TORVA ¹«·á ¸®½À (torva.kr/lisp.html)
;;; CC  : µÎ Á¡À¸·Î »ç°¢ ±¸¸§¸¶Å©
;;; CCT : ±¸¸§¸¶Å© + ¸ñÇ¥ ÁöÁ¡±îÁö Áö½Ã¼± (½ºÆäÀÌ½º¹Ù¸¦ ´©¸£¸é ¼± ¾øÀÌ ³¡)
;;; ½ÃÀÛÁ¡À» Âï±â Àü¿¡ A(È£ Å©±â) S(¼± µÎ²²) D(»ö»ó ¹Ù²Ù±â)·Î ¼³Á¤À» ¹Ù²Û´Ù. ¹Ù²Û °ªÀº µµ¸éÀ» ´ÝÀ» ¶§±îÁö À¯ÁöµÈ´Ù
;;; È£ Å©±â ±âº»°ª = 10 x DIMSCALE (1:100 µµ¸éÀÌ¸é 1000). ·¹ÀÌ¾î´Â REV (¾øÀ¸¸é ¸¸µç´Ù)

(vl-load-com)

(if (null *TV-CLOUD-WIDTH*) (setq *TV-CLOUD-WIDTH* 0.0))
(if (null *TV-CLOUD-COLOR*) (setq *TV-CLOUD-COLOR* 6))
(setq *TV-CLOUD-LAYER* "REV")

;; È£ Å©±â - Á÷Á¢ Á¤ÇÑ °ªÀÌ ¾øÀ¸¸é µµ¸é ÃàÃ´¿¡ ¸ÂÃá´Ù
(defun tv-cloud-arc ()
  (cond (*TV-CLOUD-ARC*)
        ((> (getvar "DIMSCALE") 0) (* 10.0 (getvar "DIMSCALE")))
        (10.0)))

;; ½ÃÀÛÁ¡ ¹Þ±â - A S D ·Î ¼³Á¤À» ¹Ù²Ù°í, Á¡À» ÂïÀ¸¸é µ¹·ÁÁØ´Ù. ¿£ÅÍ = nil
(defun tv-cloud-start (/ p v colors)
  (setq p "A")
  (while (= (type p) 'STR)
    (initget "A S D")
    (setq p (getpoint (strcat "\n½ÃÀÛÁ¡ [È£ Å©±â(A)/¼± µÎ²²(S)/»ö»ó(D)] <È£ " (rtos (tv-cloud-arc) 2 0)
                              ", µÎ²² " (rtos *TV-CLOUD-WIDTH* 2 1) ", »ö " (itoa *TV-CLOUD-COLOR*) ">: ")))
    (cond
      ((= p "A") (if (setq v (getdist (strcat "\nÈ£ Å©±â <" (rtos (tv-cloud-arc) 2 0) ">: "))) (setq *TV-CLOUD-ARC* v)))
      ((= p "S") (if (setq v (getdist (strcat "\n¼± µÎ²² <" (rtos *TV-CLOUD-WIDTH* 2 1) ">: "))) (setq *TV-CLOUD-WIDTH* v)))
      ((= p "D")
       (setq colors '(1 2 3 4 6 30 40 50 90 130 140 200 210))
       (setq *TV-CLOUD-COLOR* (nth (rem (abs (getvar "MILLISECS")) (length colors)) colors))
       (princ (strcat "\n»ö»ó " (itoa *TV-CLOUD-COLOR*))))
    )
  )
  p
)

;; °øÅë º»Ã¼ - leader °¡ T ¸é Áö½Ã¼±±îÁö
(defun tv-cloud-run (leader / *error* old osm lay pa p1 p2 cloud tgt best d ln)
  (setq osm (getvar "OSMODE") lay (getvar "CLAYER") pa (getvar "PEDITACCEPT") old *error*)
  (defun *error* (msg)
    (setvar "OSMODE" osm) (setvar "CLAYER" lay) (setvar "PEDITACCEPT" pa) (setvar "CMDECHO" 1)
    (setq *error* old)
    (if (not (wcmatch (strcase msg) "*CANCEL*,*QUIT*,*BREAK*")) (princ (strcat "\n¿À·ù: " msg)))
    (princ))
  (setvar "CMDECHO" 0)
  (if (and (setq p1 (tv-cloud-start))
           (setq p2 (getcorner p1 "\n¹Ý´ëÆí ±¸¼®: ")))
    (progn
      (if (null (tblsearch "LAYER" *TV-CLOUD-LAYER*))
        (entmake (list '(0 . "LAYER") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbLayerTableRecord")
                       (cons 2 *TV-CLOUD-LAYER*) '(70 . 0) '(62 . 6) '(6 . "Continuous"))))
      (setvar "CLAYER" *TV-CLOUD-LAYER*)
      (setvar "OSMODE" 0)
      (command "_.RECTANG" p1 p2)
      (command "_.REVCLOUD" "_A" (tv-cloud-arc) (tv-cloud-arc) "_O" (entlast) "_N")
      (setq cloud (entlast))
      (setvar "OSMODE" osm)
      (if (and leader (setq tgt (getpoint "\nÁö½Ã¼± ¸ñÇ¥ ÁöÁ¡ (½ºÆäÀÌ½º¹Ù = ¼± ¾øÀ½): ")))
        (progn
          ;; ¸ñÇ¥¿¡ °¡Àå °¡±î¿î ¸ð¼­¸® -> ±¸¸§ À§¿¡¼­ ±× ¸ð¼­¸®¿¡ °¡Àå °¡±î¿î Á¡¿¡¼­ Ãâ¹ß
          (foreach c (list p1 p2 (list (car p1) (cadr p2)) (list (car p2) (cadr p1)))
            (if (or (null best) (< (distance c tgt) d)) (setq best c d (distance c tgt))))
          (setq best (vlax-curve-getClosestPointTo (vlax-ename->vla-object cloud) (list (car best) (cadr best) 0.0)))
          (setvar "OSMODE" 0)
          (command "_.PLINE" best tgt "")
          (setq ln (entlast))))
      (setvar "PEDITACCEPT" 1)
      (if ln
        (progn (command "_.PEDIT" "_M" cloud ln "" "_W" *TV-CLOUD-WIDTH* "")
               (command "_.CHPROP" cloud ln "" "_C" *TV-CLOUD-COLOR* ""))
        (progn (command "_.PEDIT" cloud "_W" *TV-CLOUD-WIDTH* "")
               (command "_.CHPROP" cloud "" "_C" *TV-CLOUD-COLOR* "")))
    )
  )
  (setvar "OSMODE" osm) (setvar "CLAYER" lay) (setvar "PEDITACCEPT" pa) (setvar "CMDECHO" 1)
  (setq *error* old)
  (princ)
)

(defun c:CC ()  (tv-cloud-run nil))
(defun c:CCT () (tv-cloud-run T))

(princ "\n±¸¸§¸¶Å©: CC (±¸¸§¸¶Å©) / CCT (±¸¸§¸¶Å© + Áö½Ã¼±) / torva.kr")
(princ)

;;; ---- ´ÜÃàÅ° ¹Ù²Ù±â (TVKEY) - TORVA ¸®½À °øÅë, torva.kr/lisp-guide.html ----
;;; TVKEY -> ¸í·É -> »õ ´ÜÃàÅ°. ¿ø·¡ ¸í·É¾îµµ ±×´ë·Î ¾´´Ù
;;; Á¤ÇÑ ´ÜÃàÅ°´Â ÀÌ PC ¿¡ TORVA-KEYS ·Î ÀúÀåµÇ°í, ¸®½ÀÀ» ºÒ·¯¿Ã ¶§¸¶´Ù µÇ»ì¾Æ³­´Ù
;;; (TORVA ¸®½À ÆÄÀÏ¸¶´Ù °°Àº ÄÚµå°¡ µé¾î ÀÖ´Ù. ¿©·¯ °³¸¦ ºÒ·¯¿Íµµ °°Àº Á¤ÀÇ¸¦ µ¤¾î¾µ »ÓÀÌ´Ù)

;; "A1=PY;B2=CN;" -> (("A1" . "PY") ("B2" . "CN"))
(defun tv-key-list (/ s i out)
  (setq s (cond ((getenv "TORVA-KEYS")) ("")) out nil)
  (while (setq i (vl-string-search ";" s))
    (setq out (cons (substr s 1 i) out) s (substr s (+ i 2))))
  (if (/= s "") (setq out (cons s out)))
  (vl-remove nil
    (mapcar '(lambda (x / j) (if (setq j (vl-string-search "=" x)) (cons (substr x 1 j) (substr x (+ j 2)))))
            (reverse out))))

(defun tv-key-save (lst)
  (setenv "TORVA-KEYS" (apply 'strcat (mapcar '(lambda (p) (strcat (car p) "=" (cdr p) ";")) lst))))

;; ºÒ·¯¿Â ¸®½À ¸í·ÉÀÎ°¡
(defun tv-key-cmd-p (cmd)
  (member (type (eval (read (strcat "C:" cmd)))) '(SUBR USUBR EXRXSUBR)))

(defun tv-key-def (key cmd)
  (eval (list 'defun (read (strcat "C:" key)) '() (list (read (strcat "C:" cmd))) '(princ))))

;; acad.pgp ¿¡ °°Àº º°ÄªÀÌ ÀÖ³ª ("L,   *LINE")
(defun tv-key-pgp-p (key / f h l hit)
  (if (setq f (findfile "acad.pgp"))
    (progn
      (setq h (open f "r"))
      (while (and (not hit) (setq l (read-line h)))
        (if (and (not (wcmatch l ";*")) (wcmatch (strcase l) (strcat key ",*"))) (setq hit T)))
      (close h)))
  hit)

;; ¾µ ¼ö ¾ø´Â ´ÜÃàÅ°¸é ±î´ßÀ», ¾µ ¼ö ÀÖÀ¸¸é nil
(defun tv-key-bad (key lst)
  (cond
    ((not (vl-every '(lambda (c) (or (<= 48 c 57) (<= 65 c 90))) (vl-string->list key))) "¿µ¹®°ú ¼ýÀÚ¸¸ ¾¹´Ï´Ù")
    ((getcname key) "AutoCAD ¸í·É°ú °°Àº ÀÌ¸§ÀÔ´Ï´Ù")
    ((tv-key-pgp-p key) "AutoCAD ´ÜÃàÅ°(acad.pgp)¿Í °°Àº ÀÌ¸§ÀÔ´Ï´Ù")
    ((and (tv-key-cmd-p key) (not (assoc key lst))) "ÀÌ¹Ì ÀÖ´Â ¸®½À ¸í·ÉÀÔ´Ï´Ù")))

(defun c:TVKEY (/ cmd key lst why)
  (setq lst (tv-key-list)
        cmd (strcase (getstring "\n´ÜÃàÅ°¸¦ ºÙÀÏ ¸í·É [¸ñ·Ï(?)]: ")))
  (cond
    ((= cmd ""))
    ((= cmd "?")
     (if lst
       (foreach p lst (princ (strcat "\n  " (car p) " = " (cdr p))))
       (princ "\nÁ¤ÇÑ ´ÜÃàÅ°°¡ ¾ø½À´Ï´Ù")))
    ((not (tv-key-cmd-p cmd)) (princ (strcat "\n" cmd " ´Â ºÒ·¯¿Â ¸®½À ¸í·ÉÀÌ ¾Æ´Õ´Ï´Ù")))
    (T
     (setq key (strcase (getstring (strcat "\n" cmd " ÀÇ »õ ´ÜÃàÅ° [Áö¿ì±â(-)]: "))))
     (cond
       ((= key ""))
       ((= key "-")
        (foreach p lst
          (if (= (cdr p) cmd) (set (read (strcat "C:" (car p))) nil)))
        (tv-key-save (vl-remove-if '(lambda (p) (= (cdr p) cmd)) lst))
        (princ (strcat "\n" cmd " ÀÇ ´ÜÃàÅ°¸¦ Áö¿ü½À´Ï´Ù")))
       ((= key cmd))
       ((setq why (tv-key-bad key lst)) (princ (strcat "\n" key ": " why)))
       (T
        (tv-key-save (cons (cons key cmd) (vl-remove-if '(lambda (p) (= (car p) key)) lst)))
        (tv-key-def key cmd)
        (princ (strcat "\nÀÌÁ¦ " key " ·Îµµ " cmd " °¡ ½ÇÇàµË´Ï´Ù"))))))
  (princ))

;; ºÒ·¯¿Ã ¶§ - ÀúÀåµÈ ´ÜÃàÅ° Áß ¸í·ÉÀÌ ºÒ·¯¿ÍÁ® ÀÖ´Â °ÍÀ» µÇ»ì¸°´Ù
(foreach p (tv-key-list)
  (if (tv-key-cmd-p (cdr p)) (tv-key-def (car p) (cdr p))))
(princ "\n´ÜÃàÅ° ¹Ù²Ù±â: TVKEY")
(princ)
