 % Title "Drawing GUI"

'% WindowStyle WS_OVERLAPPEDWINDOW
'% Animated
'% ScaleUp
 % PlaceCentral
'% AnchorCentral
'% shaders

 uses consoleG
 '
 'color
 static float rr=.5,gg=.8,bb=.5,aa=.8

 static int editing

 function KeyState(int k) as int
 ===============================
 return GetAsyncKeyState(k) and 0x8000 'key down
 end function

 uses DrawPanels


  type NodeObject
  ===============
  float x,y,z
  int exist
  method act
  if exist>1
   glpushmatrix
   gltranslatef x,y,z
   if exist>16
    int i=exist-16
   else
    scale 0.5
    go sphere
   endif
   glpopmatrix
  endif
  end method
  end type
  '
  % mnode 1000
  static NodeObject node[mnode]
  '
  type ExtendObject
  =================
  int id
  float transform[16] 'matrix
  int cobj 'compiled object
  method act
   int i
   glpushmatrix
   'color etc
   glmultmatrixf transform
   go cobj
   glpopmatrix
  end method
  end type

  static NodeObject node[mnode]


  type LineObject
  ===============
  int vert1,vert2
  int exist
  int width
  int color
  method act
   thickness width
   'glColor4ubv color
   glbegin GL_LINES
   glvertex3fv node[vert1]
   glvertex3fv node[vert2]
   glend
  end method
  end type


  type FaceObject
  ===============
  int vert[16]
  int n
  float rr,gg,bb,aa 'color
  int texture
  int id
  int exist
  method act
  int i,j
  if n>=3
   if pick
    picklabel id
   else
    glcolor4fv rr
   endif
   glbegin GL_POLYGON
   for i=1 to n
    j=vert[i]
    glVertex3fv node[j]
   next
   'glVertex3fv vert[1] 'unneeded closure
   glend
  endif
  end method
  end type


  static LineObject line[mnode]
  static FaceObject face[mnode]
  '
  static int nnode, nline, nface, nvol
  static int editing
  '
  static int        tags[mnode]
  static int        mapn[mnode]
  '
  def stride @%1+=sizeof %1
  '
  function objfromarrays() as string
  ==================================
  int i,j,k
  bstring buf=nuls 0x10000
  bstring s
  '
  k=1
  NodeObject pp at @node
  for i=1 to nnode
  s="v " str(pp.x,4) " " str(pp.y,4) " " str(pp.z,4)+cr
  mid buf,k,s
  k+=len(s)
  stride pp
  next
  mid(buf,k,cr) : k+=2
  '
  LineObject pp at @line
  for i=1 to nline
  s="l " pp.vert1 " " pp.vert2 +cr
  mid buf,k,s
  k+=len(s)
  stride pp
  next
  mid(buf,k,cr) : k+=2
  '
  FaceObject pp at @face
  for i=1 to nface
  int*cn
  @cn=@pp.vert
  mid(buf,k)="f " : k+=2
  for j=1 to pp.n
   s=str(cn,4)+" "
   mid buf,k,s
   k+=len(s)
   stride cn
  next
  mid(buf,k)=chr(13,10) : k+=2
  stride pp
  next
  mid(buf,k,"# END"+cr) : k+=7
  function=left(buf,k)
  del buf
  del s
  end function


  procedure pack()
  ================
  int i,j,k
  'mark nodes used in polygon
  ---------------------------
  for i=1 to nface
   if face[i].exist
    int cn at @face[i].vert
    for j=1 to face[i].n
     k=cn[j]
     tags[k]=1
    next
   endif
  next
  '
  'mark nodes used in lines
  -------------------------
  for i=1 to nline
   if line[i].exist
    j=line[i].vert1
    tags[j]=1
    j=line[i].vert2
    tags[j]=1
   endif
  next
  '
  'mark nodes that exist
  ----------------------
  for i=1 to nnode
   if node[i].exist
    tags[i]=1
   endif
  next
  '
  'map new node index
  -------------------
  j=0
  for i=1 to nnode
   if tags[i]
    j++
    mapn[i]=j
   endif
  next
  '
  'remap node indexes for lines
  -----------------------------
  for i=1 to nline
   if line[i].exist
    j=line[i].vert1
    line[i].vert1=mapn[j]
    j=line[i].vert2
    line[i].vert2=mapn[j]
   endif
  next
  '
  'remap node indexes for faces
  -----------------------------
  for i=1 to nface
   if face[i].exist
    int cn at @face[i].vert
    for j=1 to face[i].n
     k=cn[j]
     cn[j]=mapn[k]
    next
   endif
  next
  '
  'pack nodes
  -----------
  j=0
  for i=1 to nnode
   if tags[i]
    j++
    if j<>i
     node[j]=node[i]
    endif
   endif
  next
  nnode=j
  '
  'pack lines
  -----------
  j=0
  for i=1 to nline
   if line[i].exist
    j++
    if j<>i
     line[j]=line[i]
    endif
   endif
  next
  nline=j
  '
  'pack faces
  -----------
  j=0
  for i=1 to nface
   if face[i].exist
    j++
    if j<>i
     face[j]=face[i]
    endif
   endif
  next
  nface=j
  '
  end procedure


  =======================
  procedure GuiElements()
  =======================

   if not pick
    if picked=0
     editing=0
    endif
   endif


  'BACKGROUND GRID
  ================
  '
  static int ShowGrid
  if not editing
   if lastkey=0x47
    ShowGrid=1-ShowGrid 'toggle
    lastkey=0
   endif
  endif


  '
  if not pick
    if ShowGrid
      pushstate
      color .2,.4,.6,1.0
      thickness 1
      move -50,-30, -2.002
      grid 1,100,60
      popstate
    endif
  endif

  'PACK GEOMETRICS
  ================
  if not editing
   if lastkey=0x5A 'Z
    pack() 'consolidate nodes etc
    lastkey=0
   endif
  endif

  'SHOW DATA IN OBJ FORMAT
  ========================
  if not editing
   if lastkey=0x51 'Q
    mbox ObjFromArrays()
    lastkey=0
   endif
  endif
  

  'NODES
  ======
  '
  static int nd1,nd2
  '
  if not editing
  if KeyState 0x4E 'N'
  if bleft
   bleft=0
   nnode++
   float z=-0.0
   float f=(32-z)/crect.bottom
   node[nnode]={f*mposx,-f*mposy}
   node[nnode].exist=3 '1 exist  2 visible
  endif 'bleft
  endif 'keystate 'N'
  endif 'editing
  '
  shading
  move -16*aspect,16.0,-0.0
  int i
  int kp
  for i=1 to nnode 'each node
  if pick
   picklabel 10000+i
  elseif not editing
   if bleft 'mouse
   if picked=10000+i 'move node
   '
   if KeyState VK_DELETE 'del node
    kp=1
    node[i].exist=0
   endif 'del
   '
   if KeyState 0x4C 'L' line
    kp=1
    bleft=0
    nd2=i
    if nd1
     nline++
     line[nline]={nd1,nd2}
     line[nline].width=1
     line[nline].exist=3
    endif 'nd1
    nd1=nd2 'line chain
   else 'not 'L
    nd1=0
   endif 'L
   '
   if KeyState 0x50 'P' polygon
    kp=1
    bleft=0
    static int cf,cp
    static int* cm
    if cf=0
     nface++
     face[nface].exist=3
     face[nface].rr={rr,gg,bb,aa}
     face[nface].id=12000+nface
     cp=1
     @cm=@face[nface]
     cm[cp]=i
     cf=i
    else 'cf<>0
     cp++
     face[nface].n=cp
     cm[cp]=i
    endif 'cf
   else 'not P
    cf=0
   endif 'P polygon
   '
   if KeyState 0x4D 'M' move node
    static int dn
    static float dx,dy
    float z=-0.0
    float f=(32-z)/crect.bottom
    if dn=0
     dx=node[i].x
     dy=node[i].y
     dn=1
    endif 'dn=0
    node[i].x= dx+f*(mposx-sposx)
    node[i].y= dy-f*(mposy-sposy)
   else 'not M
    dn=0  'end of move
   endif 'M move / nokey
   '
  endif 'picked node
 else 'not bleft
  dn=0 'end of move
 endif 'pick / bleft / not bleft
      '
 if not KeyState 0x4C 'L'
  nd1=0
 endif 'not L

 if not KeyState 0x50 'P'
  cf=0
 endif 'not P
 '
 endif 'not editing
 node[i].act 'RENDER NODE
 '
 next 'nnode 'each node
 '
 picklabel 0
 flat
 '
 'LINES
 ======
 for i=1 to nline
  line[i].act 'RENDER LINE
 next 'nline
 '
 'FACES
 ======
 for i=1 to nface
 if face[i].exist
 if picked=12000+i
      '
  'CHANGE COLOR
  if KeyState 0x43 'C color
   face[i].rr={rr,gg,bb,aa}
  endif 'C
  '
  if bleft
  '
  'DELETE FACE
  if KeyState VK_DELETE
   face[i].exist=0
   '
  'MOVE FACE INCLUDING NODES
  elseif KeyState 0x4D 'M move
   static int dn
   static float dx[16] 'max nodes
   static float dy[16] 'max nodes
   float z=-0.0
   float f=(32-z)/crect.bottom
   int j,*k
   '
   @k=@face[i].vert
   if dn=0
    for j=1 to face[i].n 'each node of face
     'create anchor points
     dx[j]=node[k].x
     dy[j]=node[k].y
     @k+=4
    next 'j each node of face
    dn=1
   endif 'dn=0
   '
   @k=@face[i].vert
   for j=1 to face[i].n 'each node of face
    node[k].x= dx[j]+f*(mposx-sposx)
    node[k].y= dy[j]-f*(mposy-sposy)
    @k+=4
   next 'j each node of face
  endif 'keystate M move
 endif 'bleft
 endif 'picked
 face[i].act 'RENDER FACE
 endif 'face exist
 next 'i nface faces
 '
 if bleft=0
  dx=0 : dy=0 : dn=0
 endif 'bleft=0
 '
 end procedure 'GuiElements
