;;; AutoCATS 리습 자료실
;; 명령: MIDMARK
;; 기능: 선·호·경량 폴리선의 길이 절반 지점에 십자 마크를 만듭니다.
;; 출처: https://www.autocats.co.kr/lisp/midpoint-mark
;; 버전: 1.0 (2026-10-23)
;; 라이선스: 자유 사용·수정, 재배포 시 출처(autocats.co.kr) 표기
;; 안전: 잠긴 레이어·외부참조 보호, 변경은 UNDO 그룹, 명령별 범위는 상세 가이드 참고

(vl-load-com)

(defun autocats-midmark-safe-p (ent / data row block)
  (setq data (entget ent)
    row (tblsearch "LAYER" (cdr (assoc 8 data))))
  (and data row (= 0 (logand 4 (cdr (assoc 70 row))))
    (or (/= "INSERT" (cdr (assoc 0 data)))
      (and (setq block (tblsearch "BLOCK" (cdr (assoc 2 data))))
        (= 0 (logand 12 (cdr (assoc 70 block))))))))

(defun autocats-midmark-batch (selection action / index changed skipped ent result)
  (setq index 0 changed 0 skipped 0)
  (if selection
    (repeat (sslength selection)
      (setq ent (ssname selection index)
        result (if (autocats-midmark-safe-p ent) (vl-catch-all-apply action (list ent))))
      (if (and result (not (vl-catch-all-error-p result)))
        (setq changed (1+ changed))
        (setq skipped (1+ skipped)))
      (setq index (1+ index))))
  (princ (strcat "\n[MIDMARK] 완료: " (itoa changed) " / 건너뜀: " (itoa skipped)))
  (list changed skipped))

(defun autocats-midmark-point (ent / end length)
  (if (member (cdr (assoc 0 (entget ent))) '("LINE" "ARC" "LWPOLYLINE"))
    (progn (setq end (vlax-curve-getEndParam ent) length (vlax-curve-getDistAtParam ent end))
      (if (> length 0.0) (vlax-curve-getPointAtDist ent (/ length 2.0))))))
(defun autocats-midmark-draw (ent size / point row a b)
  (setq point (autocats-midmark-point ent) row (tblsearch "LAYER" (getvar "CLAYER")))
  (if (and point (> size 0.0) row (> (cdr (assoc 62 row)) 0) (= 0 (logand 5 (cdr (assoc 70 row)))))
    (progn
      (setq a (entmakex (list '(0 . "LINE") (cons 8 (getvar "CLAYER"))
            (cons 10 (mapcar '+ point (list (- size) 0.0 0.0))) (cons 11 (mapcar '+ point (list size 0.0 0.0))))))
      (setq b (entmakex (list '(0 . "LINE") (cons 8 (getvar "CLAYER"))
            (cons 10 (mapcar '+ point (list 0.0 (- size) 0.0))) (cons 11 (mapcar '+ point (list 0.0 size 0.0))))))
      (if (and a b) T (progn (if a (entdel a)) (if b (entdel b)) nil)))))

(defun c:MIDMARK (/ *error* undo-open size selection)
  (defun *error* (msg)
    (if undo-open (progn (command-s "_.UNDO" "_End") (setq undo-open nil)))
    (if (and msg (not (wcmatch (strcase msg) "*CANCEL*,*QUIT*,*EXIT*,*취소*")))
      (princ (strcat "\n[MIDMARK] 중단: " msg)))
    (princ))

  (initget 7) (setq size (getdist "\n십자 한 팔 길이: "))
  (if size (progn
      (princ "\n대상 객체를 선택하세요: ")
      (setq selection (ssget '((0 . "LINE,ARC,LWPOLYLINE"))))
      (if selection
        (progn
          (command "_.UNDO" "_Begin")

          (setq undo-open T)
          (autocats-midmark-batch selection '(lambda (ent) (autocats-midmark-draw ent size)))
          (command "_.UNDO" "_End")
          (setq undo-open nil)))))
  (princ))

(princ "\n[AutoCATS] MIDMARK 로드 완료")
(princ)
