///////////////////////////////////////////////////////////////////////////////
//  Entity primary actions                                                   //
///////////////////////////////////////////////////////////////////////////////

=enttype = [|| (=s * $arg1) [=s (enttype) $arg1]]

=entattr = [|| (=s * $arg2) [= (entattr $arg1) $arg2]]

// clear ents of given type
clearents = [ 
   if $editing [
      entcancel
      entselect [=enttype $arg1]
      echo Deleted (enthavesel) $arg1 entities
      delent
   ] 
]

// replace all ents that match current selection
// with the values given
replaceents = [
   if $editing [
      do [
         entfind @(entget)
         entset @(loopconcat+ i 1 $numargs [result $[arg@i]])
      ]
      echo Replaced (enthavesel) entities
   ]
]

selentedit     = [saycommand (concatword "/entset " (entget))]
selreplaceents = [saycommand (concatword "/replaceents " (entget))]
selentfindall  = [do [entfind @(entget)]]

// modify given attribute of ent by a given amount
// arg1 attribute
// arg2 value
entproperty = [entattr $arg1 (+ (entattr $arg1) $arg2)]

enttypelist = [ 
   light mapmodel playerstart envmap particles sound spotlight decal
   teleport teledest jumppad
   flag
]

enttypeselect = [     
   enttypelength = (listlen $enttypelist)
   next = (mod (+ (indexof $enttypelist (enttype)) $arg1) $enttypelength)
   if (< $next 0) [ next = (+ $next $enttypelength) ]
   do [entset @(listsplice (entget) (at $enttypelist $next) 0 1)]
]


///////////////////////////////////////////////////////////////////////////////
//  Copy & Paste                                                             //
///////////////////////////////////////////////////////////////////////////////

// 3 types of copying and pasting
// 1. select only cubes      -> paste only cubes
// 2. select cubes and ents  -> paste cubes and ents. same relative positions
// 3. select only ents       -> paste last selected ent. if ents are selected, replace attrs as paste

opaquepaste = 1
entcopymode = 0

editcopy   = [
   if (|| (havesel) [! (enthavesel)]) [
      entcopymode = 0
      entcopy
      copy
   ] [
      entcopymode = 1
      entcopy
   ]
]

editpaste  = [ 
   cancelpaste = (! (|| (enthavesel) [havesel]));
   if $entcopymode [
      entreplace
      if $cancelpaste [cancelsel]
   ] [
      pastehilite
      reorient // temp; real fix will be in octaedit
      onrelease [ 
         if $opaquepaste delcube 
         paste; entpaste
         if $cancelpaste [cancelsel] 
      ] 
   ]
]


///////////////////////////////////////////////////////////////////////////////
//  Selection                                                                //
///////////////////////////////////////////////////////////////////////////////

// select ents with given properties
// '*' is wildcard
entfind = [
   if $numargs [
      entselect (concat [&& [=enttype @@arg1]] (loopconcat i (- $numargs 1) [
         result [[=entattr @@i @@[arg@(+ $i 2)]]]
      ]))
   ] [entselect 1]
]

entfindinsel = [
   if $numargs [
      entselect (concat [&& insel [=enttype @@arg1]] (loopconcat i (- $numargs 1) [
         result [[=entattr @@i @@[arg@(+ $i 2)]]]
      ]))
   ] [entselect insel]
]

drag       = [dragging 1; onrelease [dragging 0]]
corners    = [selectcorners 1; dragging 1; onrelease [selectcorners 0; dragging 0]]
editmove   = [moving 1; onrelease [moving 0]; result $moving]
entdrag    = [entmoving 1; onrelease [entmoving 0]; result $entmoving] 
editdrag   = [cancelsel; || (entdrag) [drag]]
selcorners = [if $hmapedit [hmapselect] [cancelsel; || (entdrag) [corners]]]
editextend = [|| (entdrag) [if (havesel) [selextend; reorient; editmovecut] [drag]]]

editmovewith = [
   if (havesel) [
      || (editmove) [arg1]
      onrelease [moving 0; dragging 0]
   ] [
      arg1
   ]
]

editmovecorner = [editmovewith selcorners]
editmovedrag   = [editmovewith editdrag]


///////////////////////////////////////////////////////////////////////////////
//  Miscellaneous Editing Commands                                           //
///////////////////////////////////////////////////////////////////////////////

editfacewsel = [
   if (|| havesel [! (enthavesel)]) [
      if $moving [pushsel $arg1] [
         entcancel
         editface $arg1 $arg2
      ]
   ]
]

entswithdirection = [playerstart teledest mapmodel decal]
entdirectionprop  = [0           0        1        1    ]

entdirection = [
   if (&& (enthavesel) [= (havesel) 0]) [
      entdiridx = (indexof $entswithdirection (enttype))
      if (>= $entdiridx 0) [
         entdirprop = (at $entdirectionprop $entdiridx)
         if (> $arg1 0) [
            entproperty $entdirprop $arg2
            if (> (entattr $entdirprop) 360) [entproperty $entdirprop -360]          
         ] [
            entproperty $entdirprop (- 0 $arg2)
            if (< (entattr $entdirprop) 0) [entproperty $entdirprop 360]
         ]
      ]
      result 1
   ] [
      result 0
   ]
]

selmovecut = 1
toggleeditmovecut = [
   selmovecut = (! $selmovecut)
   echo (? $selmovecut "Move Selection" "Cut Selection")
]
editmovecut = [
   if $selmovecut [editmove] [editcut]
]

editdel    = [if (! (enthavesel)) [delcube]; delent]
editflip   = [flip; entflip]
editrotate = [|| (entdirection $arg1 15) [rotate $arg1; entrotate $arg1]]
editcut    = [  
   if (moving 1) [
      if (= $moving 1) [selsave]
      onrelease [ 
         moving 0
         if (selmoved) [
            selswap
            copy; entcopy
            delcube; delent
            selrestore
            paste; entpaste
         ]
      ]
   ]
]

setting_entediting = 1

passthrough = [ 
   passthroughsel $arg1; 
   if $arg1 [
      passthroughcube_bak = $passthroughcube
      passthroughcube 1
   ] [
      passthroughcube $passthroughcube_bak
   ]
   entcancel 
   if $setting_entediting [entediting (! $arg1)]
]

entcomplete = [listcomplete $arg1 $enttypelist]
entcomplete newent
entcomplete entfind
entcomplete clearents

listcomplete editmat "air water clip glass noclip lava gameclip death nogi alpha"
air = [ editmat air $arg1 ]
looplist i ["" 2 3 4] [
   [water@i] = [editmat water@i $arg1]
   [lava@i]  = [editmat lava@i $arg1]
   [glass@i] = [editmat glass@i $arg1]
]
clip     = [editmat clip $arg1]
noclip   = [editmat noclip $arg1]
gameclip = [editmat gameclip $arg1]
death    = [editmat death $arg1]
nogi     = [editmat nogi $arg1]
alpha    = [editmat alpha $arg1]

blendpaintmodes = ["off" "replace" "dig" "fill" "inverted dig" "inverted fill"]

minimaphere = [minimapheight (at (getcampos) 2)]

getsundir = [sunlightyaw (getcamyaw); sunlightpitch (getcampitch)]

defvarp editfloatspeed 1 1000 10000

makeitsnow = [newent particles 13 364 70 0xAAA 550] // derp
