-- ########################################################################################
-- # Test program for mnoo_fltk
-- ########################################################################################
local mnoofltk=require("mnoo_current/mnoofltk.lua")
local mnoo=require("mnoo_current/mnoo.lua")

mnoofltk.fltk:scheme{name="plastic"}

local tabs, w-- forward declaration for callback
-- ########################################################################################
-- # Callback function for everybody
-- # Print nice summary of all callback arguments
-- ########################################################################################
local cb=
   function(arg) 
      assert(arg.data) print("Callback by '"..arg.data.."'")
      for key, val in pairs(arg) do
	 local spaces=string.rep(" ", 30-string.len(key))
	 print(" "..key..spaces.."= "..val)
      end

      if arg.data=="w i n d o w" and arg.eventType=="resize" then 
	 -- window resize event
	 -- actually do something, resize the tab
	 
	 tabs:resize{x=0, y=0, w=arg.w, h=arg.h}
      elseif arg.data=="w i n d o w" and arg.eventType=="close" then 
	 os.exit()
--	 w:delete{}
      end
   end

-- ########################################################################################
-- # Create window
-- ########################################################################################
local winw=600
local winh=400
w=mnoofltk.window:new{x=100, y=100, w=winw, h=winh, callback=cb, data="w i n d o w"}
w:size_range{minw=winw, minh=winh, maxw=winw+100, maxh=winh+100}
w:label{label="mnoofltk test / demo application"}

-- ########################################################################################
-- # Create Tabs panel (also sometimes called "notebook")
-- ########################################################################################
tabs=w:tabs{x=0, y=0, w=winw, h=winh}
local p1=tabs:page{label="scroll"}
local p2=tabs:page{label="checkbutton"}
local p3=tabs:page{label="color"}
local p4=tabs:page{label="choice+menubutton"}
local p5=tabs:page{label="canvas"}

-- ########################################################################################
-- # Create page 1: scroll
-- ########################################################################################
main_scroll=p1:scroll{x=10, y=30, w=winw-20, h=winh-35} -- size needs to be adjusted by trial-and error, sorry
for i1=1, 20 do
   for i2=1, 30 do
      main_scroll:button{x=(i1-1)*150, y=(i2-1)*20, w=150, h=20, callback=cb, data="b u t t o n "..i1.."/"..i2, label="b"..i1.."/"..i2}
   end
end

-- ########################################################################################
-- # Create page 2: Checkbuttons
-- ########################################################################################
local lcb1=function(args)args.data:set_value{value=0} end
local lcb2=function(args)args.data:set_value{value=1} end
for i1=1, 10 do
   local chb=p2:checkbutton{x=20, y=20*i1+20, w=30, h=20, callback=cb, data="c h e c k b u t t o n "..i1, label="cb "..i1}
   p2:button{x=100, y=20*i1+20, w=200, h=20, callback=lcb1, data=chb, label="cb:set_value{value=0}"}
   p2:button{x=350, y=20*i1+20, w=200, h=20, callback=lcb2, data=chb, label="cb:set_value{value=1}"}
end

local wcount=0
local w2, wzap
local do_win=
   function()
      -- can't delete window from its own callback.
      -- so hide it, and delete later
      if wzap then wzap:delete{} wzap=nil end
      if w2 then w2:hide{} wzap=w2 end
      w2=mnoofltk.window:new{x=300+10*wcount, y=120, w=300, h=240, callback=cb, data="w i n d o w 2"} 
      wcount=wcount+1
      w2:label{label="testwindow "..wcount}
      
      for i=1, 10 do
	 w2:button{x=20, y=20*i, w=260, h=20, label="b "..i, callback=cb, data="b u t t o n"}
      end
      w2:show{}
   end
p2:button{x=100, y=300, w=100, h=20, label="open win", callback=do_win, data=0}
p2:input{x=100, y=320, w=100, h=20, label="input", callback=cb, data="i n p u t"}

-- ########################################################################################
-- # Create page 3: Color
-- ########################################################################################
do -- protect local variables used by callback

   local b1, b2, b3, b4
   colcb=
      function(arg) 
	 print(arg.data)
	 b4:set_color{color=arg.data}
	 w:redraw{}
      end
   
   b1=p3:button{x=100, y=40, w=100, h=20, label="red", callback=colcb, data=mnoofltk.fltk:rgb_color{red=255, green=0, blue=0}}
   b2=p3:button{x=100, y=60, w=100, h=20, label="green", callback=colcb, data=mnoofltk.fltk:rgb_color{red=0, green=255, blue=0}}
   b3=p3:button{x=100, y=80, w=100, h=20, label="blue", callback=colcb, data=mnoofltk.fltk:rgb_color{red=0, green=0, blue=255}}
   b4=p3:button{x=100, y=100, w=100, h=20, label="white", callback=colcb, data=mnoofltk.fltk:rgb_color{red=255, green=255, blue=255}}
   
   local g -- scroll
   local zap=nil
   local rebuild
   rebuild=function()
	      -- kludge, because we may not delete the widget that triggered the callback
	      if zap then
		 zap:delete{}
		 zap=nil
	      end

	      if g then 
		 p3:remove{widget=g}
		 zap=g
	      end
	      g=p3:scroll{x=20+30*math.random(), y=130+30*math.random(), w=350+30*math.random(), h=150+30*math.random()}   
	      for i=1, 100 do
		 g:button{x=math.random(1000), y=math.random(1000), w=200, h=20, callback=rebuild, data=0, label="delete widgets"}
	      end
	      p3:redraw{}
	   end
   rebuild()
end

-- ########################################################################################
-- # Create page 4: Choice
-- ########################################################################################

local ch1, ch2
local chcb=
   function() 
      local index=ch1:get_index{}
      ch2:set_index{index=index}
   end
ch1=p4:choice{x=200, y=30, w=200, h=20, data="c h o i c e", callback=chcb, label="controls other choice"}
ch2=p4:choice{x=200, y=50, w=200, h=20, data="c h o i c e", callback=cb, label="dumps callback"}
p4:button{x=400, y=30, w=50, h=20, callback=function() local i=ch1:get_index{} ch1:set_index{index=i+1} end, data=0, label="++"}
p4:button{x=450, y=30, w=50, h=20, callback=function() local i=ch1:get_index{} ch1:set_index{index=i-1} end, data=0, label="--"}

for _, item in ipairs({"one", "two", "three", "a/b/c/1", "a/b/c/2", "a/b/3", "a/b/c", "d/e/f"}) do
   ch1:add{text=item}
   ch2:add{text=item}
end
ch1:set_index{index=1}
ch2:set_index{index=1}

p4:button{x=100, y=200, w=200, h=20, label="about", callback=function()mnoofltk.fltk:message{text="mnoofltk demo (c) Markus Nentwig 2006 mnoo version: "..mnoo.getVersion()} end, data=0}

local mb=p4:menubutton{x=100, y=220, w=200, h=20, label="a menubutton"}
mb:add{label="1) a", callback=cb, data="m e n u b u t t o n (a)"}
mb:add{label="2) b", callback=cb, data="m e n u b u t t o n (b)"}
mb:add{label="3) c", callback=cb, data="m e n u b u t t o n (c)"}

-- ########################################################################################
-- # Create page 5: Canvas
-- ########################################################################################

-- color to fill the canvas background
local background=mnoofltk.fltk:rgb_color{red=0, green=0, blue=0}

-- canvas object
local canvas

-- x and y coordinates of the line bundle mid points
local x={50, 60, 70}
local y={60, 60, 60}

-- table with colors
local col

-- current brightness (mousewheel control)
local brightness=0

-- which button was clicked (for drag event)
local button

-- callback function, when the canvas generates a mouse event
local my_event_fun=
   function(arg) 
      cb(arg)
      
      if arg.eventType=="push" then 
	 button=arg.button
      end
      
      if arg.eventType=="push" or arg.eventType=="drag" then
	 assert(arg.x) assert(arg.y)
	 x[button]=arg.x
	 y[button]=arg.y
	 canvas:redraw{} -- will be redrawn after return to fltk main loop
      elseif arg.eventType=="mousewheel" then
	 brightness=brightness+10*arg.dy
	 brightness=math.min(brightness, 255)
	 brightness=math.max(brightness, 0)
	 col=nil
	 canvas:redraw{} -- will be redrawn after return to fltk main loop
      end
   end

-- callback function, when FLTK main loop wants to redraw the canvas
local redraw_fun=
   function(args) 

      -- clean background
      mnoofltk.fltk:set_color{color=background}
      mnoofltk.fltk:rect{x=canvas:getx{}, y=canvas:gety{}, w=canvas:getw{}, h=canvas:geth{}}
      
      -- midpoint and radius of circle that describes common line endpoints
      local radius=math.min(canvas:getw{}, canvas:geth{})/2-20
      local x0=canvas:getx{}+canvas:getw{}/2
      local y0=canvas:gety{}+canvas:geth{}/2

      -- regenerate colors on startup / if changed
      if not col then
	 col={
	    mnoofltk.fltk:rgb_color{red=255, green=brightness, blue=brightness},
	    mnoofltk.fltk:rgb_color{red=brightness, green=255, blue=brightness},
	    mnoofltk.fltk:rgb_color{red=brightness, green=brightness, blue=255}
	 }
      end
      
      -- draw three sets of line bundles
      for i=1, 3 do
	 mnoofltk.fltk:set_color{color=col[i]}      

	 for angle=0, 2*math.pi, 2*math.pi/50 do
	    local x1=x0+radius*math.cos(angle)
	    local y1=y0-radius*math.sin(angle)
	    
	    mnoofltk.fltk:begin_line{} 
	    mnoofltk.fltk:vertex{x=x1, y=y1} -- point on circle
	    mnoofltk.fltk:vertex{x=x[i], y=y[i]} -- point clicked last with mouse button x
	    mnoofltk.fltk:end_line{}
	 end
      end

--      cb(args)
   end

-- ########################################################################################
-- # Create the canvas, using above callbacks for redraw and event handling
-- ########################################################################################
canvas=p5:canvas{
   x=p5:getx{}+10, 
   y=p5:gety{}+10,
   w=p5:getw{}-20, 
   h=p5:geth{}-20, 
   redraw_fun=redraw_fun, 
   redraw_data="c a n v a s (redraw)",
   event_fun=my_event_fun, 
   event_data="c a n v a s (event)"}

-- ########################################################################################
-- # Window is hidden by default. Show it
-- ########################################################################################
w:show{}

-- ########################################################################################
-- # Enter FLTK main loop, which will run until all windows are closed
-- # an alternative would be a loop around mnoofltk.fltk:wait{time=x}, to keep this application
-- # in control all times.
-- ########################################################################################
mnoofltk.fltk:run{}