import Painter from "../rendering/Painter";
import Event from "../events/Event";
import DisplayObject from "./DisplayObject";
import Rectangle from "openfl/geom/Rectangle";
import Point from "openfl/geom/Point";
declare namespace starling.display {
	/**
	 * A DisplayObjectContainer represents a collection of display objects.
	 * It is the base class of all display objects that act as a container for other objects. By 
	 * maintaining an ordered list of children, it defines the back-to-front positioning of the 
	 * children within the display tree.
	 * 
	 * <p>A container does not a have size in itself. The width and height properties represent the 
	 * extents of its children. Changing those properties will scale all children accordingly.</p>
	 * 
	 * <p>As this is an abstract class, you can't instantiate it directly, but have to 
	 * use a subclass instead. The most lightweight container class is "Sprite".</p>
	 * 
	 * <strong>Adding and removing children</strong>
	 * 
	 * <p>The class defines methods that allow you to add or remove children. When you add a child, 
	 * it will be added at the frontmost position, possibly occluding a child that was added 
	 * before. You can access the children via an index. The first child will have index 0, the 
	 * second child index 1, etc.</p> 
	 * 
	 * Adding and removing objects from a container triggers non-bubbling events.
	 * 
	 * <ul>
	 * <li><code>Event.ADDED</code>: the object was added to a parent.</li>
	 * <li><code>Event.ADDED_TO_STAGE</code>: the object was added to a parent that is 
	 * connected to the stage, thus becoming visible now.</li>
	 * <li><code>Event.REMOVED</code>: the object was removed from a parent.</li>
	 * <li><code>Event.REMOVED_FROM_STAGE</code>: the object was removed from a parent that 
	 * is connected to the stage, thus becoming invisible now.</li>
	 * </ul>
	 * 
	 * Especially the <code>ADDED_TO_STAGE</code> event is very helpful, as it allows you to 
	 * automatically execute some logic (e.g. start an animation) when an object is rendered the 
	 * first time.
	 * 
	 * @see Sprite
	 * @see DisplayObject
	 *  
	 */
	export class DisplayObjectContainer extends DisplayObject {
		/**
		 *  @private 
		 */
		protected constructor();
		/**
		 *  Disposes the resources of all children. 
		 */
		override dispose(): void;
		/**
		 *  Adds a child to the container. It will be at the frontmost position. 
		 */
		addChild(child: DisplayObject): DisplayObject;
		/**
		 *  Adds a child to the container at a certain index. 
		 */
		addChildAt(child: DisplayObject, index: number): DisplayObject;
		/**
		 *  Removes a child from the container. If the object is not a child, the method returns
		 *      * <code>null</code>. If requested, the child will be disposed right away. 
		 */
		removeChild(child: DisplayObject, dispose?: boolean): DisplayObject;
		/**
		 *  Removes a child at a certain index. The index positions of any display objects above
		 *      * the child are decreased by 1. If requested, the child will be disposed right away. 
		 */
		removeChildAt(index: number, dispose?: boolean): DisplayObject;
		/**
		 *  Removes a range of children from the container (endIndex included). 
		 *      * If no arguments are given, all children will be removed. 
		 */
		removeChildren(beginIndex?: number, endIndex?: number, dispose?: boolean): void;
		/**
		 *  Returns a child object at a certain index. If you pass a negative index,
		 *      * '-1' will return the last child, '-2' the second to last child, etc. 
		 */
		getChildAt(index: number): DisplayObject;
		/**
		 *  Returns a child object with a certain name (non-recursively). 
		 */
		getChildByName(name: string): DisplayObject;
		/**
		 *  Returns the index of a child within the container, or "-1" if it is not found. 
		 */
		getChildIndex(child: DisplayObject): number;
		/**
		 *  Moves a child to a certain index. Children at and after the replaced position move up.
		 */
		setChildIndex(child: DisplayObject, index: number): void;
		/**
		 *  Swaps the indexes of two children. 
		 */
		swapChildren(child1: DisplayObject, child2: DisplayObject): void;
		/**
		 *  Swaps the indexes of two children. 
		 */
		swapChildrenAt(index1: number, index2: number): void;
		/**
		 *  Sorts the children according to a given function (that works just like the sort function
		 *      * of the Vector class). 
		 */
		sortChildren(compareFunction: (arg0: DisplayObject, arg1: DisplayObject) => number): void;
		/**
		 *  Determines if a certain object is a child of the container (recursively). 
		 */
		contains(child: DisplayObject): boolean;
		/**
		 *  @inheritDoc 
		 */
		override getBounds(targetSpace: DisplayObject, out?: Rectangle): Rectangle;
		/**
		 *  @inheritDoc 
		 */
		override hitTest(localPoint: Point): DisplayObject;
		/**
		 *  @inheritDoc 
		 */
		override render(painter: Painter): void;
		/**
		 *  Dispatches an event on all children (recursively). The event must not bubble. 
		 */
		broadcastEvent(event: Event): void;
		/**
		 *  Dispatches an event with the given parameters on all children (recursively). 
		 *      * The method uses an internal pool of event objects to avoid allocations. 
		 */
		broadcastEventWith(eventType: string, data?: any): void;
		/**
		 *  The number of children of this container. 
		 */
		get numChildren(): number;
		/**
		 *  If a container is a 'touchGroup', it will act as a single touchable object.
		 *      * Touch events will have the container as target, not the touched child.
		 *      * (Similar to 'mouseChildren' in the classic display list, but with inverted logic.)
		 *      * @default false 
		 */
		get touchGroup(): boolean;
		set touchGroup(value: boolean)
	}
}
export default starling.display.DisplayObjectContainer;