/*
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/>.  */

/* 
This widget is a push button that dispatches mouse events to its script object.
This widget has three properties that can be set: theme; buttonStyle and label.
*/

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

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

-- metadata
metadata author is "LiveCode"
metadata version is "1.0.2"
metadata title is "Cross Platform Button"
metadata svgicon is "M49.2,0h-34C6.8,0,0,6.8,0,15.2c0,8.4,6.8,15.2,15.2,15.2h34c8.4,0,15.2-6.8,15.2-15.2C64.3,6.8,57.5,0,49.2,0z M18.5,19.6c-0.2,0.3-0.4,0.6-0.7,0.8c-0.3,0.2-0.7,0.4-1.1,0.5s-0.9,0.1-1.4,0.1h-4.5v-2.9h2v1.2h2.4c0.4,0,0.8-0.1,1-0.2c0.4-0.2,0.7-0.6,0.7-1.3c0-0.5-0.2-0.9-0.6-1.1c-0.2-0.1-0.6-0.2-1-0.2h-2.5v1.2h-2V14h2v1h2.4c0.4,0,0.8-0.1,1.1-0.2c0.3-0.2,0.4-0.5,0.4-0.9c0-0.5-0.2-0.8-0.5-0.9c-0.3-0.1-0.7-0.2-1.2-0.2h-2.2v1h-2V11h4.9c1.2,0,2.1,0.4,2.6,1.1c0.3,0.4,0.5,0.9,0.5,1.5c0,0.6-0.2,1.1-0.5,1.5c-0.2,0.2-0.4,0.4-0.8,0.6c0.5,0.2,0.9,0.5,1.2,0.9S19,17.5,19,18C19,18.6,18.8,19.2,18.5,19.6z M27.3,21.1h-1.9V20c0,0-0.1,0.1-0.1,0.2c-0.1,0.1-0.2,0.2-0.3,0.3c-0.3,0.3-0.6,0.5-0.9,0.6s-0.6,0.2-1,0.2c-1.1,0-1.8-0.4-2.2-1.2c-0.2-0.4-0.3-1.1-0.3-1.9v-4.5h2v4.5c0,0.4,0,0.7,0.1,1c0.2,0.4,0.5,0.6,1,0.6c0.7,0,1.1-0.3,1.4-0.8c0.1-0.3,0.2-0.7,0.2-1.2v-4.1h2V21.1z M32.6,15.1h-1.2V19c0,0.3,0,0.5,0.1,0.6s0.3,0.1,0.7,0.1c0.1,0,0.1,0,0.2,0c0.1,0,0.1,0,0.2,0v1.5l-0.9,0c-0.9,0-1.5-0.1-1.9-0.5c-0.2-0.2-0.3-0.6-0.3-1v-4.6h-1v-1.4h1v-2.1h1.9v2.1h1.2V15.1z M37.2,15.1H36V19c0,0.3,0,0.5,0.1,0.6s0.3,0.1,0.7,0.1c0.1,0,0.1,0,0.2,0c0.1,0,0.1,0,0.2,0v1.5l-0.9,0c-0.9,0-1.5-0.1-1.9-0.5c-0.2-0.2-0.3-0.6-0.3-1v-4.6h-1v-1.4h1v-2.1H36v2.1h1.2V15.1z M44.7,20.2c-0.6,0.8-1.6,1.2-2.9,1.2s-2.2-0.4-2.9-1.2c-0.6-0.7-0.9-1.6-0.9-2.6h2c0,0.7,0.2,1.2,0.5,1.6c0.3,0.4,0.7,0.6,1.3,0.6s1-0.2,1.3-0.6c0.3-0.4,0.5-1,0.5-1.7c0-0.7-0.2-1.3-0.5-1.7c-0.3-0.4-0.7-0.6-1.3-0.6s-1,0.2-1.3,0.6c-0.3,0.4-0.4,0.9-0.5,1.6h-2c0-1,0.3-1.9,0.9-2.6c0.6-0.8,1.6-1.2,2.9-1.2s2.2,0.4,2.9,1.2s0.9,1.7,0.9,2.8C45.7,18.5,45.3,19.4,44.7,20.2z M53.8,21.1h-2v-4.5c0-0.4-0.1-0.7-0.2-0.9c-0.2-0.4-0.6-0.6-1.1-0.6c-0.7,0-1.1,0.3-1.3,0.8C49.1,16.2,49,16.6,49,17v4h-1.9v-7.4h1.9v1.1c0.2-0.4,0.5-0.7,0.7-0.8c0.4-0.3,0.9-0.5,1.5-0.5c0.8,0,1.4,0.2,1.9,0.6c0.5,0.4,0.7,1.1,0.7,2V21.1z M47.2,5.5h-30c-6,0-13.1,3.2-14.6,7.8C3.6,7.5,9.7,3,17.2,3h30c8.1,0,14.7,5.3,14.7,11.9C61.9,9.5,53.8,5.5,47.2,5.5z"

-- property declarations
property buttonTheme 			get mTheme 		set setTheme
property buttonStyle 	get mStyle 		set setStyle
property buttonLabel 			get mLabel 		set setLabel
--

-- 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
--

-- constants
constant kMaxHeight is 88
constant kMinHeight is 35
constant kWhite is [1,1,1]
constant kBlack is [0,0,0]
--

public handler OnSave(out rProperties as Array)
	put the empty array into rProperties
	
	put mTheme into rProperties["theme"]
	put mStyle into rProperties["buttonstyle"]
	put mLabel into rProperties["label"]
	
	return rProperties
end handler

public handler OnLoad(in pProperties as Array)
	put pProperties["theme"] into mTheme
	put pProperties["buttonstyle"] into mStyle
	put pProperties["label"] into mLabel
end handler

public handler OnCreate() returns nothing
	put "ios-8" into mTheme
	put "Button" into mLabel
	put "default" into mStyle
	put "none" into mState
end handler

public handler OnPaint() returns nothing
	
	// 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

public handler OnMouseDown() returns nothing
	put "pressed" into mState
	redraw all

	post "mouseDown"
end handler
--
public handler OnMouseUp() returns nothing
	put "none" into mState
	redraw all
    
    post "mouseUp"
end handler
--
public handler OnMouseEnter() returns nothing
	put "over" into mState
	redraw all
end handler
--
public handler OnMouseLeave() returns nothing
	if mState is not "pressed" then
		put "none" into mState
		redraw all
	end if
end handler

private handler getStrokeWidth() returns Integer
	return 1
end handler

private handler getCornerRadius() returns Integer
	if mTheme is "ios-8" then
		return 9
	else if mTheme is "macos-10.10" then
		return 5
	end if	 
	
	return 10
end handler

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

private handler getFontSize() returns Integer
	if mTheme is "ios-8" then
	 	if my height >= kMaxHeight then
			return 42 
		else if my height <= kMinHeight then
			return 12
		else
			return 24
		end if	
	end if	
	
	return 11
end handler

private handler getPaint_BackgroundFill() returns 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 kWhite
		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 color [76/255,150/255,252/255], gradient stop at 1.0 with color [16/255,103/255,227/255] ] into tStops
		else if mStyle is "default" then
			put [ gradient stop at 0.0 with color [105/255,177/255,250/255], 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 color [105/255,177/255,250/255], 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
		scale tPaint by [my height, my width]
		rotate tPaint by 90
		return tPaint
	end if
	
	return solid paint with color kWhite
end handler

private handler getPaint_BackgroundStrokeFill() returns Paint
	if mTheme is "ios-8" then
		return solid paint with color kWhite
	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 color [40/255,125/255,253/255], gradient stop at 1.0 with color [8/255,63/255,220/255] ] 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
		scale tPaint by [my height, my width]
		rotate tPaint by 90
		return tPaint
	end if
	
	return solid paint with color kWhite
end handler

private handler getPaint_TextFill() returns Paint
	if mTheme is "ios-8" then
		return solid paint with color [51/255,153/255,1]
		
	else if mTheme is "macos-10.10" then
		if mStyle is "default" then
			return solid paint with color kWhite
		else if mState is "pressed" then
			return solid paint with color kWhite
		else
			return solid paint with color kBlack
		end if			
	end if
	
	return solid paint with color kBlack
end handler

public handler setTheme(in pThemeName as String) returns nothing
	put pThemeName into mTheme
	redraw all
end handler

private handler setLabel(in pLabel as String) returns nothing
	put pLabel into mLabel
	redraw all
end handler

private handler setStyle(in pStyle as String) returns nothing
	if pStyle is in ["standard","default"] then
		put pStyle into mStyle
		redraw all
	end if
end handler

end widget
