Update maniac.monkey

Update maniac.monkey

started adding the Path's for the lib data for the Framework.
Also started included some Async stuff. But it is not usable Righ now

#Rem monkeydoc Module maniac
	Copyright (C) 2015  Stephan Duckerschein~n
	This Framework provides many additional Graphical Effects and primite Drawings, like unfilled rectangular , ellipsis etc. Diverse GUI Elements.~n
	It has it's own TileMap Engine included and even a Debug Tracking-System. ~n
	~n
	Installation:~n
	to use this Module, you have to Copy the "lib/" Folder data to Your App's Data.~n
	~n
	In the following is an Example, how to Include the maniac Framework to your Monkey Project.~n
Example:
<pre>
'This Example Shows how to integrate the Maniac-Framework to your App

'1. First You have to Import the Libs
import mojo
import maniac

'2. Main Function and App extending Class
Function Main:Int()
	New Example
	Return 0
End

Class Example extends App
	Method OnCreate:Int()
		SetUpdateRate( 60 )
		initManiac()			' THIS INITS THE MANIAC FRAMEWORK! THIS NEED TO BE DONE BEFORE USING IT!!!!!
	end Method

	Method OnUpdate:int()

	end method

	Method OnRender:int()
		Cls
	end Method
End class
</pre>

~n
Featurelist:
	GUI: - Textfield, Button, Dialog, GalleryViewer, Slider, DropDown, ListView, Checkbox ~n
	Graphics: - Outlined: Rect, Ellipsis ; LighningFX, Grid ~n
	TileMap: TileMapEngine featuring an Editor~n
	Font: Including a Font~n

#End

#rem
 <The Duke Game Framework. It provides useful little helperfunctions and class to develope 2D Games with Monkey X>
    Copyright (C) 2014-2015  Stephan Duckerschein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #end

#rem
	The main Aim is to provide a wideranged kit for developing games with Monkey X.
	It tries to be as lightweight as possible.
	And it should be usable without changeging the mojo framework.

	Features:
		DebugSystem: It tracks all used Elements from Maniac within the DebugClass.
		So you can easily monitor your Objects.
#end

#rem
	TO DO FEATURES:
		- Include Async Loader for the Images
		- make the including Paths to Files configurable by including an config.ini file to define them ...
#end

#rem
	Importing the Module-Parts of the maniac Framework.
#end

Import maniacLowLevel			'325		364
Import maniacFont				'249
Import maniacDebug				'334
Import maniacGraphics			'686		763
Import maniacMisc				'248
Import maniacSimpleGUI			'1214		1515
Import maniacTween				'667
Import maniacMap				'168

#rem
	These are all global accessable Objects to your project.They will be initialised automatically within the initManiac() Method.
#end
Global MANIAC_FONT:ManiacFont
Global MANIAC_IMG_LOGO:Image
Global MANIAC_IMG_STAR:Image
Global MANIAC_IMG_STARBLUR:Image
Global MANIAC_IMG_BACKGROUND:Image
Global MANIAC_IMG_FRAME_RAW:Image 		'
Global MANIAC_IMG_FRAME_BLUR:Image
Global MANIAC_IMG_SLIDERLINE:Image
Global MANIAC_IMG_SLIDERPICKER:Image
Global MANIAC_IMG_EDITICON:Image
Global MANIAC_IMG_CHECK:Image
Global MANIAC_IMG_DROPDOWN:Image
Global MANIAC_IMG_ARROWDOWN:Image
Global MANIAC_CHARACTERSCOUNT:Int = 30

#rem
	Here are the Paths to the Included Images for this Framework
	At the moment theyre not used.
	Future Feature: Set them up via a config.ini file or something.
#end
Global MANIAC_PATH_LOGO:String						= "lib/logo.png"
Global MANIAC_PATH_STAR:String						= "lib/star.png"
Global MANIAC_PATH_STARBLUR:String
Global MANIAC_PATH_BACKGROUND:String  				= "lib/Hintergrund.png"
Global MANIAC_PATH_FRAME_RECT:String
Global MANIAC_PATH_FRSME_RECTBLUR:String
Global MANIAC_PATH_FRAME_RECTROUND:String
Global MANIAC_PATH_FRAME_RECTROUNDBLUR:String
Global MANIAC_PATH_FRAME_CIRCLE:String
Global MANIAC_PATH_FRAME_CIRCLEBLUR:String
Global MANIAC_PATH_ICO_EDIT:String
Global MANIAC_PATH_ICO_CHECK:String
Global MANIAC_PATH_ICO_DROPDOWN_ARROW:String
Global MANIAC_PATH_ICO_ARROWDOWN:String
Global MANIAC_PATH_ICO_SLIDERLINE:String
Global MANIAC_PATH_ICO_SLIDERPICKER:String

Const FPSGRAPH_OFF:Int = 0
Const FPSGRAPH_FPS_ONLY:Int = 1
Const FPSGRAPH_GRAPH:Int = 2

Global MANIAC_FPSGRAPH:Maniac_Debug' = New fpsCounter
Global MODULE_INITED_CORRECT:Bool 		'if false, the whole Maniac-Module uses a fallback Drawings-Stuff

Global DW:Float,DH:Float,MX:Float,MY:Float
'Mouse Button States
Global gl_clicked:Bool
Global gl_mousereleased:Bool

Global MANIAC_DEBUG:Bool = False
Global MANIAC_LOADASYNC:Bool = False 		'## RECOMMEND: SET ON FALSE, as there is no Async Loader included @ the moment !!!

Global maniac_lastTime:Int
Global maniac_timeScale:Float

#Rem monkeydoc
	This Function Inits this Module.
	It Loads all necessary Images and Sounds and stuff from the lib/ folder.
	if No Images were found, it falls back to a "at least running without any Image" mode. so it just shows up, that there are Graphics missing
#End
Function initManiac(_Debug:Bool = False)
	MANIAC_DEBUG = _Debug
	DW = DeviceWidth()
	DH = DeviceHeight()
	MODULE_INITED_CORRECT = True

	If MANIAC_LOADASYNC = False
		MANIAC_FONT = New ManiacFont(22,27,["lib/font2.png"],[[32,5,27,0,0,0,0,0,0,19],[33,5,27,0,393,46,7,18,-1,4],[34,9,27,0,122,99,10,10,-1,3],[35,15,27,0,51,66,17,17,-1,5],[36,16,27,0,478,0,18,22,-1,2],[37,20,27,0,332,25,21,21,-1,2],[38,16,27,0,34,66,17,17,-1,5],[39,5,27,0,116,99,6,10,-1,3],[40,9,27,0,89,0,11,24,-1,2],[41,9,27,0,78,0,11,24,-1,2],[42,14,27,0,378,46,15,18,-1,4],[43,12,27,0,386,83,14,14,-1,6],[44,6,27,0,109,99,7,10,-1,14],[45,10,27,0,174,99,12,7,-1,10],[46,5,27,0,219,99,6,6,-1,15],[47,12,27,0,366,25,13,21,-1,2],[48,18,27,0,24,83,19,16,-1,5],[49,12,27,0,60,83,14,16,-1,5],[50,14,27,0,171,83,15,15,-1,6],[51,16,27,0,154,83,17,15,-1,6],[52,15,27,0,154,66,17,17,-1,5],[53,15,27,0,138,66,16,17,-1,5],[54,16,27,0,121,66,17,17,-1,5],[55,13,27,0,106,66,15,17,-1,5],[56,15,27,0,89,66,17,17,-1,5],[57,15,27,0,43,83,17,16,-1,6],[58,5,27,0,424,83,6,14,-1,7],[59,6,27,0,68,66,7,17,-1,7],[60,10,27,0,412,83,12,14,-1,7],[61,14,27,0,79,99,16,11,-1,7],[62,10,27,0,400,83,12,14,-1,7],[63,13,27,0,75,66,14,17,-1,5],[64,21,27,0,14,46,22,20,-1,6],[65,17,27,0,461,66,18,17,-1,5],[66,14,27,0,446,66,15,17,-1,5],[67,15,27,0,430,66,16,17,-1,5],[68,15,27,0,414,66,16,17,-1,5],[69,14,27,0,399,66,15,17,-1,5],[70,13,27,0,385,66,14,17,-1,5],[71,15,27,0,369,66,16,17,-1,5],[72,14,27,0,353,66,16,17,-1,5],[73,11,27,0,142,83,12,16,-1,6],[74,15,27,0,126,83,16,16,-1,5],[75,14,27,0,337,66,16,17,-1,5],[76,14,27,0,322,66,15,17,-1,5],[77,17,27,0,304,66,18,17,-1,5],[78,15,27,0,287,66,17,17,-1,5],[79,18,27,0,107,83,19,16,-1,5],[80,15,27,0,416,46,16,18,-1,4],[81,18,27,0,268,66,19,17,-1,5],[82,15,27,0,400,46,16,18,-1,4],[83,16,27,0,250,66,18,17,-1,5],[84,15,27,0,319,83,16,15,-1,6],[85,15,27,0,90,83,17,16,-1,5],[86,16,27,0,233,66,17,17,-1,5],[87,16,27,0,215,66,18,17,-1,5],[88,15,27,0,199,66,16,17,-1,5],[89,14,27,0,184,66,15,17,-1,5],[90,15,27,0,74,83,16,16,-1,5],[91,9,27,0,67,0,11,24,-1,2],[92,12,27,0,353,25,13,21,-1,2],[93,9,27,0,56,0,11,24,-1,2],[94,12,27,0,26,99,13,12,-1,2],[95,15,27,0,203,99,16,6,-1,20],[96,7,27,0,141,99,8,9,-1,3],[97,14,27,0,304,83,15,15,-1,7],[98,12,27,0,287,46,13,19,-1,3],[99,12,27,0,472,83,13,14,-1,7],[100,12,27,0,70,46,14,20,-1,2],[101,13,27,0,290,83,14,15,-1,7],[102,12,27,0,274,46,13,19,-1,3],[103,13,27,0,260,46,14,19,-1,7],[104,13,27,0,246,46,14,19,-1,3],[105,5,27,0,239,46,7,19,-1,3],[106,5,27,0,315,0,7,23,-1,3],[107,12,27,0,56,46,14,20,-1,2],[108,5,27,0,50,46,6,20,-1,2],[109,16,27,0,272,83,18,15,-1,7],[110,13,27,0,258,83,14,15,-1,7],[111,12,27,0,458,83,14,14,-1,7],[112,12,27,0,36,46,14,20,-1,7],[113,13,27,0,225,46,14,19,-1,7],[114,10,27,0,246,83,12,15,-1,7],[115,13,27,0,232,83,14,15,-1,7],[116,12,27,0,171,66,13,17,-1,4],[117,12,27,0,218,83,14,15,-1,7],[118,13,27,0,443,83,15,14,-1,7],[119,16,27,0,200,83,18,15,-1,7],[120,13,27,0,186,83,14,15,-1,7],[121,13,27,0,211,46,14,19,-1,7],[122,12,27,0,430,83,13,14,-1,8],[123,12,27,0,28,0,14,25,-1,2],[124,5,27,0,309,0,6,23,-1,3],[125,12,27,0,14,0,14,25,-1,2],[126,15,27,0,157,99,17,8,-1,10],[127,13,27,0,0,46,14,20,-1,3],[161,5,27,0,371,46,7,18,-1,9],[162,12,27,0,465,0,13,22,-1,3],[163,14,27,0,18,66,16,17,-1,5],[164,16,27,0,0,66,18,17,-1,4],[165,14,27,0,481,46,15,17,-1,5],[166,5,27,0,303,0,6,23,-1,3],[167,13,27,0,317,25,15,21,-1,5],[168,9,27,0,192,99,11,6,-1,5],[169,21,27,0,189,46,22,19,-1,5],[170,13,27,0,65,99,14,11,-1,5],[171,17,27,0,368,83,18,14,-1,7],[172,12,27,0,95,99,14,10,-1,10],[174,21,27,0,167,46,22,19,-1,5],[176,12,27,0,52,99,13,11,-1,4],[177,13,27,0,357,46,14,18,-1,4],[178,12,27,0,0,99,13,13,-1,4],[179,12,27,0,13,99,13,12,-1,5],[180,8,27,0,132,99,9,9,-1,3],[181,14,27,0,152,46,15,19,-1,7],[182,18,27,0,297,25,20,21,-1,4],[183,5,27,0,186,99,6,6,-1,10],[184,7,27,0,149,99,8,8,-1,17],[185,7,27,0,498,83,8,13,-1,5],[186,11,27,0,39,99,13,11,-1,5],[187,17,27,0,350,83,18,14,-1,7],[188,17,27,0,278,25,19,21,-1,2],[189,18,27,0,259,25,19,21,-1,2],[190,18,27,0,239,25,20,21,-1,2],[191,13,27,0,467,46,14,17,-1,10],[192,17,27,0,285,0,18,23,-1,-1],[193,17,27,0,267,0,18,23,-1,-1],[194,17,27,0,249,0,18,23,-1,-1],[195,17,27,0,447,0,18,22,-1,0],[196,17,27,0,221,25,18,21,-1,1],[197,17,27,0,231,0,18,23,-1,-1],[198,22,27,0,0,83,24,16,-1,6],[199,15,27,0,486,25,16,20,-1,5],[200,14,27,0,216,0,15,23,-1,-1],[201,14,27,0,201,0,15,23,-1,-1],[202,14,27,0,186,0,15,23,-1,-1],[203,14,27,0,206,25,15,21,-1,1],[204,11,27,0,174,0,12,23,-1,-1],[205,11,27,0,162,0,12,23,-1,-1],[206,12,27,0,148,0,14,23,-1,-1],[207,11,27,0,194,25,12,21,-1,1],[208,17,27,0,448,46,19,17,-1,5],[209,15,27,0,430,0,17,22,-1,0],[210,18,27,0,411,0,19,22,-1,-1],[211,18,27,0,392,0,19,22,-1,-1],[212,18,27,0,373,0,19,22,-1,-1],[213,18,27,0,175,25,19,21,-1,0],[214,18,27,0,467,25,19,20,-1,1],[215,12,27,0,485,83,13,13,-1,7],[216,18,27,0,129,0,19,23,-1,2],[217,15,27,0,356,0,17,22,-1,-1],[218,15,27,0,339,0,17,22,-1,-1],[219,15,27,0,322,0,17,22,-1,-1],[220,15,27,0,450,25,17,20,-1,1],[221,14,27,0,114,0,15,23,-1,-1],[222,14,27,0,432,46,16,17,-1,5],[223,14,27,0,342,46,15,18,-1,4],[224,14,27,0,160,25,15,21,-1,1],[225,14,27,0,145,25,15,21,-1,1],[226,14,27,0,130,25,15,21,-1,1],[227,14,27,0,435,25,15,20,-1,2],[228,14,27,0,137,46,15,19,-1,3],[229,14,27,0,115,25,15,21,-1,1],[230,21,27,0,479,66,23,16,-1,6],[231,12,27,0,329,46,13,18,-1,7],[232,13,27,0,101,25,14,21,-1,1],[233,13,27,0,87,25,14,21,-1,1],[234,13,27,0,72,25,15,21,-1,1],[235,13,27,0,123,46,14,19,-1,3],[236,7,27,0,64,25,8,21,-1,1],[237,8,27,0,55,25,9,21,-1,1],[238,11,27,0,42,25,13,21,-1,1],[239,9,27,0,112,46,11,19,-1,3],[240,14,27,0,314,46,15,18,-1,3],[241,13,27,0,421,25,14,20,-1,2],[242,12,27,0,407,25,14,20,-1,1],[243,12,27,0,393,25,14,20,-1,1],[244,12,27,0,379,25,14,20,-1,1],[245,12,27,0,98,46,14,19,-1,2],[246,12,27,0,300,46,14,18,-1,3],[247,14,27,0,335,83,15,14,-1,5],[248,12,27,0,28,25,14,21,-1,4],[249,12,27,0,14,25,14,21,-1,1],[250,12,27,0,0,25,14,21,-1,1],[251,12,27,0,496,0,14,21,-1,1],[252,12,27,0,84,46,14,19,-1,3],[253,13,27,0,0,0,14,25,-1,1],[254,12,27,0,42,0,14,24,-1,3],[255,13,27,0,100,0,14,23,-1,3]])
		MANIAC_IMG_BACKGROUND = LoadImage("lib/Hintergrund.png")
		MANIAC_IMG_STAR = LoadImage("lib/star.png")
		MANIAC_IMG_LOGO = LoadImage("lib/logo.png")
		MANIAC_IMG_FRAME_RAW = LoadImage("lib/Frame_raw2.png",1,Image.MidHandle)
		MANIAC_IMG_FRAME_BLUR = LoadImage("lib/Frame_blur.png",1,Image.MidHandle)
		MANIAC_IMG_EDITICON = LoadImage("lib/ico_edit.png")
		MANIAC_IMG_SLIDERLINE = LoadImage("lib/Slider_Line.png")
		MANIAC_IMG_SLIDERPICKER = LoadImage("lib/Slider_Picker.png",1,Image.MidHandle)
		MANIAC_IMG_CHECK = LoadImage("lib/ico_check.png")
		MANIAC_IMG_DROPDOWN = LoadImage("lib/ico_dropdown.png")
		MANIAC_IMG_ARROWDOWN = LoadImage("lib/ico_arrowdown.png")
	Else
		#rem
			TO DO:
			Try to find a way to include some Async Loading stuff with the lowest impact of how to use this Framework.
			## RECOMMEND : SET TO FALSE ##
		#end
	Endif

	If MANIAC_DEBUG = True
		MANIAC_FPSGRAPH = New Maniac_Debug(DW*0.2,DH*0.8,DW*0.65,DH*0.19)
	Endif
	If MANIAC_FONT = Null
		Print "Found no Font Data"
		MODULE_INITED_CORRECT = False
	Endif
	If MANIAC_IMG_FRAME_RAW = Null
		Print "Found no Raw Frame Data"
		MODULE_INITED_CORRECT = False
	Endif
	If MANIAC_IMG_FRAME_BLUR = Null
		Print "Found no blurred Frame Data"
		MODULE_INITED_CORRECT = False
	Endif
	If MANIAC_IMG_EDITICON = Null
		Print "Found no Edit_Icon"
		MODULE_INITED_CORRECT = False
	Endif
	If MANIAC_FPSGRAPH = Null
		Print "Couldnt create an FPS Graph"
		MODULE_INITED_CORRECT = False
	Endif

End Function

#Rem monkeydoc
	This Function should called on every Update() MEthod within your App.
	It keeps some important states of the ManiacModule active
#End
Function maniacUpdate()
	UpdateAsyncEvents()
	If MANIAC_DEBUG = True
		Maniac_Debug.addCall()
	Endif

	MX = MouseX()
	MY = MouseY()

	Maniac_CheckMouseState()

	ll_UpdateSpeeds()
End Function

Function maniacSetDebug(b:Bool = True)
	MANIAC_DEBUG = b
End Function

Function maniacSetAsyncLoad(b:Bool = True)
	MANIAC_LOADASYNC = b
End Function

#Rem monkeydoc Module maniac
	Copyright (C) 2015  Stephan Duckerschein~n
	This Framework provides many additional Graphical Effects and primite Drawings, like unfilled rectangular , ellipsis etc. Diverse GUI Elements.~n
	It has it's own TileMap Engine included and even a Debug Tracking-System. ~n
	~n
	Installation:~n
	to use this Module, you have to Copy the "lib/" Folder data to Your App's Data.~n
	~n
	In the following is an Example, how to Include the maniac Framework to your Monkey Project.~n
Example:
<pre>
'This Example Shows how to integrate the Maniac-Framework to your App

'1. First You have to Import the Libs
import mojo
import maniac

'2. Main Function and App extending Class
Function Main:Int()
	New Example
	Return 0
End

Class Example extends App
	Method OnCreate:Int()
		SetUpdateRate( 60 )
		initManiac()			' THIS INITS THE MANIAC FRAMEWORK! THIS NEED TO BE DONE BEFORE USING IT!!!!!
	end Method

	Method OnUpdate:int()

	end method

	Method OnRender:int()
		Cls
	end Method
End class
</pre>

~n
Featurelist:
	GUI: - Textfield, Button, Dialog, GalleryViewer, Slider, DropDown, ListView, Checkbox ~n
	Graphics: - Outlined: Rect, Ellipsis ; LighningFX, Grid ~n
	TileMap: TileMapEngine featuring an Editor~n
	Font: Including a Font~n

#End

#rem
 <The Duke Game Framework. It provides useful little helperfunctions and class to develope 2D Games with Monkey X>
    Copyright (C) 2014-2015  Stephan Duckerschein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 #end

#rem
	The main Aim is to provide a wideranged kit for developing games with Monkey X.
	It tries to be as lightweight as possible.
	And it should be usable without changeging the mojo framework.

	Features:
		DebugSystem: It tracks all used Elements from Maniac within the DebugClass.
		So you can easily monitor your Objects.
#end

#rem
	Importing the Module-Parts of the maniac Framework.
#end

Import maniacLowLevel			'325		364
Import maniacFont				'249
Import maniacDebug				'334
Import maniacGraphics			'686		763
Import maniacMisc				'248
Import maniacSimpleGUI			'1214		1515
Import maniacTween				'667
Import maniacMap				'168

#rem
	These are all global accessable Objects to your project.They will be initialised automatically within the initManiac() Method.
#end
Global MANIAC_FONT:ManiacFont
Global MANIAC_IMG_LOGO:Image
Global MANIAC_IMG_STAR:Image
Global MANIAC_IMG_STARBLUR:Image
Global MANIAC_IMG_BACKGROUND:Image
Global MANIAC_IMG_FRAME_RAW:Image 		'
Global MANIAC_IMG_FRAME_BLUR:Image
Global MANIAC_IMG_SLIDERLINE:Image
Global MANIAC_IMG_SLIDERPICKER:Image
Global MANIAC_IMG_EDITICON:Image
Global MANIAC_IMG_CHECK:Image
Global MANIAC_IMG_DROPDOWN:Image
Global MANIAC_IMG_ARROWDOWN:Image
Global MANIAC_CHARACTERSCOUNT:Int = 30

Const FPSGRAPH_OFF:Int = 0
Const FPSGRAPH_FPS_ONLY:Int = 1
Const FPSGRAPH_GRAPH:Int = 2

Global MANIAC_FPSGRAPH:Maniac_Debug' = New fpsCounter
Global MODULE_INITED_CORRECT:Bool 		'if false, the whole Maniac-Module uses a fallback Drawings-Stuff

Global DW:Float,DH:Float,MX:Float,MY:Float
'Mouse Button States
Global gl_clicked:Bool
Global gl_mousereleased:Bool

Global MANIAC_DEBUG:Bool = False

Global maniac_lastTime:Int
Global maniac_timeScale:Float

#Rem monkeydoc
	This Function Inits this Module.
	It Loads all necessary Images and Sounds and stuff from the lib/ folder.
	if No Images were found, it falls back to a "at least running without any Image" mode. so it just shows up, that there are Graphics missing
#End
Function initManiac(_Debug:Bool = False)
	MANIAC_DEBUG = _Debug
	DW = DeviceWidth()
	DH = DeviceHeight()
	MODULE_INITED_CORRECT = True
	MANIAC_FONT = New ManiacFont(22,27,["lib/font2.png"],[[32,5,27,0,0,0,0,0,0,19],[33,5,27,0,393,46,7,18,-1,4],[34,9,27,0,122,99,10,10,-1,3],[35,15,27,0,51,66,17,17,-1,5],[36,16,27,0,478,0,18,22,-1,2],[37,20,27,0,332,25,21,21,-1,2],[38,16,27,0,34,66,17,17,-1,5],[39,5,27,0,116,99,6,10,-1,3],[40,9,27,0,89,0,11,24,-1,2],[41,9,27,0,78,0,11,24,-1,2],[42,14,27,0,378,46,15,18,-1,4],[43,12,27,0,386,83,14,14,-1,6],[44,6,27,0,109,99,7,10,-1,14],[45,10,27,0,174,99,12,7,-1,10],[46,5,27,0,219,99,6,6,-1,15],[47,12,27,0,366,25,13,21,-1,2],[48,18,27,0,24,83,19,16,-1,5],[49,12,27,0,60,83,14,16,-1,5],[50,14,27,0,171,83,15,15,-1,6],[51,16,27,0,154,83,17,15,-1,6],[52,15,27,0,154,66,17,17,-1,5],[53,15,27,0,138,66,16,17,-1,5],[54,16,27,0,121,66,17,17,-1,5],[55,13,27,0,106,66,15,17,-1,5],[56,15,27,0,89,66,17,17,-1,5],[57,15,27,0,43,83,17,16,-1,6],[58,5,27,0,424,83,6,14,-1,7],[59,6,27,0,68,66,7,17,-1,7],[60,10,27,0,412,83,12,14,-1,7],[61,14,27,0,79,99,16,11,-1,7],[62,10,27,0,400,83,12,14,-1,7],[63,13,27,0,75,66,14,17,-1,5],[64,21,27,0,14,46,22,20,-1,6],[65,17,27,0,461,66,18,17,-1,5],[66,14,27,0,446,66,15,17,-1,5],[67,15,27,0,430,66,16,17,-1,5],[68,15,27,0,414,66,16,17,-1,5],[69,14,27,0,399,66,15,17,-1,5],[70,13,27,0,385,66,14,17,-1,5],[71,15,27,0,369,66,16,17,-1,5],[72,14,27,0,353,66,16,17,-1,5],[73,11,27,0,142,83,12,16,-1,6],[74,15,27,0,126,83,16,16,-1,5],[75,14,27,0,337,66,16,17,-1,5],[76,14,27,0,322,66,15,17,-1,5],[77,17,27,0,304,66,18,17,-1,5],[78,15,27,0,287,66,17,17,-1,5],[79,18,27,0,107,83,19,16,-1,5],[80,15,27,0,416,46,16,18,-1,4],[81,18,27,0,268,66,19,17,-1,5],[82,15,27,0,400,46,16,18,-1,4],[83,16,27,0,250,66,18,17,-1,5],[84,15,27,0,319,83,16,15,-1,6],[85,15,27,0,90,83,17,16,-1,5],[86,16,27,0,233,66,17,17,-1,5],[87,16,27,0,215,66,18,17,-1,5],[88,15,27,0,199,66,16,17,-1,5],[89,14,27,0,184,66,15,17,-1,5],[90,15,27,0,74,83,16,16,-1,5],[91,9,27,0,67,0,11,24,-1,2],[92,12,27,0,353,25,13,21,-1,2],[93,9,27,0,56,0,11,24,-1,2],[94,12,27,0,26,99,13,12,-1,2],[95,15,27,0,203,99,16,6,-1,20],[96,7,27,0,141,99,8,9,-1,3],[97,14,27,0,304,83,15,15,-1,7],[98,12,27,0,287,46,13,19,-1,3],[99,12,27,0,472,83,13,14,-1,7],[100,12,27,0,70,46,14,20,-1,2],[101,13,27,0,290,83,14,15,-1,7],[102,12,27,0,274,46,13,19,-1,3],[103,13,27,0,260,46,14,19,-1,7],[104,13,27,0,246,46,14,19,-1,3],[105,5,27,0,239,46,7,19,-1,3],[106,5,27,0,315,0,7,23,-1,3],[107,12,27,0,56,46,14,20,-1,2],[108,5,27,0,50,46,6,20,-1,2],[109,16,27,0,272,83,18,15,-1,7],[110,13,27,0,258,83,14,15,-1,7],[111,12,27,0,458,83,14,14,-1,7],[112,12,27,0,36,46,14,20,-1,7],[113,13,27,0,225,46,14,19,-1,7],[114,10,27,0,246,83,12,15,-1,7],[115,13,27,0,232,83,14,15,-1,7],[116,12,27,0,171,66,13,17,-1,4],[117,12,27,0,218,83,14,15,-1,7],[118,13,27,0,443,83,15,14,-1,7],[119,16,27,0,200,83,18,15,-1,7],[120,13,27,0,186,83,14,15,-1,7],[121,13,27,0,211,46,14,19,-1,7],[122,12,27,0,430,83,13,14,-1,8],[123,12,27,0,28,0,14,25,-1,2],[124,5,27,0,309,0,6,23,-1,3],[125,12,27,0,14,0,14,25,-1,2],[126,15,27,0,157,99,17,8,-1,10],[127,13,27,0,0,46,14,20,-1,3],[161,5,27,0,371,46,7,18,-1,9],[162,12,27,0,465,0,13,22,-1,3],[163,14,27,0,18,66,16,17,-1,5],[164,16,27,0,0,66,18,17,-1,4],[165,14,27,0,481,46,15,17,-1,5],[166,5,27,0,303,0,6,23,-1,3],[167,13,27,0,317,25,15,21,-1,5],[168,9,27,0,192,99,11,6,-1,5],[169,21,27,0,189,46,22,19,-1,5],[170,13,27,0,65,99,14,11,-1,5],[171,17,27,0,368,83,18,14,-1,7],[172,12,27,0,95,99,14,10,-1,10],[174,21,27,0,167,46,22,19,-1,5],[176,12,27,0,52,99,13,11,-1,4],[177,13,27,0,357,46,14,18,-1,4],[178,12,27,0,0,99,13,13,-1,4],[179,12,27,0,13,99,13,12,-1,5],[180,8,27,0,132,99,9,9,-1,3],[181,14,27,0,152,46,15,19,-1,7],[182,18,27,0,297,25,20,21,-1,4],[183,5,27,0,186,99,6,6,-1,10],[184,7,27,0,149,99,8,8,-1,17],[185,7,27,0,498,83,8,13,-1,5],[186,11,27,0,39,99,13,11,-1,5],[187,17,27,0,350,83,18,14,-1,7],[188,17,27,0,278,25,19,21,-1,2],[189,18,27,0,259,25,19,21,-1,2],[190,18,27,0,239,25,20,21,-1,2],[191,13,27,0,467,46,14,17,-1,10],[192,17,27,0,285,0,18,23,-1,-1],[193,17,27,0,267,0,18,23,-1,-1],[194,17,27,0,249,0,18,23,-1,-1],[195,17,27,0,447,0,18,22,-1,0],[196,17,27,0,221,25,18,21,-1,1],[197,17,27,0,231,0,18,23,-1,-1],[198,22,27,0,0,83,24,16,-1,6],[199,15,27,0,486,25,16,20,-1,5],[200,14,27,0,216,0,15,23,-1,-1],[201,14,27,0,201,0,15,23,-1,-1],[202,14,27,0,186,0,15,23,-1,-1],[203,14,27,0,206,25,15,21,-1,1],[204,11,27,0,174,0,12,23,-1,-1],[205,11,27,0,162,0,12,23,-1,-1],[206,12,27,0,148,0,14,23,-1,-1],[207,11,27,0,194,25,12,21,-1,1],[208,17,27,0,448,46,19,17,-1,5],[209,15,27,0,430,0,17,22,-1,0],[210,18,27,0,411,0,19,22,-1,-1],[211,18,27,0,392,0,19,22,-1,-1],[212,18,27,0,373,0,19,22,-1,-1],[213,18,27,0,175,25,19,21,-1,0],[214,18,27,0,467,25,19,20,-1,1],[215,12,27,0,485,83,13,13,-1,7],[216,18,27,0,129,0,19,23,-1,2],[217,15,27,0,356,0,17,22,-1,-1],[218,15,27,0,339,0,17,22,-1,-1],[219,15,27,0,322,0,17,22,-1,-1],[220,15,27,0,450,25,17,20,-1,1],[221,14,27,0,114,0,15,23,-1,-1],[222,14,27,0,432,46,16,17,-1,5],[223,14,27,0,342,46,15,18,-1,4],[224,14,27,0,160,25,15,21,-1,1],[225,14,27,0,145,25,15,21,-1,1],[226,14,27,0,130,25,15,21,-1,1],[227,14,27,0,435,25,15,20,-1,2],[228,14,27,0,137,46,15,19,-1,3],[229,14,27,0,115,25,15,21,-1,1],[230,21,27,0,479,66,23,16,-1,6],[231,12,27,0,329,46,13,18,-1,7],[232,13,27,0,101,25,14,21,-1,1],[233,13,27,0,87,25,14,21,-1,1],[234,13,27,0,72,25,15,21,-1,1],[235,13,27,0,123,46,14,19,-1,3],[236,7,27,0,64,25,8,21,-1,1],[237,8,27,0,55,25,9,21,-1,1],[238,11,27,0,42,25,13,21,-1,1],[239,9,27,0,112,46,11,19,-1,3],[240,14,27,0,314,46,15,18,-1,3],[241,13,27,0,421,25,14,20,-1,2],[242,12,27,0,407,25,14,20,-1,1],[243,12,27,0,393,25,14,20,-1,1],[244,12,27,0,379,25,14,20,-1,1],[245,12,27,0,98,46,14,19,-1,2],[246,12,27,0,300,46,14,18,-1,3],[247,14,27,0,335,83,15,14,-1,5],[248,12,27,0,28,25,14,21,-1,4],[249,12,27,0,14,25,14,21,-1,1],[250,12,27,0,0,25,14,21,-1,1],[251,12,27,0,496,0,14,21,-1,1],[252,12,27,0,84,46,14,19,-1,3],[253,13,27,0,0,0,14,25,-1,1],[254,12,27,0,42,0,14,24,-1,3],[255,13,27,0,100,0,14,23,-1,3]])
	MANIAC_IMG_BACKGROUND = LoadImage("lib/Hintergrund.png")
	MANIAC_IMG_STAR = LoadImage("lib/star.png")
	MANIAC_IMG_LOGO = LoadImage("lib/logo.png")
	MANIAC_IMG_FRAME_RAW = LoadImage("lib/Frame_raw2.png",1,Image.MidHandle)
	MANIAC_IMG_FRAME_BLUR = LoadImage("lib/Frame_blur.png",1,Image.MidHandle)
	MANIAC_IMG_EDITICON = LoadImage("lib/ico_edit.png")
	MANIAC_IMG_SLIDERLINE = LoadImage("lib/Slider_Line.png")
	MANIAC_IMG_SLIDERPICKER = LoadImage("lib/Slider_Picker.png",1,Image.MidHandle)
	MANIAC_IMG_CHECK = LoadImage("lib/ico_check.png")
	MANIAC_IMG_DROPDOWN = LoadImage("lib/ico_dropdown.png")
	MANIAC_IMG_ARROWDOWN = LoadImage("lib/ico_arrowdown.png")

	If MANIAC_DEBUG = True
		MANIAC_FPSGRAPH = New Maniac_Debug(DW*0.2,DH*0.8,DW*0.65,DH*0.19)
	Endif
	If MANIAC_FONT = Null
		Print "Found no Font Data"
		MODULE_INITED_CORRECT = False
	Endif
	If MANIAC_IMG_FRAME_RAW = Null
		Print "Found no Raw Frame Data"
		MODULE_INITED_CORRECT = False
	Endif
	If MANIAC_IMG_FRAME_BLUR = Null
		Print "Found no blurred Frame Data"
		MODULE_INITED_CORRECT = False
	Endif
	If MANIAC_IMG_EDITICON = Null
		Print "Found no Edit_Icon"
		MODULE_INITED_CORRECT = False
	Endif
	If MANIAC_FPSGRAPH = Null
		Print "Couldnt create an FPS Graph"
		MODULE_INITED_CORRECT = False
	Endif

End Function

#Rem monkeydoc
	This Function should called on every Update() MEthod within your App.
	It keeps some important states of the ManiacModule active
#End
Function maniacUpdate()
	UpdateAsyncEvents()
	If MANIAC_DEBUG = True
		Maniac_Debug.addCall()
	Endif

	MX = MouseX()
	MY = MouseY()

	Maniac_CheckMouseState()

	ll_UpdateSpeeds()
End Function

Function maniacSetDebug(b:Bool = True)
	MANIAC_DEBUG = b
End Function


Friendly enumerator (skip nulls)

Friendly enumerator (skip nulls)

#rem
	header:This module contains the FlxGroup class
#end
Strict

Import reflection

Import flxextern
Import flxbasic
Import flxobject
Import flxu
Import system.flxarray

#Rem
summary:This is an organizational class that can update and render a bunch of FlxBasics.
[i][b]NOTE:[/b] Although FlxGroup extends [a flxbasic.monkey.html]FlxBasic[/a], it will not automatically add itself to the global collisions quad tree, it will only add its members.[/i]
#End
Class FlxGroup Extends FlxBasic

	Global ClassObject:Object

	#Rem
	summary:See detail.
	Use with [a #Sort]Sort()[/a] to sort in ascending order.
	#End
	Const ASCENDING:Bool = False

	#Rem
	summary:See detail.
	Use with [a #Sort]Sort()[/a] to sort in descending order.
	#End
	Const DESCENDING:Bool = True

Private

	Field _maxSize:Int

	Field _marker:Int

	Field _length:Int

	Field _members:FlxBasic[]

	Field _comparators:StringMap<Comparator>

	Field _comparator:Comparator

	Field _sortDescending:Bool

	Field _enumerator:Enumerator

Public
	#Rem
	summary:Constructor
	Params:
	[list]
	[*]maxSize:Int - the maximum capacity of this group.
	[/list]
	#End
	Method New(maxSize:Int = 0)
		Super.New()
		_maxSize = maxSize
		_marker = 0
		_length = 0
		_cameras = Null
		_comparators = New StringMap<Comparator>()
		_enumerator = New Enumerator(Null)
	End Method

	#Rem
	summary:The number of entries in the members array.
	For performance and safety you should check this variable instead of members.length unless you really know what you're doing!
	#End
	Method Length:Int() Property
		Return _length
	End Method

	#Rem
	summary:See detail.
	Array of all the [a flxbasic.monkey.html]FlxBasic[/a]s that exist in this group.
	#End
	Method Members:FlxBasic[]() Property
		Return _members
	End Method

	#Rem
	summary:Override this function to handle any deleting or "shutdown" type operations you might need,such as removing traditional Monkey/Mojo children like Images objects.
	#End
	Method Destroy:Void()
		Local basic:FlxBasic
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) basic.Destroy()
			i+=1
		Wend

		_length = 0
		_members = _members.Resize(_length)
		_cameras = Null

		If (_comparator <> Null) Then
			_comparator.Clear()
			_comparator = Null
		End If

		_comparators.Clear()
		_comparators = Null

		Super.Destroy()
	End Method

	#Rem
	summary:Just making sure we don't increment the active objects count.
	#End
	Method PreUpdate:Void()

	End Method

	#Rem
	summary:Automatically goes through and calls update on everything you added.
	#End
	Method Update:Void()
		Local basic:FlxBasic
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists And basic.active) Then
				basic.PreUpdate()
				basic.Update()
				If (basic.HasTween) basic.UpdateTweens()
				basic.PostUpdate()
			End If
			i+=1
		Wend

		If (HasTween) UpdateTweens()
	End Method

	#Rem
	summary:Automatically goes through and calls render on everything you added.
	#End
	Method Draw:Void()
		If (_cameras <> Null And Not _cameras.Contains(FlxG._CurrentCamera.ID)) Return

		Local basic:FlxBasic
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists And basic.visible) basic.Draw()
			i+=1
		Wend
	End Method

	#Rem
	summary:The maximum capacity of this group.  Default is 0, meaning no max capacity, and the group can just grow.
	#End
	Method MaxSize:Int() Property
		Return _maxSize
	End Method

	Method MaxSize:Void(size:Int) Property
		_maxSize = size

		If (_marker >= _maxSize) _marker = 0
		If (_maxSize = 0 Or _maxSize >= _length) Return

		Local basic:FlxBasic
		Local i:Int = _maxSize
		Local l:Int = _length

		While(i < l)
			basic = _members[i]
			If (basic <> Null) basic.Destroy()
			i+=1
		Wend

		_members = _members.Resize(_maxSize)
		_length = _maxSize
	End Method

	#Rem
	summary:See details.
	Adds a new [a flxbasic.monkey.html]FlxBasic[/a] subclass ([a flxbasic.monkey.html]FlxBasic[/a], [a flxsprite.monkey.html]FlxSprite[/a], Enemy, etc) to the group. FlxGroup will try to replace a null member of the array first. Failing that, FlxGroup will add it to the end of the member array, assuming there is room for it, and doubling the size of the array if necessary.

	[b]WARNING[/b]: If the group has a maxSize that has already been met, the object will NOT be added to the group!

	Params:
	[list]
	[*][a flxbasic.monkey.html]object:FlxBasic[/a] - the object you want to add to the group.
	[/list]
	Return the same [a flxbasic.monkey.html]FlxBasic[/a] object that was passed in.
	#End
	Method Add:FlxBasic(object:FlxBasic)
		If (_IndexOf(object) >= 0) Return object

		Local i:Int = 0

		While (i < _length)
			If (_members[i] = Null) Then
				_members[i] = object
				If (i >= _length) _length = i+1
				Return object
			End If
			i+=1
		Wend

		If (_maxSize > 0) Then
			If (_length = _members.Length()) Then
				If (_length >= _maxSize) Then
					Return object
				ElseIf (_length*2 + 10 <= _maxSize)
					_members = _members.Resize(_length*2 + 10)
				Else
					_members = _members.Resize(_maxSize)
				End If
			End if
		Else
			If (_length = _members.Length()) Then
				_members = _members.Resize(_length*2 + 10)
			End If
		End If

		_members[i] = object
		_length+=1

		Return object
	End Method

	#Rem
	summary:Recycling is designed to help you reuse game objects without always re-allocating or "newing" them.
	If you specified a maximum size for this group (like in [a flxemitter.monkey.html]FlxEmitter[/a],then recycle will employ what we're calling "rotating" recycling. Recycle() will first check to see if the group is at capacity yet. If group is not yet at capacity, Recycle() returns a new object. If the group IS at capacity, then Recycle() just returns the next object in line

	If you did NOT specify a maximum size for this group, then Recycle() will employ what we're calling "grow-style" recycling. Recycle() will return either the first object with exists = false, or, finding none, add a new object to the array, doubling the size of the array if necessary.

	[b]WARNING:[/b] If this function needs to create a new object, and no object class was provided, it will return null instead of a valid object!

	Params:
	[list]
	[*]objectClass:FlxClass - the type objectClass implements FlxClass you want to recycle (e.g. FlxSpriteClass, EvilRobotClass, etc). Do NOT "new" the class in the parameter!
	[/list]
	Return a reference to the object that was created. Don't forget to cast it back to the objectClass you want (e.g. myObject = myObjectClass(myGroup.recycle(myObjectClassClass))).
	#End
	Method Recycle:FlxBasic(objectClass:ClassInfo = null)
		If (_maxSize > 0) Then
			If (_length < _maxSize) Then
				If (objectClass = Null) Return Null
				Return Add(FlxBasic(objectClass.NewInstance()))
			Else
				Local basic:FlxBasic = _members[_marker]
				_marker+=1
				If (_marker >= _maxSize) _marker = 0
				Return basic
			End If
		Else
			Local basic:FlxBasic = GetFirstAvailable(objectClass)
			If (basic <> Null) Return basic
			If (objectClass = Null) Return Null
			Return Add(FlxBasic(objectClass.NewInstance()))
		End If
	End Method

	#Rem
	summary:Removes an object from the group.
	Params:
	[list]
	[*][a flxbasic.monkey.html]object:FlxBasic[/a] - The [a flxbasic.monkey.html]FlxBasic[/a] you want to remove.
	[*]splice:Bool - whether the object should be cut from the array entirely or not.
	[/list]
	Return the removed object.
	#End
	Method Remove:FlxBasic(object:FlxBasic, splice:Bool = False)
		Local index:Int = _IndexOf(object)

		If (index < 0) Return Null

		If (splice) Then
			Local i:Int = index
			Local l:Int = _length

			While(i < _length - 1)
				_members[i] = _members[i+1]
				i+=1
			Wend

			_length-=1
		Else
			_members[index] = Null
		End If

		Return object
	End Method

	#Rem
	summary:Replaces an existing [a flxbasic.monkey.html]FlxBasic[/a] with a new one.
	Params:
	[list]
	[*][a flxbasic.monkey.html]oldObject:FlxBasic[/a] - the object you want to replace.
	[*][a flxbasic.monkey.html]newObject:FlxBasic[/a] - the new object you want to use instead.
	[/list]
	Return the new object.
	#End
	Method Replace:FlxBasic(oldObject:FlxBasic, newObject:FlxBasic)
		Local index:Int  = _IndexOf(oldObject)
		If (index < 0) Return Null

		_members[index] = newObject
		Return newObject
	End Method

	#Rem
	summary:Call this function to sort the group according to a particular value and order.
	For example, to sort game objects for Zelda-style overlaps you might call myGroup.Sort(FlxObject.YComparator, FlxGroup.ASCENDING) at the bottom of your [a flxstate.monkey.html]FlxState.Update()[/a] override. To sort all existing objects after a big explosion or bomb attack, you might call myGroup.Sort(FlxBasic.ExistsComparator, FlxGroup.DESCENDING)
	Params:
	[list]
	[*]comparator:FlxBasicComparator - The FlxBasicComparator you want to sort on. Default value is FlxObject.YComparator.
	[*]order:Bool - A FlxGroup constant that defines the sort order. Possible values are ASCENDING and DESCENDING. Default value is ASCENDING.
	[/list]
	Return the new object.
	#End
	Method Sort:Void(index:String = "y", order:Bool = ASCENDING)
		_comparator = _GetComparator(GetFirstNotNull().GetClassInfo().GetField(index))
		If (_comparator = Null) Return

		_sortDescending = order
		_QSort(0, _length - 1)
	End Method

	Method SetAll:Void(variableName:String, value:Object, recurse:Bool = True)
		Local basic:FlxBasic = GetFirstNotNull()
		If (basic = Null) Return

		Local f:FieldInfo = basic.GetClassInfo().GetField(variableName)

		If (f = Null) Then
			_SetAllProperties(variableName, value, recurse)
			Return
		End If

		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (recurse And FlxGroup(basic) <> Null) Then
					FlxGroup(basic).SetAll(variableName, value, recurse)
				Else
					f.SetValue(basic, value)
				End If
			End If
			i+=1
		Wend
	End Method

	Method CallAll:Void(functionName:String, recurse:Bool = True)
		Local basic:FlxBasic = GetFirstNotNull()
		If (basic = Null) Return

		Local m:MethodInfo = basic.GetClassInfo().GetMethod(functionName,[])
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (recurse And FlxGroup(basic) <> Null) Then
					FlxGroup(basic).CallAll(functionName, recurse)
				Else
					m.Invoke(basic,[])
				End If
			End If
			i+=1
		Wend
	End Method

	Method GetFirstAvailable:FlxBasic(objectClass:ClassInfo = null)
		Local basic:FlxBasic
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And Not basic.exists And
					(objectClass = Null Or basic.GetClassInfo().ExtendsClass(objectClass))) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method GetFirstNull:Int()
		Local i:Int = 0

		While(i < _length)
			If (_members[i] = Null) Return i
			i+=1
		Wend

		Return -1
	End Method

	Method GetFirstNotNull:FlxBasic()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method GetFirstExtant:FlxBasic()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method GetFirstAlive:FlxBasic()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists And basic.alive) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method GetFirstDead:FlxBasic()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And Not basic.alive) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method CountLiving:Int()
		Local count:Int = -1
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (count < 0) count = 0
				If (basic.exists And basic.alive) count+=1
			End If
			i+=1
		Wend

		Return count
	End Method

	Method CountDead:Int()
		Local count:Int = -1
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (count < 0) count = 0
				If (Not basic.alive) count+=1
			End If
			i+=1
		Wend

		Return count
	End Method

	Method GetRandom:FlxBasic(startIndex:Int = 0, length:Int = 0)
		If (length = 0) length = _length
		Return FlxArray<FlxBasic>.GetSafeRandom(_members, startIndex, length)
	End Method

	Method Clear:Void()
		_length = 0
	End Method

	Method ReviveAll:Void()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And Not basic.exists) basic.Revive()
			i+=1
		Wend

		Super.Revive()
	End Method

	Method Kill:Void()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists) basic.Kill()
			i+=1
		Wend

		Super.Kill()
	End Method

	Method ObjectEnumerator:Enumerator()
		Return _enumerator._Reset(Self)
	End

Private
	Method _IndexOf:Int(object:FlxBasic)
		Local i:Int = 0

		While(i < _length)
			If (_members[i] = object) Return i
			i+=1
		Wend

		Return -1
	End Method

	Method _QSort:Void(left:Int, right:Int)
		If (right > left) Then
			Local pivot:Int = left + (right-left)/2
			Local newPivot:Int = _DoSort(left, right, pivot)

			_QSort(left, newPivot - 1)
			_QSort(newPivot + 1, right)
		End If
	End Method

	Method _DoSort:Int(left:Int, right:Int, pivot:Int)
		Local basic:FlxBasic = _members[pivot]

		_members[pivot] = _members[right]
		_members[right] = basic

		Local store:Int = left
		Local basicToCompare:FlxBasic
		Local i:Int = left

		While (i < right)
			basicToCompare = _members[i]

			If (basicToCompare = Null Or basic = Null) Then
				If (basicToCompare <> Null And basic = Null) Then
					_members[i] = _members[store]
					_members[store] = basicToCompare
					store+=1
				End If

				i += 1
				Continue
			End If

			If (_sortDescending) Then
				If (_comparator.Compare(basicToCompare, basic) >= 0) Then
					_members[i] = _members[store]
					_members[store] = basicToCompare
					store+=1
				End If
			Else
				If (_comparator.Compare(basicToCompare, basic) <= 0) Then
					_members[i] = _members[store]
					_members[store] = basicToCompare
					store+=1
				End If
			End If

			i+=1
		Wend

		basic = _members[store]
		_members[store] = _members[right]
		_members[right] = basic

		Return store
	End Method

	Method _SetAllProperties:Void(variableName:String, value:Object, recurse:Bool = True)
		Local basic:FlxBasic = GetFirstNotNull()
		If (basic = Null) Return

		Local prop:MethodInfo

		prop = basic.GetClassInfo().GetMethod(variableName,[GetClass(value)])
		If (prop = Null) Return

		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (recurse And FlxGroup(basic) <> Null) Then
					FlxGroup(basic).SetAll(variableName, value, recurse)
				Else
					prop.Invoke(basic,[value])
				End If
			End If
			i+=1
		Wend
	End Method

	Method _GetComparator:Comparator(sortIndex:FieldInfo)
		If (sortIndex = Null) Return Null

		Local key:String = sortIndex.Type.Name

		If (sortIndex.Type.ExtendsClass(FlxU.GetObjectClass())) Then
			key = FlxU.GetObjectClass().Name
		End If

		Local comparator:Comparator = _comparators.Get(key)

		If (comparator = Null) Then
			Select key
				Case FloatClass().Name
					comparator = New FloatComparator()

				Case IntClass().Name
					comparator = New IntComparator()

				Case BoolClass().Name
					comparator = New BoolComparator()

				Case StringClass().Name
					comparator = New StringComparator()

				Default
					comparator = New ObjectComparator()

			End Select

			_comparators.Set(key, comparator)
		End If

		comparator.Clear()

		If (key <> FlxU.GetObjectClass().Name) Then
			comparator.Reset(sortIndex)
		Else
			Local sortMethod:MethodInfo = sortIndex.Type.GetMethod("Compare",[sortIndex.Type])
			If (sortMethod = Null) sortMethod = sortIndex.Type.GetMethod("Compare",[FlxU.GetObjectClass()])

			If (sortMethod <> Null) Then
				comparator.Reset(sortIndex, sortMethod)
			Else
				comparator = Null
			End If
		End If

		Return comparator
	End Method

End Class

Class Enumerator

	Method New(group:FlxGroup)
		_Reset(group)
	End

	Method HasNext:Bool()
		If (_dirty) Then
			_dirty = False
			_hasNext = False
			_nextIndex = _index

			Repeat
				If (_nextIndex = _group._length) Then
					Return _hasNext
				End If

				_basic = _group._members[_nextIndex]

				_nextIndex += 1
			Until (_basic <> Null)

			_hasNext = True
		End If

		Return _hasNext
	End

	Method NextObject:FlxBasic()
		If ( Not HasNext()) Return Null

		_dirty = True
		_index = _nextIndex
		Return _basic
	End

Private

	Field _group:FlxGroup

	Field _index:Int

	Field _nextIndex:Int

	Field _hasNext:Bool

	Field _dirty:Bool

	Field _basic:FlxBasic

	Method _Reset:Enumerator(group:FlxGroup)
		_group = group
		_index = 0
		_nextIndex = 0
		_hasNext = False
		_dirty = True

		Return Self
	End Method

End

Private

Class Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic) Abstract

	Method Reset:Comparator(sortIndex:FieldInfo, sortMethod:MethodInfo = Null)
		_sortIndex = sortIndex
		_sortMethod = sortMethod

		Return Self
	End Method

	Method Clear:Void()
		_sortIndex = Null
		_sortMethod = Null
	End Method

Private

	Field _sortIndex:FieldInfo

	Field _sortMethod:MethodInfo

End Class

Class BoolComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return Int(UnboxBool(_sortIndex.GetValue(basic1))) - Int(UnboxBool(_sortIndex.GetValue(basic2)))
	End Method

End Class

Class IntComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return UnboxInt(_sortIndex.GetValue(basic1)) - UnboxInt(_sortIndex.GetValue(basic2))
	End Method

End Class

Class FloatComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return UnboxFloat(_sortIndex.GetValue(basic1)) - UnboxFloat(_sortIndex.GetValue(basic2))
	End Method

End Class

Class StringComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return UnboxString(_sortIndex.GetValue(basic1)).Compare(UnboxString(_sortIndex.GetValue(basic2)))
	End Method

End Class

Class ObjectComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return UnboxInt(_sortMethod.Invoke(_sortIndex.GetValue(basic1),[_sortIndex.GetValue(basic2)]))
	End Method

End Class

#Rem
footer:Flixel is an open source game-making library that is completely free for personal or commercial use.
[quote]Copyright: Flixel - 2009-2011 Adam 'Atomic' Saltsman
Copyright: Monkey port - 2011 Arthur 'devolonter' Bikmullin

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

NOTE FROM THE AUTHOR: As far as I know, you only have to include
this license if you are redistributing source code that includes
the Flixel library.  There is no need (or way, afaik) to include
it in your compiled flash games and apps![/quote]
#End

#rem
	header:This module contains the FlxGroup class
#end
Strict

Import reflection

Import flxextern
Import flxbasic
Import flxobject
Import flxu
Import system.flxarray

#Rem
summary:This is an organizational class that can update and render a bunch of FlxBasics.
[i][b]NOTE:[/b] Although FlxGroup extends [a flxbasic.monkey.html]FlxBasic[/a], it will not automatically add itself to the global collisions quad tree, it will only add its members.[/i]
#End
Class FlxGroup Extends FlxBasic

	Global ClassObject:Object

	#Rem
	summary:See detail.
	Use with [a #Sort]Sort()[/a] to sort in ascending order.
	#End
	Const ASCENDING:Bool = False

	#Rem
	summary:See detail.
	Use with [a #Sort]Sort()[/a] to sort in descending order.
	#End
	Const DESCENDING:Bool = True

Private

	Field _maxSize:Int

	Field _marker:Int

	Field _length:Int

	Field _members:FlxBasic[]

	Field _comparators:StringMap<Comparator>

	Field _comparator:Comparator

	Field _sortDescending:Bool

	Field _enumerator:Enumerator

Public
	#Rem
	summary:Constructor
	Params:
	[list]
	[*]maxSize:Int - the maximum capacity of this group.
	[/list]
	#End
	Method New(maxSize:Int = 0)
		Super.New()
		_maxSize = maxSize
		_marker = 0
		_length = 0
		_cameras = Null
		_comparators = New StringMap<Comparator>()
		_enumerator = New Enumerator(Null)
	End Method

	#Rem
	summary:The number of entries in the members array.
	For performance and safety you should check this variable instead of members.length unless you really know what you're doing!
	#End
	Method Length:Int() Property
		Return _length
	End Method

	#Rem
	summary:See detail.
	Array of all the [a flxbasic.monkey.html]FlxBasic[/a]s that exist in this group.
	#End
	Method Members:FlxBasic[]() Property
		Return _members
	End Method

	#Rem
	summary:Override this function to handle any deleting or "shutdown" type operations you might need,such as removing traditional Monkey/Mojo children like Images objects.
	#End
	Method Destroy:Void()
		Local basic:FlxBasic
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) basic.Destroy()
			i+=1
		Wend

		_length = 0
		_members = _members.Resize(_length)
		_cameras = Null

		If (_comparator <> Null) Then
			_comparator.Clear()
			_comparator = Null
		End If

		_comparators.Clear()
		_comparators = Null

		Super.Destroy()
	End Method

	#Rem
	summary:Just making sure we don't increment the active objects count.
	#End
	Method PreUpdate:Void()

	End Method

	#Rem
	summary:Automatically goes through and calls update on everything you added.
	#End
	Method Update:Void()
		Local basic:FlxBasic
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists And basic.active) Then
				basic.PreUpdate()
				basic.Update()
				If (basic.HasTween) basic.UpdateTweens()
				basic.PostUpdate()
			End If
			i+=1
		Wend

		If (HasTween) UpdateTweens()
	End Method

	#Rem
	summary:Automatically goes through and calls render on everything you added.
	#End
	Method Draw:Void()
		If (_cameras <> Null And Not _cameras.Contains(FlxG._CurrentCamera.ID)) Return

		Local basic:FlxBasic
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists And basic.visible) basic.Draw()
			i+=1
		Wend
	End Method

	#Rem
	summary:The maximum capacity of this group.  Default is 0, meaning no max capacity, and the group can just grow.
	#End
	Method MaxSize:Int() Property
		Return _maxSize
	End Method

	Method MaxSize:Void(size:Int) Property
		_maxSize = size

		If (_marker >= _maxSize) _marker = 0
		If (_maxSize = 0 Or _maxSize >= _length) Return

		Local basic:FlxBasic
		Local i:Int = _maxSize
		Local l:Int = _length

		While(i < l)
			basic = _members[i]
			If (basic <> Null) basic.Destroy()
			i+=1
		Wend

		_members = _members.Resize(_maxSize)
		_length = _maxSize
	End Method

	#Rem
	summary:See details.
	Adds a new [a flxbasic.monkey.html]FlxBasic[/a] subclass ([a flxbasic.monkey.html]FlxBasic[/a], [a flxsprite.monkey.html]FlxSprite[/a], Enemy, etc) to the group. FlxGroup will try to replace a null member of the array first. Failing that, FlxGroup will add it to the end of the member array, assuming there is room for it, and doubling the size of the array if necessary.

	[b]WARNING[/b]: If the group has a maxSize that has already been met, the object will NOT be added to the group!

	Params:
	[list]
	[*][a flxbasic.monkey.html]object:FlxBasic[/a] - the object you want to add to the group.
	[/list]
	Return the same [a flxbasic.monkey.html]FlxBasic[/a] object that was passed in.
	#End
	Method Add:FlxBasic(object:FlxBasic)
		If (_IndexOf(object) >= 0) Return object

		Local i:Int = 0

		While (i < _length)
			If (_members[i] = Null) Then
				_members[i] = object
				If (i >= _length) _length = i+1
				Return object
			End If
			i+=1
		Wend

		If (_maxSize > 0) Then
			If (_length = _members.Length()) Then
				If (_length >= _maxSize) Then
					Return object
				ElseIf (_length*2 + 10 <= _maxSize)
					_members = _members.Resize(_length*2 + 10)
				Else
					_members = _members.Resize(_maxSize)
				End If
			End if
		Else
			If (_length = _members.Length()) Then
				_members = _members.Resize(_length*2 + 10)
			End If
		End If

		_members[i] = object
		_length+=1

		Return object
	End Method

	#Rem
	summary:Recycling is designed to help you reuse game objects without always re-allocating or "newing" them.
	If you specified a maximum size for this group (like in [a flxemitter.monkey.html]FlxEmitter[/a],then recycle will employ what we're calling "rotating" recycling. Recycle() will first check to see if the group is at capacity yet. If group is not yet at capacity, Recycle() returns a new object. If the group IS at capacity, then Recycle() just returns the next object in line

	If you did NOT specify a maximum size for this group, then Recycle() will employ what we're calling "grow-style" recycling. Recycle() will return either the first object with exists = false, or, finding none, add a new object to the array, doubling the size of the array if necessary.

	[b]WARNING:[/b] If this function needs to create a new object, and no object class was provided, it will return null instead of a valid object!

	Params:
	[list]
	[*]objectClass:FlxClass - the type objectClass implements FlxClass you want to recycle (e.g. FlxSpriteClass, EvilRobotClass, etc). Do NOT "new" the class in the parameter!
	[/list]
	Return a reference to the object that was created. Don't forget to cast it back to the objectClass you want (e.g. myObject = myObjectClass(myGroup.recycle(myObjectClassClass))).
	#End
	Method Recycle:FlxBasic(objectClass:ClassInfo = null)
		If (_maxSize > 0) Then
			If (_length < _maxSize) Then
				If (objectClass = Null) Return Null
				Return Add(FlxBasic(objectClass.NewInstance()))
			Else
				Local basic:FlxBasic = _members[_marker]
				_marker+=1
				If (_marker >= _maxSize) _marker = 0
				Return basic
			End If
		Else
			Local basic:FlxBasic = GetFirstAvailable(objectClass)
			If (basic <> Null) Return basic
			If (objectClass = Null) Return Null
			Return Add(FlxBasic(objectClass.NewInstance()))
		End If
	End Method

	#Rem
	summary:Removes an object from the group.
	Params:
	[list]
	[*][a flxbasic.monkey.html]object:FlxBasic[/a] - The [a flxbasic.monkey.html]FlxBasic[/a] you want to remove.
	[*]splice:Bool - whether the object should be cut from the array entirely or not.
	[/list]
	Return the removed object.
	#End
	Method Remove:FlxBasic(object:FlxBasic, splice:Bool = False)
		Local index:Int = _IndexOf(object)

		If (index < 0) Return Null

		If (splice) Then
			Local i:Int = index
			Local l:Int = _length

			While(i < _length - 1)
				_members[i] = _members[i+1]
				i+=1
			Wend

			_length-=1
		Else
			_members[index] = Null
		End If

		Return object
	End Method

	#Rem
	summary:Replaces an existing [a flxbasic.monkey.html]FlxBasic[/a] with a new one.
	Params:
	[list]
	[*][a flxbasic.monkey.html]oldObject:FlxBasic[/a] - the object you want to replace.
	[*][a flxbasic.monkey.html]newObject:FlxBasic[/a] - the new object you want to use instead.
	[/list]
	Return the new object.
	#End
	Method Replace:FlxBasic(oldObject:FlxBasic, newObject:FlxBasic)
		Local index:Int  = _IndexOf(oldObject)
		If (index < 0) Return Null

		_members[index] = newObject
		Return newObject
	End Method

	#Rem
	summary:Call this function to sort the group according to a particular value and order.
	For example, to sort game objects for Zelda-style overlaps you might call myGroup.Sort(FlxObject.YComparator, FlxGroup.ASCENDING) at the bottom of your [a flxstate.monkey.html]FlxState.Update()[/a] override. To sort all existing objects after a big explosion or bomb attack, you might call myGroup.Sort(FlxBasic.ExistsComparator, FlxGroup.DESCENDING)
	Params:
	[list]
	[*]comparator:FlxBasicComparator - The FlxBasicComparator you want to sort on. Default value is FlxObject.YComparator.
	[*]order:Bool - A FlxGroup constant that defines the sort order. Possible values are ASCENDING and DESCENDING. Default value is ASCENDING.
	[/list]
	Return the new object.
	#End
	Method Sort:Void(index:String = "y", order:Bool = ASCENDING)
		_comparator = _GetComparator(GetFirstNotNull().GetClassInfo().GetField(index))
		If (_comparator = Null) Return

		_sortDescending = order
		_QSort(0, _length - 1)
	End Method

	Method SetAll:Void(variableName:String, value:Object, recurse:Bool = True)
		Local basic:FlxBasic = GetFirstNotNull()
		If (basic = Null) Return

		Local f:FieldInfo = basic.GetClassInfo().GetField(variableName)

		If (f = Null) Then
			_SetAllProperties(variableName, value, recurse)
			Return
		End If

		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (recurse And FlxGroup(basic) <> Null) Then
					FlxGroup(basic).SetAll(variableName, value, recurse)
				Else
					f.SetValue(basic, value)
				End If
			End If
			i+=1
		Wend
	End Method

	Method CallAll:Void(functionName:String, recurse:Bool = True)
		Local basic:FlxBasic = GetFirstNotNull()
		If (basic = Null) Return

		Local m:MethodInfo = basic.GetClassInfo().GetMethod(functionName,[])
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (recurse And FlxGroup(basic) <> Null) Then
					FlxGroup(basic).CallAll(functionName, recurse)
				Else
					m.Invoke(basic,[])
				End If
			End If
			i+=1
		Wend
	End Method

	Method GetFirstAvailable:FlxBasic(objectClass:ClassInfo = null)
		Local basic:FlxBasic
		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And Not basic.exists And
					(objectClass = Null Or basic.GetClassInfo().ExtendsClass(objectClass))) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method GetFirstNull:Int()
		Local i:Int = 0

		While(i < _length)
			If (_members[i] = Null) Return i
			i+=1
		Wend

		Return -1
	End Method

	Method GetFirstNotNull:FlxBasic()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method GetFirstExtant:FlxBasic()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method GetFirstAlive:FlxBasic()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists And basic.alive) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method GetFirstDead:FlxBasic()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And Not basic.alive) Return basic
			i+=1
		Wend

		Return Null
	End Method

	Method CountLiving:Int()
		Local count:Int = -1
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (count < 0) count = 0
				If (basic.exists And basic.alive) count+=1
			End If
			i+=1
		Wend

		Return count
	End Method

	Method CountDead:Int()
		Local count:Int = -1
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (count < 0) count = 0
				If (Not basic.alive) count+=1
			End If
			i+=1
		Wend

		Return count
	End Method

	Method GetRandom:FlxBasic(startIndex:Int = 0, length:Int = 0)
		If (length = 0) length = _length
		Return FlxArray<FlxBasic>.GetSafeRandom(_members, startIndex, length)
	End Method

	Method Clear:Void()
		_length = 0
	End Method

	Method ReviveAll:Void()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And Not basic.exists) basic.Revive()
			i+=1
		Wend

		Super.Revive()
	End Method

	Method Kill:Void()
		Local i:Int = 0
		Local basic:FlxBasic

		While(i < _length)
			basic = _members[i]
			If (basic <> Null And basic.exists) basic.Kill()
			i+=1
		Wend

		Super.Kill()
	End Method

	Method ObjectEnumerator:Enumerator()
		Return _enumerator._Reset(Self)
	End

Private
	Method _IndexOf:Int(object:FlxBasic)
		Local i:Int = 0

		While(i < _length)
			If (_members[i] = object) Return i
			i+=1
		Wend

		Return -1
	End Method

	Method _QSort:Void(left:Int, right:Int)
		If (right > left) Then
			Local pivot:Int = left + (right-left)/2
			Local newPivot:Int = _DoSort(left, right, pivot)

			_QSort(left, newPivot - 1)
			_QSort(newPivot + 1, right)
		End If
	End Method

	Method _DoSort:Int(left:Int, right:Int, pivot:Int)
		Local basic:FlxBasic = _members[pivot]

		_members[pivot] = _members[right]
		_members[right] = basic

		Local store:Int = left
		Local basicToCompare:FlxBasic
		Local i:Int = left

		While (i < right)
			basicToCompare = _members[i]

			If (basicToCompare = Null Or basic = Null) Then
				If (basicToCompare <> Null And basic = Null) Then
					_members[i] = _members[store]
					_members[store] = basicToCompare
					store+=1
				End If

				i += 1
				Continue
			End If

			If (_sortDescending) Then
				If (_comparator.Compare(basicToCompare, basic) >= 0) Then
					_members[i] = _members[store]
					_members[store] = basicToCompare
					store+=1
				End If
			Else
				If (_comparator.Compare(basicToCompare, basic) <= 0) Then
					_members[i] = _members[store]
					_members[store] = basicToCompare
					store+=1
				End If
			End If

			i+=1
		Wend

		basic = _members[store]
		_members[store] = _members[right]
		_members[right] = basic

		Return store
	End Method

	Method _SetAllProperties:Void(variableName:String, value:Object, recurse:Bool = True)
		Local basic:FlxBasic = GetFirstNotNull()
		If (basic = Null) Return

		Local prop:MethodInfo

		prop = basic.GetClassInfo().GetMethod(variableName,[GetClass(value)])
		If (prop = Null) Return

		Local i:Int = 0

		While(i < _length)
			basic = _members[i]
			If (basic <> Null) Then
				If (recurse And FlxGroup(basic) <> Null) Then
					FlxGroup(basic).SetAll(variableName, value, recurse)
				Else
					prop.Invoke(basic,[value])
				End If
			End If
			i+=1
		Wend
	End Method

	Method _GetComparator:Comparator(sortIndex:FieldInfo)
		If (sortIndex = Null) Return Null

		Local key:String = sortIndex.Type.Name

		If (sortIndex.Type.ExtendsClass(FlxU.GetObjectClass())) Then
			key = FlxU.GetObjectClass().Name
		End If

		Local comparator:Comparator = _comparators.Get(key)

		If (comparator = Null) Then
			Select key
				Case FloatClass().Name
					comparator = New FloatComparator()

				Case IntClass().Name
					comparator = New IntComparator()

				Case BoolClass().Name
					comparator = New BoolComparator()

				Case StringClass().Name
					comparator = New StringComparator()

				Default
					comparator = New ObjectComparator()

			End Select

			_comparators.Set(key, comparator)
		End If

		comparator.Clear()

		If (key <> FlxU.GetObjectClass().Name) Then
			comparator.Reset(sortIndex)
		Else
			Local sortMethod:MethodInfo = sortIndex.Type.GetMethod("Compare",[sortIndex.Type])
			If (sortMethod = Null) sortMethod = sortIndex.Type.GetMethod("Compare",[FlxU.GetObjectClass()])

			If (sortMethod <> Null) Then
				comparator.Reset(sortIndex, sortMethod)
			Else
				comparator = Null
			End If
		End If

		Return comparator
	End Method

End Class

Class Enumerator

	Method New(group:FlxGroup)
		_group = group
	End

	Method HasNext:Bool()
		Return _index < _group.Length
	End

	Method NextObject:FlxBasic()
		_index+=1
		Return _group.Members[_index-1]
	End

Private

	Field _group:FlxGroup

	Field _index:Int

	Method _Reset:Enumerator(group:FlxGroup)
		_group = group
		_index = 0

		Return Self
	End Method

End

Private

Class Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic) Abstract

	Method Reset:Comparator(sortIndex:FieldInfo, sortMethod:MethodInfo = Null)
		_sortIndex = sortIndex
		_sortMethod = sortMethod

		Return Self
	End Method

	Method Clear:Void()
		_sortIndex = Null
		_sortMethod = Null
	End Method

Private

	Field _sortIndex:FieldInfo

	Field _sortMethod:MethodInfo

End Class

Class BoolComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return Int(UnboxBool(_sortIndex.GetValue(basic1))) - Int(UnboxBool(_sortIndex.GetValue(basic2)))
	End Method

End Class

Class IntComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return UnboxInt(_sortIndex.GetValue(basic1)) - UnboxInt(_sortIndex.GetValue(basic2))
	End Method

End Class

Class FloatComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return UnboxFloat(_sortIndex.GetValue(basic1)) - UnboxFloat(_sortIndex.GetValue(basic2))
	End Method

End Class

Class StringComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return UnboxString(_sortIndex.GetValue(basic1)).Compare(UnboxString(_sortIndex.GetValue(basic2)))
	End Method

End Class

Class ObjectComparator Extends Comparator

	Method Compare:Int(basic1:FlxBasic, basic2:FlxBasic)
		Return UnboxInt(_sortMethod.Invoke(_sortIndex.GetValue(basic1),[_sortIndex.GetValue(basic2)]))
	End Method

End Class

#Rem
footer:Flixel is an open source game-making library that is completely free for personal or commercial use.
[quote]Copyright: Flixel - 2009-2011 Adam 'Atomic' Saltsman
Copyright: Monkey port - 2011 Arthur 'devolonter' Bikmullin

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

NOTE FROM THE AUTHOR: As far as I know, you only have to include
this license if you are redistributing source code that includes
the Flixel library.  There is no need (or way, afaik) to include
it in your compiled flash games and apps![/quote]
#End


Made the 'Offset' parameter in the second overload of 'SetBuffer' safe to use.