/*
Copyright (C) 2015 Runtime Revolution Ltd.

This file is part of LiveCode.

LiveCode is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License v3 as published by the Free
Software Foundation.

LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with LiveCode.  If not see <http://www.gnu.org/licenses/>.  */


-- declaring the extension as a widget, followed by the identifier
widget com.livecode.extensions.livecode.buttonPopupLauncher
--

-- dependancy declarations
use com.livecode.canvas
use com.livecode.widget
use com.livecode.engine
-- use com.livecode.extensions.livecode.segmentedControlPopup
--

-- adding metadata to ensure the extension displays correctly in livecode
metadata author is "Benjamin Beaumont, Ian Macphail"
metadata version is "1.0.1"
metadata title is "Cross Platform Button Popup Launcher"
--

-- property declarations
property theme 			get mTheme 		set setTheme
property buttonstyle 	get mStyle 		set setStyle
property label 			get mLabel 		set setLabel
property labels			get mLabels		set mLabels
--

-- private instance variables
private variable mTheme as optional string
private variable mStyle as optional string
private variable mLabel as optional string
private variable mState as optional string
private variable mPopup as optional string
private variable mLabels as optional string
--

----------
-- this handler is called when the widget is created
public handler OnCreate() as undefined
	put "ios-8" into mTheme
	put "Stop,Go,Cancel" into mLabels
	put "Stop" into mLabel
	put "standard" into mStyle
	put "none" into mState
	put "com.livecode.extensions.livecode.segmentedControlPopup" into mPopup
end handler
----------

----------
-- this handler is called whenever the widget is drawn
public handler OnPaint() as undefined
	// Draw the shadow
	// To implement. Waiting for the ability to draw outside the bounds of a control
	
	// Draw the main background
	variable tPath as Path
	put rounded rectangle path of my bounds with radius getCornerRadius() into tPath
	set the paint of this canvas to getPaint_BackgroundFill()
	fill tPath on this canvas
	
	// Draw the stoke
	set the paint of this canvas to getPaint_BackgroundStrokeFill()
	set the stroke width of this canvas to getStrokeWidth()
	stroke tPath on this canvas
	
	// Draw the text
	set the font of this canvas to font getFontName() at size getFontSize()
	set the paint of this canvas to getPaint_TextFill()
	fill text mLabel at center of my bounds on this canvas
end handler
----------

----------
-- the following handlers are for mouse actions
public handler OnMouseDown() as undefined
	put "pressed" into mState
	redraw all
	dispatch command "mouseDown" to my script object
end handler

public handler OnMouseUp() as undefined
	put "none" into mState
	redraw all
	
	variable tProps
	put the empty array into tProps
	put mLabels into tProps["labels"]
	
	popup widget mPopup at the mouse position with properties tProps
	if the result is defined then
		setLabel(the result)
	else
		setLabel("<none>")
	end if
	dispatch command "mouseUp" to my script object
end handler

public handler OnMouseEnter() as undefined
	put "over" into mState
	redraw all
end handler

public handler OnMouseLeave() as undefined
	if mState is not "pressed" then
		put "none" into mState
		redraw all
	end if
end handler
----------

----------
-- this handler returns the stroke width
private handler getStrokeWidth() as number
	return 1
end handler
----------

----------
-- this handler returns the corner radius
private handler getCornerRadius() as number
	if mTheme is "ios-8" then
		return 9
	else if mTheme is "macos-10.10" then
		return 5
	end if	 
	
	return 10
end handler
----------

----------
-- this handler returns a font name as a string
private handler getFontName() as string
	if mTheme is "ios-8" then
		return "Helvetica Neue"
	end if	
	
	return the name of the font of this canvas
end handler
----------

----------
-- this handler returns the font size
private handler getFontSize() as number
	if mTheme is "ios-8" then
	 	if my height >= 88 then
			return 42 
		else if my height <= 35 then
			return 12
		else
			return 24
		end if	
	end if	
	
	return 11
end handler
----------

----------
-- this handler returns a paint for the background fill
private handler getPaint_BackgroundFill() as Paint
	if mTheme is "ios-8" then
		if mState is "pressed" then	
			return solid paint with color [246/255, 246/255, 247/255]
		else
			return solid paint with color [1, 1, 1]
		end if
	
	else if mTheme is "macos-10.10" then
		variable tStops as list
		if mStyle is "default" and mState is "pressed" then
			put [ gradient stop at 0.0 with stringToColor("76,150,252"), gradient stop at 1.0 with stringToColor("16,103,227") ] into tStops
		else if mStyle is "default" then
			put [ gradient stop at 0.0 with stringToColor("105,177,250"), gradient stop at 1.0 with color [0.051,0.506,1] ] into tStops
		else if mState is "pressed" then
			put [ gradient stop at 0.0 with stringToColor("105,177,250"), gradient stop at 1.0 with color [0.051,0.506,1] ] into tStops
		else
			return solid paint with color [1, 1, 1,0.17]
		end if
		
		// Create the linear gradient paint
		variable tPaint as Paint
		put linear gradient with ramp tStops into tPaint
		
		// Scale the paint
		variable tWidth as real
		variable tHeight as real
		put the width of my bounds into tWidth
		put the height of my bounds into tHeight
		scale tPaint by [tHeight, tWidth]
		rotate tPaint by 90
		return tPaint
	end if
	
	return solid paint with color [1, 1, 1]
end handler
----------

----------
-- this handler returns a paint for the background stroke
private handler getPaint_BackgroundStrokeFill() as Paint
	if mTheme is "ios-8" then
		return solid paint with color [1, 1, 1]
	else if mTheme is "macos-10.10" then
		variable tStops as list
		if mStyle is "default" and mState is "pressed" then
			put [ gradient stop at 0.0 with stringToColor("40,125,253"), gradient stop at 1.0 with stringToColor("8,63,220") ] into tStops
		else if mStyle is "default" then
			put [ gradient stop at 0.0 with color [0.29,0.63,0.97], gradient stop at 1.0 with color [0.02,0.38,1] ] into tStops
		else if mState is "pressed" then
			put [ gradient stop at 0.0 with color [0.29,0.63,0.97], gradient stop at 1.0 with color [0.02,0.38,1] ] into tStops
		else
			put [ gradient stop at 0.0 with color [0.765,0.765,0.765], gradient stop at 1.0 with color [0.67,0.67,0.67] ] into tStops
		end if
		
		// Create the linear gradient paint
		variable tPaint as Paint
		put linear gradient with ramp tStops into tPaint
	
		// Scale the paint
		variable tWidth as real
		variable tHeight as real
		put the width of my bounds into tWidth
		put the height of my bounds into tHeight
		scale tPaint by [tHeight, tWidth]
		rotate tPaint by 90
		return tPaint
	end if
	
	return solid paint with color [1, 1, 1]
end handler
----------

----------
-- this handler returns a paint for the text
private handler getPaint_TextFill() as Paint
	if mTheme is "ios-8" then
		return solid paint with color [0, 0.48, 1]
		
	else if mTheme is "macos-10.10" then
		if mStyle is "default" then
			return solid paint with color [1,1,1]
		else if mState is "pressed" then
			return solid paint with color [1,1,1]
		else
			return solid paint with color [0,0,0]
		end if			
	end if
	
	return solid paint with color [0,0,0]
end handler
----------

----------
-- this handler sets the theme of the button
public handler setTheme(in pThemeName as string) as undefined
	put pThemeName into mTheme
	redraw all
end handler
----------

----------
-- this handler sets the label of the button
private handler setLabel(in pLabel as string) as undefined
	put pLabel into mLabel
	redraw all
end handler
----------

----------
-- this handler sets the style of the button
private handler setStyle(in pStyle as string) as undefined
	if pStyle is in ["standard","default"] then
		put pStyle into mStyle
		redraw all
	end if
end handler
----------

----------
-- this handler returns a string as a color
private handler stringToColor(in pString as string) as Color
	variable tRed as real
	variable tGreen as real
	variable tBlue as real
	variable tAlpha as real

	variable tComponentList as list
	split pString by "," into tComponentList

	variable tComponentCount
	put the number of elements in tComponentList into tComponentCount
	if tComponentCount is not 3 and tComponentList is not 4 then
		// Invalid number of components detected
		throw "Invalid color"
	end if

	put (element 1 of tComponentList) parsed as number into tRed
	put (element 2 of tComponentList) parsed as number into tGreen
	put (element 3 of tComponentList) parsed as number into tBlue

	if tComponentCount is 4 then
		put (element 4 of tComponentList) parsed as number into tAlpha
	else
		put 1.0 into tAlpha
	end if

	return color [ tRed/255, tGreen/255, tBlue/255, tAlpha ]
end handler
----------

end widget