[Checkins] SVN: z3c.reference/trunk/ complete rewrite of imagetool

gerold böhler gerold at reloc.org
Tue Sep 18 05:16:39 EDT 2007


Log message for revision 79732:
  complete rewrite of imagetool

Changed:
  U   z3c.reference/trunk/flash/fla/imagetool.as
  U   z3c.reference/trunk/flash/fla/imagetool.fla
  A   z3c.reference/trunk/flash/src/ascb/
  A   z3c.reference/trunk/flash/src/ascb/util/
  A   z3c.reference/trunk/flash/src/ascb/util/Proxy.as
  A   z3c.reference/trunk/flash/src/com/
  A   z3c.reference/trunk/flash/src/com/gskinner/
  A   z3c.reference/trunk/flash/src/com/gskinner/events/
  A   z3c.reference/trunk/flash/src/com/gskinner/events/GDispatcher.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/
  A   z3c.reference/trunk/flash/src/com/robertpenner/bezier/
  A   z3c.reference/trunk/flash/src/com/robertpenner/bezier/CubicCurve.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Back.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Bounce.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Circ.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Cubic.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Elastic.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Expo.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Linear.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Quad.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Quart.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Quint.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/Sine.as
  A   z3c.reference/trunk/flash/src/com/robertpenner/easing/easing_readme.txt
  A   z3c.reference/trunk/flash/src/de/
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/APCore.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/IAnimationPackage.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Alpha.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Animation.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/AnimationCore.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Bevel.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blink.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blur.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/BlurDuplicate.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorBrightness.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorDodge.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorNegative.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorTransform.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/DropShadow.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Filter.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Glow.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientBevel.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientGlow.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IAnimatable.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IMultiAnimatable.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ISingleAnimatable.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskCore.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskMoveFX.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskScaleFX.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Move.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCubicCurve.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCurve.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnPath.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnQuadCurve.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Parallel.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Rotation.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Scale.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Sequence.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Shake.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Skew.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Timeline.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Trail.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Volume.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Arc.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Burst.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/CubicCurve.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Curve.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/DashLine.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Drawer.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Ellipse.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Gear.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IDrawable.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IOutline.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Line.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Poly.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/QuadCurve.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Rectangle.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/RoundRectangle.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Shape.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/ShapeComposite.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Spiral.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Star.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/SuperShape.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Animator.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/BezierToolkit.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Clip.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorCore.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorFX.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorToolkit.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/FrameTween.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IComposite.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitor.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitorElement.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Pause.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/SingleAnimator.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Text.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TimeTween.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Tween.as
  A   z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TweenAction.as
  A   z3c.reference/trunk/flash/src/de/andre_michelle/
  A   z3c.reference/trunk/flash/src/de/andre_michelle/events/
  A   z3c.reference/trunk/flash/src/de/andre_michelle/events/FrameBasedInterval.as
  A   z3c.reference/trunk/flash/src/de/andre_michelle/events/ImpulsDispatcher.as
  A   z3c.reference/trunk/flash/src/org/
  A   z3c.reference/trunk/flash/src/org/dembicki/
  A   z3c.reference/trunk/flash/src/org/dembicki/Path.as
  A   z3c.reference/trunk/flash/src/org/json/
  A   z3c.reference/trunk/flash/src/org/json/Json.as
  U   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Canvas.as
  U   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Controller.as
  U   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/EditableImage.as
  A   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/EditableImageAttitude.as
  U   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/ImageTool.as
  A   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/MovieclipAttitude.as
  A   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Seam.as
  A   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/SeamDirection.as
  A   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/SeamPoint.as
  A   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Slider.as
  U   z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Viewport.as
  U   z3c.reference/trunk/flash/src/z3c/reference/imagetool/core/FlashvarManager.as
  U   z3c.reference/trunk/src/z3c/reference/browser/resources/imagetool.swf

-=-
Modified: z3c.reference/trunk/flash/fla/imagetool.as
===================================================================
--- z3c.reference/trunk/flash/fla/imagetool.as	2007-09-18 09:01:27 UTC (rev 79731)
+++ z3c.reference/trunk/flash/fla/imagetool.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -1,46 +1,53 @@
-stop();
-
-Stage.align = "LT";
-Stage.scaleMode = "noScale";
-		
-
-// Debug Block Start
-if (System.capabilities.playerType == "External")
-{
-    if (!_level0.url) _level0.url="testimage.jpg";
-    
-    //default values
-    if (!_level0.crop_x) _level0.crop_x = 100;
-    if (!_level0.crop_y) _level0.crop_y = 100;
-    if (!_level0.crop_w) _level0.crop_w = 100;
-    if (!_level0.crop_h) _level0.crop_h = 100;
-    if (!_level0.original_w) _level0.original_w = 600;
-    if (!_level0.original_h) _level0.original_h = 400;
-    //if (!_level0.output_w) _level0.output_w = 200;
-    //if (!_level0.output_h) _level0.output_h = 50;
-    if (!_level0.zoomfactor) _level0.zoomfactor=0.33;
-    if (!_level0.rotation) _level0.rotation=90;
-    _level0.keepAspectRatio = false;
-}
-// Debug Block End
-
-
-// init flashvar manager
-z3c.reference.imagetool.core.FlashvarManager.oneTimeInit();
-
-// create an instance of the z3c Image Tool
-//var tool:z3c.reference.imagetool.baseskin.ImageTool = z3c.reference.imagetool.baseskin.ImageTool(_level0.attachMovie("BaseClip","BaseClip", _level0.getNextHighestDepth()));
-attachMovie("imagetool_mc", "imagetool_mc", getNextHighestDepth())
-
-/*
-tool.setOutputSize(FlashvarManager.get("output_w"), FlashvarManager.get("output_h"));
-tool.setOriginalSize(FlashvarManager.get("original_w"), FlashvarManager.get("original_h"));
-tool.setCrop(FlashvarManager.get("crop_x"), FlashvarManager.get("crop_y"), FlashvarManager.get("crop_w"), FlashvarManager.get("crop_h"));
-tool.setUrl(FlashvarManager.get("url"));
-tool.setRotation(FlashvarManager.get("rotation") * -1); //PIL rotates opposite to flash
-tool.setOutputRatio(FlashvarManager.get("zoomfactor"));
-tool.initialize();
-*/
-
-
-
+/*
+ * imagetool.as - #include file
+ *
+ * parameters:
+ * 
+ * url:                         path to the image to be loaded
+ * crop_x:                      crop start x position
+ * crop_y:                      crop start y position
+ * crop_w:                      crop area width
+ * crop_h:                      crop area height
+ * min_w:                       minimum width the cropped area must have
+ * min_h:                       minimum height the cropped area must have
+ * rotation:                    rotation of the image (0, 90, 180, 270)
+ * presets:                     list of available ratios, passed as json string 
+ *                              example: [{"name": "widescreen", "value": "16:9"}, {"name": "tv", "value": "4:3"}]
+ * 
+ */
+
+
+stop();
+
+Stage.align = "LT";
+Stage.scaleMode = "noScale";
+_focusrect = false;
+
+// Debug Block Start
+if (System.capabilities.playerType == "External")
+{
+    if (!_level0.url) _level0.url="toothbrush.jpg";
+    
+    //default values
+    if (_level0.crop_x == undefined) _level0.crop_x = 1190;
+    if (_level0.crop_y == undefined) _level0.crop_y = 830;
+    if (_level0.crop_w == undefined) _level0.crop_w = 400;
+    if (_level0.crop_h == undefined) _level0.crop_h = 300;
+    if (_level0.rotation == undefined) _level0.rotation = 0;
+    if (_level0.presets == undefined) _level0.presets = '[{"name": "Freehand"}, {"name": "Ratio", "ratio": "4:3"}, {"name": "Output", "output_w": 123, "output_h": 321}, {"name": "Min", "min_w": 222, "min_h": 111}, {"name": "Max", "max_w": 555, "max_h": 444}, {"name": "MinMax", "output_w": 987, "output_h": 654, "max_w": 543, "max_h": 432, "min_w": 432, "min_h": 321}]';
+}
+// Debug Block End
+
+// bugfix for dropdown
+dropdown_mc._lockroot = true;
+dropdown_mc._visible = false;
+dropdown_mc._alpha = 0;
+
+// init flashvar manager
+z3c.reference.imagetool.core.FlashvarManager.collectFlashVars();
+
+// create an instance of the z3c Image Tool
+attachMovie("imagetool_mc", "imagetool_mc", getNextHighestDepth())
+
+// bring dropdown to front
+dropdown_mc.swapDepths(imagetool_mc);
\ No newline at end of file

Modified: z3c.reference/trunk/flash/fla/imagetool.fla
===================================================================
(Binary files differ)

Added: z3c.reference/trunk/flash/src/ascb/util/Proxy.as
===================================================================
--- z3c.reference/trunk/flash/src/ascb/util/Proxy.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/ascb/util/Proxy.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,27 @@
+/**
+* Part of ASCBLibrary
+* <p>
+* @author Joey Lott
+* @see <a href="http://www.person13.com/">Joey Lott</a>
+* @see <a href="http://www.person13.com/ascblibrary/">ASCBLibrary</a>
+*/
+class ascb.util.Proxy {
+
+  public static function create(oTarget:Object, fFunction:Function):Function {
+
+    var aParameters:Array = new Array();
+    for(var i:Number = 2; i < arguments.length; i++) {
+      aParameters[i - 2] = arguments[i];
+    }
+
+    var fProxy:Function = function():Void {
+      var aActualParameters:Array = arguments.concat(aParameters);
+      aActualParameters.push(arguments.callee);
+      fFunction.apply(oTarget, aActualParameters);
+    };
+
+    return fProxy;
+
+  }
+
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/ascb/util/Proxy.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/gskinner/events/GDispatcher.as
===================================================================
--- z3c.reference/trunk/flash/src/com/gskinner/events/GDispatcher.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/gskinner/events/GDispatcher.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,90 @@
+/*
+GDispatcher Beta 2 by Grant Skinner, http://gskinner.com/
+
+Extended by Alex Uhlmann with the approval of Grant Skinner.
+	-support for Macromedia Flex
+	-same dispatching behaviour like mx.events.EventDispatcher.
+
+No documentation is provided with this beta release. Please see
+http://gskinner.com/blog/ for information and documentation.
+
+Please report any bugs, or feature requests to gdispatcher at gskinner.com
+You may NOT re-distribute or sell this code in any form.
+
+The GDispatcher class should be completely interchangeable with the
+mx.events.EventDispatcher class.
+*/
+
+class com.gskinner.events.GDispatcher {
+	static var _instance:GDispatcher = undefined;
+	private var gDispatcher_listeners:Object;
+	
+	static function initialize(p_obj:Object):Void {
+		if (_instance == undefined) { _instance = new GDispatcher; }
+		p_obj.dispatchEvent = _instance.dispatchEvent;
+		p_obj.eventListenerExists = _instance.eventListenerExists;
+		p_obj.addEventListener = _instance.addEventListener;
+		p_obj.removeEventListener = _instance.removeEventListener;
+		p_obj.removeAllEventListeners = _instance.removeAllEventListeners;
+	}
+	
+	// internal function to locate listeners:
+	static function _indexOfListener(p_listeners:Array,p_obj:Object,p_function:String):Number {
+		var l:Number = p_listeners.length;
+		var i:Number = -1;
+		while (++i < l) {
+			var obj:Object = p_listeners[i];
+			if (obj.o == p_obj && obj.f == p_function) { return i; }
+		}
+		return -1;
+	}
+	static function _dispatchEvent(p_dispatchObj:Object,p_listeners:Array,p_eventObj:Object) {
+		var i:String;
+		// trick from MM: fixes problem with users removing items from listeners while it executes.
+		for (i in p_listeners) {
+			var o:Object = p_listeners[i].o;
+			var oType:String = typeof(o);
+			var f:String = p_listeners[i].f;
+			if (oType == "object" || oType == "movieclip") {				
+				if (o.handleEvent != undefined && f == undefined) {
+					o.handleEvent(p_eventObj);
+				} //else {
+					if (f == undefined) { f = p_eventObj.type; }
+					o[f](p_eventObj);
+				//}
+			} else { // function
+				o.apply(p_dispatchObj,[p_eventObj]);
+			}
+		}
+	}
+	
+	// functions used by dispatchers:
+	private function dispatchEvent(p_eventObj:Object):Void {
+		if (p_eventObj.type == "ALL") { return; } // disallow events of type "ALL"
+		if (p_eventObj.target == undefined) { p_eventObj.target = this; }
+		this[p_eventObj.type + "Handler"](p_eventObj);
+		var listeners:Array = gDispatcher_listeners[p_eventObj.type];
+		if (listeners != undefined) { GDispatcher._dispatchEvent(this,listeners,p_eventObj); }
+		listeners = gDispatcher_listeners["ALL"];
+		if (listeners != undefined) { GDispatcher._dispatchEvent(this,listeners,p_eventObj); }
+	}
+	private function eventListenerExists(p_event:String,p_obj:Object,p_function:String):Boolean {
+		return (GDispatcher._indexOfListener(gDispatcher_listeners[p_event],p_obj,p_function) != -1);
+	}
+	private function addEventListener(p_event:String,p_obj:Object,p_function:String):Void {
+		if (gDispatcher_listeners == undefined) { gDispatcher_listeners = {}; _global.ASSetPropFlags(this,gDispatcher_listeners,1); }
+		var listeners:Array = gDispatcher_listeners[p_event];
+		if (listeners == undefined) { gDispatcher_listeners[p_event] = listeners = []; }
+		if (GDispatcher._indexOfListener(listeners,p_obj,p_function) == -1) { listeners.push({o:p_obj,f:p_function}); }
+	}
+	private function removeEventListener(p_event:String,p_obj:Object,p_function:String):Void {
+		var listeners = gDispatcher_listeners[p_event];
+		if (listeners == undefined) { return; }
+		var index:Number = GDispatcher._indexOfListener(listeners,p_obj,p_function);
+		if (index != -1) { listeners.splice(index,1); }
+	}
+	private function removeAllEventListeners(p_event:String):Void {
+		if (p_event == undefined) { delete(gDispatcher_listeners); }
+		else { delete(gDispatcher_listeners[p_event]); }
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/com/gskinner/events/GDispatcher.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/bezier/CubicCurve.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/bezier/CubicCurve.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/bezier/CubicCurve.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,134 @@
+/*
+* Class for drawing cubic bezier curves. 
+* Adapted from bezier_draw_cubic.as and drawing_api_core_extensions.as by Alex Uhlmann. 
+* Approved by Robert Penner.
+* @author Robert Penner, Alex Uhlmann
+* @version 0.3 ALPHA
+* -note that line 92 this.mc.moveTo (p1.x, p1.y); is commented out.
+*/
+class com.robertpenner.bezier.CubicCurve {	
+	
+	private var _xpen:Number;
+	private var _ypen:Number;
+	private var mc:MovieClip;
+
+	public function CubicCurve(mc) {
+		this.mc = mc;
+	}
+
+	private function intersect2Lines(p1:Object, p2:Object, p3:Object, p4:Object):Object {		
+		var x1:Number = p1.x; 
+		var y1:Number = p1.y;
+		var x4:Number = p4.x; 
+		var y4:Number = p4.y;
+		
+		var dx1:Number = p2.x - x1;
+		var dx2:Number = p3.x - x4;
+		if (!(dx1 || dx2)) {
+			return NaN;
+		}
+		
+		var m1:Number = (p2.y - y1) / dx1;
+		var m2:Number = (p3.y - y4) / dx2;
+		
+		if (!dx1) {
+			// infinity
+			return { x:x1,
+				 y:m2 * (x1 - x4) + y4 };
+		
+		} else if (!dx2) {
+			// infinity
+			return { x:x4,
+				 y:m1 * (x4 - x1) + y1 };
+		}
+		var xInt:Number = (-m2 * x4 + y4 + m1 * x1 - y1) / (m1 - m2);
+		var yInt:Number = m1 * (xInt - x1) + y1;
+		return { x:xInt, y:yInt };
+	}
+	
+	private function midLine(a:Object, b:Object):Object {		
+		return { x:(a.x + b.x)/2, y:(a.y + b.y)/2 };
+	}
+	
+	private function bezierSplit(p0:Object, p1:Object, p2:Object, p3:Object):Object {		
+		var m:Function = this.midLine;
+		var p01:Object = m(p0, p1);
+		var p12:Object = m(p1, p2);
+		var p23:Object = m(p2, p3);
+		var p02:Object = m(p01, p12);
+		var p13:Object = m(p12, p23);
+		var p03:Object = m(p02, p13);
+		return {
+			b0:{a:p0,  b:p01, c:p02, d:p03},
+			b1:{a:p03, b:p13, c:p23, d:p3 }  
+		};
+	}
+
+	private function _cBez(a:Object, b:Object, c:Object, d:Object, k:Number):Void {		
+		// find intersection between bezier arms
+		var s:Object = this.intersect2Lines (a, b, c, d);
+		// find distance between the midpoints
+		var dx:Number = (a.x + d.x + s.x * 4 - (b.x + c.x) * 3) * .125;
+		var dy:Number = (a.y + d.y + s.y * 4 - (b.y + c.y) * 3) * .125;
+		// split curve if the quadratic isn't close enough
+		if (dx*dx + dy*dy > k) {
+			var halves:Object = this.bezierSplit (a, b, c, d);
+			var b0:Object = halves.b0; var b1 = halves.b1;
+			// recursive call to subdivide curve
+			this._cBez (a, b0.b, b0.c, b0.d, k);
+			this._cBez (b1.a,  b1.b, b1.c, d,    k);
+		} else {
+			// end recursion by drawing quadratic bezier
+			this.mc.curveTo (s.x, s.y, d.x, d.y);
+			this._xpen = d.x;
+			this._ypen = d.y;
+		}
+	}
+	
+	private function drawBezierPts(p1:Object, p2:Object, p3:Object, p4:Object, tolerance:Number):Void {		
+		if (tolerance == undefined) {
+			tolerance = 5;
+		}
+		//this.mc.moveTo (p1.x, p1.y);
+		this._xpen = p1.x;
+		this._ypen = p1.y;
+		this._cBez (p1, p2, p3, p4, tolerance*tolerance);
+	}
+
+	public function drawBezier(x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number, 
+							x4:Number, y4:Number, tolerance:Number):Void {	
+		
+		this.drawBezierPts ({x:x1, y:y1},
+						{x:x2, y:y2},
+						{x:x3, y:y3},
+						{x:x4, y:y4},
+						tolerance);
+	}
+
+	private function curveToCubic(x1:Number, y1:Number, x2:Number, y2:Number, 
+								x3:Number, y3:Number, tolerance:Number):Void {		
+		
+		if (tolerance == undefined) {
+			tolerance = 5;
+		}
+		this._cBez (
+			{x:this._xpen, y:this._ypen},
+			{x:x1, y:y1},
+			{x:x2, y:y2},
+			{x:x3, y:y3},
+			tolerance*tolerance );
+	}
+
+	private function curveToCubicPts(p1:Object, p2:Object, p3:Object, tolerance:Number):Void {		
+		if (tolerance == undefined) {
+			tolerance = 5;
+		}
+		this._cBez (
+			{x:this._xpen, y:this._ypen},
+			p1, p2, p3, tolerance*tolerance );
+	}
+	
+	public function toString():String {
+		return "com.robertpenner.bezier.CubicCurve";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/bezier/CubicCurve.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Back.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Back.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Back.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,15 @@
+class com.robertpenner.easing.Back {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number, s:Number):Number {
+		if (s == undefined) s = 1.70158;
+		return c*(t/=d)*t*((s+1)*t - s) + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number, s:Number):Number {
+		if (s == undefined) s = 1.70158;
+		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number, s:Number):Number {
+		if (s == undefined) s = 1.70158; 
+		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
+		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Back.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Bounce.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Bounce.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Bounce.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,20 @@
+class com.robertpenner.easing.Bounce {
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		if ((t/=d) < (1/2.75)) {
+			return c*(7.5625*t*t) + b;
+		} else if (t < (2/2.75)) {
+			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
+		} else if (t < (2.5/2.75)) {
+			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
+		} else {
+			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
+		}
+	}
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return c - com.robertpenner.easing.Bounce.easeOut (d-t, 0, c, d) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		if (t < d/2) return com.robertpenner.easing.Bounce.easeIn (t*2, 0, c, d) * .5 + b;
+		else return com.robertpenner.easing.Bounce.easeOut (t*2-d, 0, c, d) * .5 + c*.5 + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Bounce.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Circ.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Circ.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Circ.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,12 @@
+class com.robertpenner.easing.Circ {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
+		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Circ.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Cubic.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Cubic.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Cubic.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,12 @@
+class com.robertpenner.easing.Cubic {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*(t/=d)*t*t + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*((t=t/d-1)*t*t + 1) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		if ((t/=d/2) < 1) return c/2*t*t*t + b;
+		return c/2*((t-=2)*t*t + 2) + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Cubic.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Elastic.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Elastic.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Elastic.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,21 @@
+class com.robertpenner.easing.Elastic {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number, a:Number, p:Number):Number {
+		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;  var s:Number;
+		if (!a || a < Math.abs(c)) { a=c; s=p/4; }
+		else s = p/(2*Math.PI) * Math.asin (c/a);
+		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number, a:Number, p:Number):Number {
+		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;  var s:Number;
+		if (!a || a < Math.abs(c)) { a=c; s=p/4; }
+		else s = p/(2*Math.PI) * Math.asin (c/a);
+		return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number, a:Number, p:Number):Number {
+		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);  var s:Number;
+		if (!a || a < Math.abs(c)) { a=c; s=p/4; }
+		else s = p/(2*Math.PI) * Math.asin (c/a);
+		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Elastic.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Expo.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Expo.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Expo.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,14 @@
+class com.robertpenner.easing.Expo {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		if (t==0) return b;
+		if (t==d) return b+c;
+		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
+		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Expo.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Linear.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Linear.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Linear.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,15 @@
+class com.robertpenner.easing.Linear {
+	static function easeNone (t:Number, b:Number, c:Number, d:Number):Number {
+		var a = c*t/d + b;		
+		return a;
+	}
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*t/d + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*t/d + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*t/d + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Linear.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Quad.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Quad.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Quad.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,12 @@
+class com.robertpenner.easing.Quad {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*(t/=d)*t + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return -c *(t/=d)*(t-2) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		if ((t/=d/2) < 1) return c/2*t*t + b;
+		return -c/2 * ((--t)*(t-2) - 1) + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Quad.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Quart.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Quart.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Quart.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,12 @@
+class com.robertpenner.easing.Quart {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*(t/=d)*t*t*t + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return -c * ((t=t/d-1)*t*t*t - 1) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
+		return -c/2 * ((t-=2)*t*t*t - 2) + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Quart.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Quint.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Quint.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Quint.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,12 @@
+class com.robertpenner.easing.Quint {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*(t/=d)*t*t*t*t + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return c*((t=t/d-1)*t*t*t*t + 1) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
+		return c/2*((t-=2)*t*t*t*t + 2) + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Quint.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/Sine.as
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/Sine.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/Sine.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,11 @@
+class com.robertpenner.easing.Sine {
+	static function easeIn (t:Number, b:Number, c:Number, d:Number):Number {
+		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
+	}
+	static function easeOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return c * Math.sin(t/d * (Math.PI/2)) + b;
+	}
+	static function easeInOut (t:Number, b:Number, c:Number, d:Number):Number {
+		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/Sine.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/com/robertpenner/easing/easing_readme.txt
===================================================================
--- z3c.reference/trunk/flash/src/com/robertpenner/easing/easing_readme.txt	                        (rev 0)
+++ z3c.reference/trunk/flash/src/com/robertpenner/easing/easing_readme.txt	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,37 @@
+============================================================================================
+ Easing Equations v2.0
+ September 1, 2003
+ (c) 2003 Robert Penner, all rights reserved. 
+ This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html.
+============================================================================================
+
+These tweening functions provide different flavors of 
+math-based motion under a consistent API. 
+
+Types of easing:
+
+      Linear
+      Quadratic
+      Cubic
+      Quartic
+      Quintic
+      Sinusoidal
+      Exponential
+      Circular
+      Elastic
+      Back
+      Bounce
+
+Changes:
+2.0 - ported to ActionScript 2.0; functions now in packages and use strong typing
+1.5 - added bounce easing
+1.4 - added elastic and back easing
+1.3 - tweaked the exponential easing functions to make endpoints exact
+1.2 - inline optimizations (changing t and multiplying in one step)--thanks to Tatsuo Kato for the idea
+
+Discussed in Chapter 7 of 
+Robert Penner's Programming Macromedia Flash MX
+(including graphs of the easing equations)
+
+http://www.robertpenner.com/profmx
+http://www.amazon.com/exec/obidos/ASIN/0072223561/robertpennerc-20


Property changes on: z3c.reference/trunk/flash/src/com/robertpenner/easing/easing_readme.txt
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:eol-style
   + native

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/APCore.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/APCore.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/APCore.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,366 @@
+/*
+* AnimationPackage by default uses Grant Skinner's GDispatcher 
+* instead of Macromedia's EventDispatcher. Swop this line 
+* with the line below if you want to use Macromedia's EventDispatcher 
+* instead of GDispatcher. Also swop the initialize method 
+* invocations in APCore.init() at line 91.
+*/
+//import mx.events.EventDispatcher;
+import com.gskinner.events.GDispatcher;
+
+import ascb.util.Proxy;
+import de.alex_uhlmann.animationpackage.IAnimationPackage;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.andre_michelle.events.ImpulsDispatcher;
+
+/**
+* @class APCore
+* @author Alex Uhlmann
+* @description         Most classes in AnimationPackage subclass the singelton APCore, either directly or indirectly.
+*                        It implements listener functionality and common used methods 
+*                        and creates the animationClip (apContainer_mc) in _root timeline, 
+*                        which is a movieclip that contains everything made by AnimationPackage unless you explicitly prevent this.
+* 			For example if you use the classes of de.alex_uhlmann.animationpackage.drawing you are able to specify a movieclip of any timeline 
+* 			that will be used to draw the shape. If you don't specify anything, a new movieclip, created in _root.apContainer_mc will be used to draw the shape.
+*                 
+* @usage     <tt>private class constructor</tt> <p>
+* 			<b>Event handling</b>
+* 			<p>
+* 			There are basically two ways to handle events in AnimationPackage. One way is using callbacks.
+* 			(based on the internal AsBroadcaster)
+* 			The other is using com.gskinner.events.GDispatcher or mx.events.EventDispatcher. 
+* 			Take a look into the readme.htm under "usage" for more information. Since you need the static initialize(), addListener(), 
+* 			and removeListener() methods of APCore to use callbacks, here is an example using the callback structure to handle custom events.
+* 			<p>
+* 			To subscribe an object to events use
+*                 <tt>APCore.addListener(obj);</tt>
+*                i.e. if you want a movieclip to move back and forth, you can do it like:
+*                <blockquote><pre>               
+* 			APCore.initialize();
+* 			var myListener:Object = new Object();
+*			APCore.addListener(myListener);
+*			var myMove:Move = new Move(mc);
+*			myMove.animationStyle(2000,Expo.easeInOut,"onCallback");
+*			myMove.run(500,200);
+*			myListener.onCallback = function()
+*			{
+*				myMove.callback = "onCallback2";
+*				myMove.run(100,200);
+*			}
+*			myListener.onCallback2 = function()
+*			{		
+*				myMove.callback = "onCallback";	
+*				myMove.run(500,200);
+*			}
+*                </pre></blockquote>	
+* 			<a href="APCore_01.html">(Example .swf)</a> 
+* 			<p>
+* 			<b>Controlling your frame rate</b>
+* 			<p>
+* 			APCore offers some methods concerning your movie's frame rate (fps = frames per second). 
+* 			As soon as you use a class of AnimationPackage the APCore.initialize method is called and 
+* 			calculates your movie's fps. This calculation takes one second till it gets the only result. 
+* 			Then, due to performance reasons, the calculation will not be continued. If you still want to calculate your fps 
+* 			you can do so by calling APCore.watchFPS(). Stop watching the fps with APCore.unwatchFPS(). 
+* 			For duration mode "MS" in tween mode "FRAMES" you might even set the fps with APCore.setFPS(). 
+* 			Note, that this will not modify your movie's actual fps (this is not possible with ActionScript). 
+* 			See AnimationCore class and AnimationCore.setDurationMode for details.
+*/
+dynamic class de.alex_uhlmann.animationpackage.APCore 
+											implements IAnimationPackage {       
+	
+	private static var animationClip:MovieClip;
+	private static var apCoreInstance:APCore;
+	private static var apCentralMC:MovieClip;
+	private static var fps:Number = 0;
+	private static var isCalculatingFPS:Boolean = false;
+	private static var instanceCount: Number = 0;
+	private var ID:Number;
+	
+	//EventDispatcher mix-in
+	private var dispatchEvent:Function;
+	public var addEventListener:Function;
+	public var removeEventListener:Function;
+	//EventDispatcher methods used for overriding mix-in
+	private var dispatchEventOrig:Function;
+	private var dispatchEventOverridden:Function;		
+	public var addEventListenerOrig:Function;
+	public var addEventListenerOverridden:Function;
+	public var removeEventListenerOrig:Function;
+	public var removeEventListenerOverridden:Function;
+	//optional GDispatcher mix-in
+	public var eventListenerExists:Function;
+	public var removeAllEventListeners:Function;	
+	//AsBroadcaster
+	public static var addListener:Function;
+	public static var removeListener:Function;
+	public static var broadcastMessage:Function;
+
+	private function APCore() {}
+	
+	private function init():Void {
+		this.ID = ++APCore.instanceCount;
+		if(!arguments[0]) {
+			//this enabled subclasses to overwrite mix-in methods.
+			dispatchEventOverridden = this.dispatchEvent;
+			addEventListenerOverridden = this.addEventListener;
+			removeEventListenerOverridden = this.removeEventListener;
+			
+			//EventDispatcher.initialize(this);
+			GDispatcher.initialize(this);
+			
+			//this enabled subclasses to overwrite mix-in methods.
+			dispatchEventOrig = this.dispatchEvent;
+			addEventListenerOrig = this.addEventListener;
+			removeEventListenerOrig = this.removeEventListener;
+		}
+	}
+	
+	/**
+	* @method APCore.initialize
+	* @description 	static, Initializes AnimationPackage including the internal broadcaster. Every class that needs listener 
+	*				functionality will call this method. Needed if no other class of AnimationPackage that needs 
+	*				listener functionality was constructed before or if you want to access 
+	* 				the only APCore instance (i.e. for getNextDepth() or createClip() methods). APCore is a Singelton [GoF].
+	* @usage   <tt>APCore.initialize();</tt> 	  
+	* @return (APCore) the only instance of APCore. Singelton [GoF]
+	*/
+	/*
+	* initialize listener functionality, create needed container movieclips and calculate the frame rate for one second. 
+	* Singelton [GoF]
+	*/
+	public static function initialize(Void):APCore {		
+		if(APCore.apCoreInstance == null) {			
+			APCore.apCoreInstance = new APCore();
+			AsBroadcaster.initialize(APCore);
+			if (APCore.animationClip == null) {			
+				APCore.setAnimationClip(_root);
+			}
+			APCore.createCentralMC();
+			APCore.calculateFPS();	
+			/*
+			* The Macromedia Flex compiler doesn't understand the assignment 
+			* done in Line 56 of AnimationCore: 
+			* public static var easing_def:Function = Linear.easeNone;
+			* Therefore, I have to assign the full path of Linear.easeNone to 
+			* AnimationCore.easing_def at runtime. Because of performance reasons 
+			* this is done in APCore.
+			*/
+			AnimationCore.easing_def = _global.com.robertpenner.easing.Linear.easeNone;
+		}
+		return APCore.apCoreInstance;
+	}	
+	
+	/**
+	* @method APCore.getAnimationClip
+	* @description 	static, residence of the animationClip. See class documentation and APCore.setAnimationClip.
+	* @usage   <tt>APCore.getAnimationClip(target);</tt>
+	* @return (MovieClip) movieclip in which the apContainer_mc has been created.
+	*/
+	public static function getAnimationClip(Void):MovieClip {
+		return APCore.animationClip;
+	}
+	
+	/**
+	* @method APCore.setAnimationClip
+	* @description 	static, allow to set the timeline for the animationClip (apContainer_mc). Default is _root timeline.
+	*                        The animationClip is a movieclip that contains everything made by AnimationPackage 
+	* 			unless you explicitly prevent this. See class documentation.
+	* @usage   <tt>APCore.setAnimationClip(target);</tt>
+	* @param target (MovieClip) movieclip in which the apContainer_mc will be created.
+	*/
+	public static function setAnimationClip(target:MovieClip):Void {
+		var apCoreInstance:APCore = APCore.apCoreInstance;
+		APCore.animationClip =
+			target.createEmptyMovieClip("apContainer_mc", apCoreInstance.getNextDepth(target));
+		APCore.animationClip.onUnload = 
+			Proxy.create(apCoreInstancee, apCoreInstance.onAnimationClipOverwrite);
+	}
+	
+	private function onAnimationClipOverwrite(Void):Void {
+		trace("ERROR: APCore.animationClip in "+this+" has been overwritten."
+			+" Check your code for any depth overwriting or initialize AP" 
+			+" within a specified Movieclip. See APCore.setAnimationClip.");
+	}
+	
+	private static function createCentralMC(Void):Void {
+		if(APCore.apCentralMC == null) {
+			APCore.apCentralMC = 
+				APCore.animationClip.createEmptyMovieClip("apCentral_mc", 
+					APCore.apCoreInstance.getNextDepth(APCore.animationClip));		
+			ImpulsDispatcher.initialize(APCore.apCentralMC);
+		}		
+	}
+	
+	public static function getCentralMC(Void):MovieClip {
+		return APCore.apCentralMC;
+	}
+	
+	public static function calculateFPS(Void):Void {
+		if(APCore.fps == 0 && APCore.isCalculatingFPS == false) {			
+			APCore.watchFPS();			
+			APCore.addListener(APCore);
+		}
+	}
+	
+	private static function onFPSCalculated(Void):Void {		
+		APCore.unwatchFPS();
+	}
+	
+	private static function checkFPS(Void):Void {
+		var fpsLocal:Number = ImpulsDispatcher.getFPS();
+		if(fpsLocal != 0) {			
+			APCore.fps = fpsLocal;
+			APCore.broadcastMessage("onFPSCalculated", APCore.fps);
+			ImpulsDispatcher.removeImpulsListener(APCore);
+		}
+	}
+	
+	/**
+	* @method APCore.watchFPS
+	* @description 	static, watches your movie's frame rate (fps = frames per second). 
+	* 				Each second it receives a new result.
+	* @usage   <tt>APCore.watchFPS();</tt>
+	*/
+	public static function watchFPS(Void):Void {		
+		if(APCore.isCalculatingFPS == true) {
+			APCore.removeListener(APCore);			
+		} else {			
+			ImpulsDispatcher.watchFPS();
+			ImpulsDispatcher.addImpulsListener(APCore , "checkFPS");
+			APCore.isCalculatingFPS = true;
+		}		
+	}
+	
+	/**
+	* @method APCore.unwatchFPS
+	* @description 	static, stop watching your movie's frame rate (fps = frames per second). 
+	* 				Since watching your fps costs a little performance, I recommend to stop 
+	* 				watching your fps if  you don't need to anymore.
+	* @usage   <tt>APCore.unwatchFPS();</tt>
+	*/
+	public static function unwatchFPS(Void):Void {		
+		APCore.isCalculatingFPS = false;
+		ImpulsDispatcher.unwatchFPS();		
+	}
+
+	/**
+	* @method APCore.getFPS
+	* @description 	static, returns the last calculated value of your movie's frame rate (fps = frames per second). 
+	* @usage   <tt>APCore.getFPS();</tt>
+	* @return Number that specifies the number of frames your movie plays in one second.
+	*/
+	public static function getFPS(Void):Number {		
+		var fpsLocal:Number = ImpulsDispatcher.getFPS();
+		if(fpsLocal == 0 && APCore.fps != 0) {
+			fpsLocal = APCore.fps;
+		}		
+		return fpsLocal;
+	}
+	
+	/**
+	* @method APCore.setFPS
+	* @description 	static, sets the frame rate (fps = frames per second) stored in AnimationPackage.
+	* 			For duration mode "MS" in tween mode "FRAMES" you might set the fps with APCore.setFPS(). 
+	* 			Note, that this will not modify your movie's actual fps (this is not possible with ActionScript). 
+	* 			See AnimationCore class and AnimationCore.setDurationMode for details.
+	* @usage   <tt>APCore.setFPS();</tt>
+	* @param fps_local (Number) that specifies the number of frames your movie plays in one second. (fps)
+	*/
+	public static function setFPS(fps_local:Number):Void {
+		APCore.fps = fps_local;	
+	}
+	
+	/**
+	* @method APCore.milliseconds2frames
+	* @description 	static, converts milliseconds to frames according to the current fps (frames per second) 
+	* 				stored in AnimationPackage.
+	* @usage   <tt>APCore.milliseconds2frames();</tt>
+	* @param ms (Number) milliseconds to convert to frames.
+	* @return Number of frames that are expected to run in one second.
+	*/
+	public static function milliseconds2frames(ms:Number):Number {
+		return Math.round(ms / 1000 * APCore.getFPS());
+	}
+	
+	/*common used methods*/	
+	public function createClip(timelineObj:Object):MovieClip {
+		
+		var mc:MovieClip = timelineObj.mc;
+		var parentMC:MovieClip = timelineObj.parentMC;
+		var name:String =  timelineObj.name;		
+		var x:Number = timelineObj.x;
+		var y:Number = timelineObj.y;
+		/*
+		* Either
+		* -create a new movieclip inside another
+		* -create a new movieclip inside animationClip.
+		* -positions an already created movieclip.
+		*/
+		if(parentMC != null) {
+			mc = this.createMC(parentMC, name);
+		} else if(mc == null) {
+			var containerClip:MovieClip;
+			containerClip = APCore.animationClip;		
+			mc = this.createMC(containerClip, name);
+		}
+		if(x != null && y != null) {		    
+			mc._x = x;
+			mc._y = y;
+		}
+		return mc;
+	}
+	
+	private function createMC(parentMC:MovieClip, name:String):MovieClip {
+		/*Flash Player 7 feature disabled*/
+		//var depth:Number = animationClip.getNextHighestDepth();
+		var depth:Number = this.getNextDepth(parentMC);	
+		return parentMC.createEmptyMovieClip(name+depth+"_mc", depth);
+	}
+	
+	/* Adapted from Fernando Flórez - fernando at onelx.com - www.onelx.com */ 
+	public function getNextDepth(mc:MovieClip):Number {		
+		var t:Number = -Infinity;		
+		var i:String;		
+		for(i in mc){
+			var p:Object = mc[i];
+			if(p.getDepth() != null && p._parent == mc) {
+				t = Math.max(t,p.getDepth());
+			}
+		}	
+		return (t > -1) ? ++t : 0;
+	}
+	
+	/*listener functionality, internal AsBroadcaster is used*/
+	/**
+	* @method APCore.addListener
+	* @description  To subscribe an object to all events from AnimationPackage. 
+	* @usage    <tt>APCore.addListener(obj);</tt>  
+	* @returns   <code>true</code> if subscription was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/*internal AsBroadcaster is used*/
+	/**
+	* @method APCore.removeListener
+	* @description        To unsubscribe an object to all events from AnimationPackage.                
+	* @usage   <tt>APCore.removeListener(obj);</tt>
+	* @returns <code>true</code> if successful, <code>false</code> 
+	*                 if not successful.
+	*/
+	
+	public function getID(Void):Number {
+		return this.ID;
+	}	
+
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	
+	public function toString(Void):String {
+		return "APCore";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/APCore.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/IAnimationPackage.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/IAnimationPackage.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/IAnimationPackage.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,4 @@
+interface de.alex_uhlmann.animationpackage.IAnimationPackage {
+	public function getID(Void):Number;
+	public function toString(Void):String;
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/IAnimationPackage.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Alpha.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Alpha.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Alpha.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,480 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Alpha
+* @author Alex Uhlmann
+* @description
+* 			Manipulates _alpha property of a movieclip or a number of movieclips.<p>		
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing. 
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>			
+*			var myAlpha:Alpha = new Alpha(mc);
+*			myAlpha.animationStyle(1000,Elastic.easeInOut,"onCallback");
+*			myAlpha.run(40);
+*			</pre></blockquote>		
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>
+* 			new Alpha(mc).run(40,1000,Elastic.easeInOut,"onCallback");
+* 			</pre></blockquote>	
+* 			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 			
+* 			<blockquote><pre>
+* 			var myAlpha:Alpha = new Alpha(mc,40,1000,Elastic.easeInOut,"onCallback");
+* 			myAlpha.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValue or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+* 			<blockquote><pre>
+*			var myAlpha:Alpha = new Alpha(mc,[50,0],3000,Sine.easeInOut);
+*			myAlpha.run()
+* 			</pre></blockquote>
+* 			<p> 
+* 			Example 5: To fade a movieclip to 40 _alpha in 1 second using linear easing. 		
+* 			<blockquote><pre>
+*			new Alpha(mc).run(40,1000);
+*			</pre></blockquote> 			
+* 			Example 6: <a href="Alpha_run_02.html">(Example .swf)</a> fade out and fade in. 
+* 			<blockquote><pre>			
+*			new Alpha(mc).run(0,1000,"onCallback");	
+*			myListener.onCallback = function() {
+*				new Alpha(mc).run(100,2000,Back.easeOut);	
+*			}	
+*			</pre></blockquote>
+* 			Example 7: To animate many movieclips the same way, this class also accepts 
+* 			an Array of movieclips instead of one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want to animate. Different 
+* 			start values of your movieclip properties are considered when animating multiple movieclips 
+* 			within one animation instance.
+* 			<blockquote><pre>
+* 			var mcs:Array = new Array(mc1,mc2,mc3);
+* 			mc1._alpha = 60;
+*			var myAlpha:Alpha = new Alpha(mcs);
+*			myAlpha.animationStyle(3000,Elastic.easeInOut);
+*			myAlpha.run(10);
+* 			</pre></blockquote>
+* 
+* @usage      
+* 			<pre>var myAlpha:Alpha = new Alpha(mc);</pre>
+* 			<pre>var myAlpha:Alpha = new Alpha(mc, amount, duration, callback);</pre> 
+* 			<pre>var myAlpha:Alpha = new Alpha(mc, amount, duration, easing, callback);</pre> 
+*			<pre>var myAlpha:Alpha = new Alpha(mc, values);</pre> 
+* 			<pre>var myAlpha:Alpha = new Alpha(mc, values, duration, callback);</pre> 
+* 			<pre>var myAlpha:Alpha = new Alpha(mc, values, duration, easing, callback);</pre> 
+* 			<pre>var myAlpha:Alpha = new Alpha(mcs);</pre>
+* 			<pre>var myAlpha:Alpha = new Alpha(mcs, amount, duration, callback);</pre> 
+* 			<pre>var myAlpha:Alpha = new Alpha(mcs, amount, duration, easing, callback);</pre> 
+*			<pre>var myAlpha:Alpha = new Alpha(mcs, values);</pre> 
+* 			<pre>var myAlpha:Alpha = new Alpha(mcs, values, duration, callback);</pre> 
+* 			<pre>var myAlpha:Alpha = new Alpha(mcs, values, duration, easing, callback);</pre>
+* 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param amount (Number) Targeted amount to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Alpha 
+											extends AnimationCore 
+											implements ISingleAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public var alphaProperty:String = "_alpha";
+	
+	public function Alpha() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function initAnimation(amount:Number, duration:Number, easing:Object, callback:String):Void {		
+		if (arguments.length > 1) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		if(this.mc != null) {
+			this.setStartValue(this.mc[this.alphaProperty], true);	
+		}
+		this.setEndValue(amount);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;		
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = [this.endValue];
+		
+		if(this.mc != null) {
+			this.myAnimator.start = [this.startValue];
+			this.myAnimator.setter = [[this.mc, this.alphaProperty]];
+		} else {			
+			this.myAnimator.multiStart = [this.alphaProperty];										
+			this.myAnimator.multiSetter = [[this.mcs, this.alphaProperty]];			
+		}
+
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}	
+
+	/**
+	* @method run
+	* @description 	Fades a movieclip from its the current _alpha property value 
+	* 			to a specified amount in a specified time and easing equation.
+	* 		
+	* @usage   
+	* 		<pre>myAlpha.run();</pre>
+	* 		<pre>myAlpha.run(amount);</pre>
+	* 		<pre>myAlpha.run(amount, duration);</pre>
+	* 		<pre>myAlpha.run(amount, duration, callback);</pre>
+	*		<pre>myAlpha.run(amount, duration, easing, callback);</pre>
+	* 		<pre>myAlpha.run(values, duration);</pre>
+	* 		<pre>myAlpha.run(values, duration, callback);</pre>
+	*		<pre>myAlpha.run(values, duration, easing, callback);</pre>
+	* 	  
+	* @param amount (Number) Targeted amount to animate to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myAlpha.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	* @param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. 
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. 
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. 
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. 
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. 
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myAlpha.addEventListener(event, listener);</pre>
+	* 		    <pre>myAlpha.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myAlpha.removeEventListener(event, listener);</pre>
+	* 		    <pre>myAlpha.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myAlpha.removeAllEventListeners();</pre>
+	* 		    <pre>myAlpha.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myAlpha.eventListenerExists(event, listener);</pre>
+	* 			<pre>myAlpha.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {		
+		return "Alpha";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Alpha.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Animation.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Animation.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Animation.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,707 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.IAnimatable;
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.IVisitor;
+import de.alex_uhlmann.animationpackage.utility.IVisitorElement;
+import de.alex_uhlmann.animationpackage.utility.IComposite;
+import de.alex_uhlmann.animationpackage.utility.Pause;
+import ascb.util.Proxy;
+
+/**
+* @class Animation
+* @author Alex Uhlmann
+* @description   The Animation class combines Sequence and Parallel to allow overlaps in child animations. 
+* 			You can send start and end values in duration to the addChild method. 
+* 			Animation allows you to animate the classes of 
+* 			de.alex_uhlmann.animationpackage.animation in a sequence and/or parallel in a uniform manner.
+* 			Animation uses the composite design pattern. [GoF]
+* 			<p>
+* 			Example 1: <a href="Animation_01.html">(Example .swf)</a> Animate different animations back and forth.
+* 			Notice the we can send start and end values in duration to the addChild method. If we don't specify start 
+* 			and end parameters, the child's duration will match the duration specified to Animation.
+* 			<pre><blockquote> 
+*			var myMoveOnQuadCurve:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,300,300,500,100);
+*			var myScale:Scale = new Scale(mc,25,25);
+*			var myRotation:Rotation = new Rotation(mc,360);
+*			var myColorTransform:ColorTransform = new ColorTransform(mc,0xff0000,50);
+*			
+*			var myAnimation:Animation = new Animation();
+*			myAnimation.addChild(myMoveOnQuadCurve);
+*			myAnimation.addChild(myColorTransform);
+*			myAnimation.addChild(myScale,0,1000);
+*			myAnimation.addChild(myRotation,1000,1500);
+*			myAnimation.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			myAnimation.animate(0,100);
+*			myListener.onCallback = function(source) {	
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</pre></blockquote>
+* 			<p>			
+* @usage <tt>var myAnimation:Animation = new Animation();</tt> 
+*/
+class de.alex_uhlmann.animationpackage.animation.Animation 
+												extends AnimationCore 
+												implements ISingleAnimatable, 
+														IVisitorElement,
+														IComposite {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	
+	private var childsArr:Array;
+	private var childsTimesArr:Array;
+	private var myPausesObj:Object;
+	private var start:Number;
+	private var end:Number;
+	private var durationChild:Object;
+	private var callbackFunc:Function;
+	private var multipleValues:Boolean = false;	
+	
+	public function Animation() {
+		super();
+		this.childsArr = new Array();
+		this.childsTimesArr = new Array();
+		this.myPausesObj = new Object();
+	}
+	
+	/**
+	* @method animate
+	* @description 	animates the contents of the composite.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	public function animate(start:Number, end:Number):Void {
+		this.invokeAnimation(start, end);
+	}
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		var goto:Boolean;
+		var percentage:Number;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;
+			percentage = end;
+		} else {
+			goto = false;
+			this.setStartValue(start);	
+			this.setEndValue(end);			
+		}		
+		
+		this.tweening = true;
+		this.start = start;
+		this.end = end;
+		var myPause_loc:Pause;
+
+		this.durationChild = this.getDurationChild();
+		/*invoke all childs according to their start time in childsTimesArr.*/
+		var i:Number, len:Number = this.childsArr.length;	
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];
+			var childStart:Number = childsTimesArr[i].start;
+			var childEnd:Number = childsTimesArr[i].end;			
+			var isChildEndNotDefined : Boolean = isNaN(childEnd);
+			var isChildEndBiggerThanSpecifiedDuration : Boolean = (childEnd > this.duration && this.duration != null);
+			if(isChildEndNotDefined || isChildEndBiggerThanSpecifiedDuration) {				
+				childEnd = this.duration;
+			}
+			
+			if(goto) {
+				var childStartPerc:Number = childStart / this.duration * 100;
+				var childEndPerc:Number = childEnd / this.duration * 100;
+				var totalPerc:Number = childEndPerc - childStartPerc;
+			
+				if(childStartPerc < percentage && childEndPerc > percentage) {
+					child.goto((percentage - childStartPerc) / totalPerc * 100);
+				} else if(childStartPerc < percentage && childEndPerc <= percentage) {
+					child.goto(100);
+				} else if(childStartPerc >= percentage && childEndPerc >= percentage) {
+					child.goto(0);
+				}
+				
+			} else {
+				
+				if(childStart == 0) {
+					this.invokeAnimationInstance(child, 
+												childEnd - childStart);
+				} else {				
+					myPause_loc = new Pause();
+					var ID:Number = myPause_loc.getID();
+					if(this.getTweenMode() == AnimationCore.INTERVAL) {		
+						myPause_loc.waitMS(childStart, 
+											this, 
+											"invokeAnimationInstance", 
+											[child, childEnd - childStart, ID]);
+					} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+						if(this.getDurationMode() == AnimationCore.MS) {
+							myPause_loc.waitFrames(APCore.fps * childStart, 
+													this, 
+													"invokeAnimationInstance", 
+													[child, childEnd - childStart, ID]);
+						} else {
+							myPause_loc.waitFrames(childStart, 
+												this, 
+												"invokeAnimationInstance", 
+												[child, childEnd - childStart, ID]);
+						}
+					}
+					this.myPausesObj[ID] = myPause_loc;
+				}			
+			}			
+		}
+		
+		if(goto) {
+			if(percentage <= 0) {
+				this.dispatchEvent({type:"onStart", 
+								value:this.getStartValue()});
+			} else if(percentage >= 100) {
+				this.dispatchEvent({type:"onEnd", 
+								value:this.getEndValue()});
+			} else {
+				this.dispatchEvent({type:"onUpdate", 
+								value:this.getCurrentValue()});		
+			}		
+		} else {
+			this.dispatchEvent.apply(this, [ {type:"onStart", value:this.getStartValue()} ]);
+		}		
+	}
+
+	private function getDurationChild(Void):Object {
+		var longestDuration:Number = 0;
+		var longestDurationChild:Number;
+		var childNum:Number = null;
+		var i:Number, len:Number = this.childsArr.length;	
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];
+			var childStart:Number = childsTimesArr[i].start;
+			var childEnd:Number = childsTimesArr[i].end;
+			if(isNaN(childEnd)) {
+				childNum = i;
+			} else {
+				if(childEnd >= longestDuration) {
+					longestDurationChild = i;
+					longestDuration = childEnd;
+				}
+			}			
+		}
+
+		if(this.duration == null) {			
+			this.duration = longestDuration;			
+			this.callbackFunc = Proxy.create(this, this.invokeCallback);
+			durationChild = this.childsArr[longestDurationChild];
+			durationChild.addEventListener("onEnd", callbackFunc);
+			return null;
+		}
+
+		var durationChild:Object;
+		if(childNum == null) {			
+			var myPause_loc:Pause;
+			if(this.getTweenMode() == AnimationCore.INTERVAL) {
+				myPause_loc = new Pause(AnimationCore.MS,this.duration, this, "invokeCallback");
+			} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+				if(this.getDurationMode() == AnimationCore.MS) {
+					myPause_loc = new Pause(AnimationCore.FRAMES,APCore.fps * this.duration, 
+											this, "invokeCallback");
+				} else {
+					myPause_loc = new Pause(AnimationCore.FRAMES,this.duration, 
+											this, "invokeCallback");
+				}
+			}
+			durationChild = this.myPausesObj[myPause_loc.getID()] = myPause_loc;
+			durationChild.animate(0,100);
+		} else {			
+			this.callbackFunc = Proxy.create(this, this.invokeCallback);
+			durationChild = this.childsArr[childNum];
+			durationChild.addEventListener("onEnd", callbackFunc);
+		}
+		durationChild.addEventListener("onUpdate", this);
+		return durationChild;
+	}
+	
+	private function invokeAnimationInstance(child:Object, duration:Number, ID:Number):Void {
+		delete this.myPausesObj[ID];
+		child.duration = duration;
+		child.animate(this.start, this.end);
+	}	
+
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation(s) in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation(s). See APCore class.
+	*/
+	
+	public function animationStyle(duration:Number, easing:Object, callback:String):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].animationStyle(duration, easing);
+		}
+		super.animationStyle(duration, easing, callback);
+	}
+	
+	public function onUpdate(eventObject:Object):Void {
+		this.dispatchEvent({type:eventObject.type, value:this.getCurrentValue()});
+	}	
+	
+	public function invokeCallback(Void):Void {
+		if(this.tweening) {
+			this.durationChild.removeEventListener("onEnd", this.callbackFunc);
+			delete this.myPausesObj[this.durationChild.getID()];
+			this.stop();
+			this.tweening = false;
+			APCore.broadcastMessage(this.callback, this);
+			this.dispatchEvent.apply(this, [ {type:"onEnd", value:this.getEndValue()} ]);			
+		}
+	}
+	
+	/**
+	* @method addChild
+	* @description 	adds a primitive or composite to the composite instance of Animation. 
+	* 				Accepts optional start and end values in duration. See class description.
+	* @usage  <pre>myInstance.addChild(component);</pre>
+	* @param component (IAnimatable) Must be compatible to IAnimatable.
+	* @param start (Number) start value in duration. Either milliseconds or frames.
+	* @param end (Number) end value in duration. Either milliseconds or frames.
+	* @return IAnimatable class that was added.
+	*/
+	public function addChild(component:IAnimatable, start:Number, end:Number):IAnimatable {		
+		if(component instanceof Object) {
+			this.childsArr.push(component);
+			if(start == null) {
+				start = 0;
+			}
+			if(end == null) {
+				end = NaN;
+			}
+			this.childsTimesArr.push({start:start, end:end});
+		}
+		return component;
+	}
+	
+	/**
+	* @method removeChild
+	* @description 	removes a primitive or composite from the composite instance of Parallel 
+	* See class description.
+	* @usage  <pre>myInstance.removeChild(component);</pre>
+	* @param component (IAnimatable) Must be compatible to IAnimatable.	
+	*/		
+	public function removeChild(component:IAnimatable):Void {		
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			if(this.childsArr[i] == component) {
+				this.childsArr.splice(i, 1);
+				this.childsTimesArr.splice(i, 1);
+			}
+		}
+	}
+	
+	/**
+	* @method accept
+	* @description 	Allow a visitor to visit its elements. See Visitor design pattern [GoF].
+	* @usage  <pre>myInstance.accept(visitor);</pre>
+	* @param visitor (IVisitor) Must be compatible to de.alex_uhlmann.animationpackage.utility.IVisitor.	
+	*/
+	public function accept(visitor:IVisitor):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			visitor.visit(this.childsArr[i]);			
+		}
+	}	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	public function roundResult(rounded:Boolean):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].roundResult(rounded);		
+		}
+	}	
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	public function forceEnd(forceEndVal:Boolean):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].forceEnd(forceEndVal);		
+		}
+	}
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	public function setOptimizationMode(optimize:Boolean):Void {
+		this.equivalentsRemoved = optimize;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].setOptimizationMode(optimize);		
+		}
+	}	
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode(tweenMode);</tt> 	
+	* @param tweenMode (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	public function setTweenMode(tweenMode:String):Boolean {
+		this.tweenMode = tweenMode;
+		var isSet:Boolean;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			isSet = this.childsArr[i].setTweenMode(tweenMode);		
+		}
+		return isSet;
+	}
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode(durationMode);</tt> 	
+	* @param durationMode (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/	
+	public function setDurationMode(durationMode:String):Boolean {
+		this.durationMode = durationMode;
+		var isSet:Boolean;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			isSet = this.childsArr[i].setDurationMode(durationMode);		
+		}
+		return isSet;
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/
+	public function stop(Void):Boolean {
+		if(super.stop() == true) {			
+			var i:Number, len:Number = this.childsArr.length;
+			for (i = 0; i < len; i++) {				
+				this.childsArr[i].stop();
+			}
+			var child:String;
+			for (child in this.myPausesObj) {				
+				this.myPausesObj[child].stop();
+			}
+			return true;
+		} else {
+			return false;
+		}
+	}	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/
+	public function pause(duration:Number):Boolean {
+		if(super.pause(duration) == true) {
+			var i:Number, len:Number = this.childsArr.length;
+			for (i = 0; i < len; i++) {				
+				this.childsArr[i].pause();				
+			}			
+			var child:String;
+			for (child in this.myPausesObj) {	
+				this.myPausesObj[child].pauseMe();
+			}			
+			return true;
+		} else {
+			return false;
+		}
+	}	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	public function resume(Void):Boolean {
+		if(super.resume() == true) {
+			var i:Number, len:Number = this.childsArr.length;
+			for (i = 0; i < len; i++) {
+				this.childsArr[i].resume();
+			}	
+			var child:String;
+			for (child in this.myPausesObj) {			
+				this.myPausesObj[child].resume();
+			}
+			return true;
+		} else {
+			return false;
+		}
+	}	
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	public function getStartValue(Void):Number {		
+		var startValue:Number = super.getStartValue();
+		if(startValue == null) {
+			startValue = 0;
+		}
+		return startValue;
+	}
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	public function getEndValue(Void):Number {		
+		var endValue:Number = super.getEndValue();
+		if(endValue == null) {
+			endValue = 100;
+		}
+		return endValue;
+	}	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	public function getCurrentValue(Void):Number {
+		return this.getCurrentPercentage();
+	}	
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/
+	public function getCurrentPercentage(Void):Number {
+		if(this.durationChild != null) {
+			return this.durationChild.getCurrentPercentage();
+		} else {
+			return 0;
+		}
+	}	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	public function getDurationElapsed(Void):Number {		
+		return this.durationChild.getDurationElapsed();
+	}	
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	public function getDurationRemaining(Void):Number {
+		return this.durationChild.getDurationRemaining();
+	}	
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Animation";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Animation.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/AnimationCore.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/AnimationCore.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/AnimationCore.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,676 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.utility.IVisitor;
+import de.alex_uhlmann.animationpackage.utility.IVisitorElement;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.Pause;
+import de.alex_uhlmann.animationpackage.utility.TimeTween;
+import de.alex_uhlmann.animationpackage.utility.FrameTween;
+import com.robertpenner.easing.*;
+
+/**
+* @class AnimationCore
+* @author Alex Uhlmann
+* @description  All classes in AnimationPackage that use animations inherit their 
+* 			animationStyle properties from AnimationCore. If you don't specify 
+* 			the animationStyle properties either with the animationStyle() method 
+* 			or directly via the properties, the default animationStyle properties are used.
+* 			AnimationCore gives you the opportunity to set and retrieve default properties 
+* 			for animationStyle properties. 
+* 			Here is how those default properties are defined by default:		
+* 			<pre><blockquote>
+* 			AnimationCore.duration_def = 1000;
+*			AnimationCore.easing_def = Linear.easeNone;
+*			AnimationCore.callback_def = null;	
+* 			</pre></blockquote>
+* 			Note that all default properties have the same name as their instance properties 
+* 			but the suffix "_def". For more information about the callback property, take a look at the 
+* 			APCore class documentation and the readme.htm > "Event Handling".
+* 			<p>
+* 			AnimationCore allows you to specify the tween-engine used by AnimationPackage. 
+* 			Like discussed in the readme.htm under "Tween-engine" you can choose between time-based tweening 
+* 			(INTERVAL), and frame-based tweening (FRAMES). By default time-based tweening is activated. 
+* 			You can change the tween mode either globally for all animations in AnimationPackage or 
+* 			seperatly for each instance. You change it globally with AnimationCore.setTweenModes() (see documentation below). 
+* 			In INTERVAL mode you control the duration of animations with milliseconds. In FRAMES mode, by default,
+* 			you control the duration of animations with frames. Since this might be a little cumbersome for some developers, 
+* 			FRAMES mode can also accept milliseconds if you say so. See AnimationCore.setDurationModes for details.
+* 			If you're using frame-based tweening and you're wondering why your animations are so 
+* 			slow and sluggish, then check your movie's frame rate.
+*  			</p>
+* 			<p>
+* 			Furthermore, AnimationCore stores functionality that is used by classes that use animations. 
+* 			This includes protected functionality to stop, pause, resume, lock and unlock animations 
+* 			and static pauseAll and resumeAll methods enable you to pause/resume all running animations.
+* 			<p>
+* @usage <tt>private class constructor</tt> 
+*/
+class de.alex_uhlmann.animationpackage.animation.AnimationCore 
+													extends APCore 
+													implements IVisitorElement{	
+	
+	/*static stardard properties*/
+	/** 
+	* @property AnimationCore.duration_def (Number)(static) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property AnimationCore.easing_def (Function)(static) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property AnimationCore.callback_def (String)(static) Function to invoke after animation. See APCore class.	
+	* @property AnimationCore.INTERVAL (String)(static) Property that can be used to set the tween mode. See setTweenMode.
+	* @property AnimationCore.FRAMES (String)(static) Property that can be used to set the tween mode. See setTweenMode.
+	* @property AnimationCore.MS (String)(static) Property that can be used to set the duration mode. See setDurationMode.
+	*/	
+	public static var duration_def:Number = 1000;
+	public static var easing_def:Function = Linear.easeNone;
+	public static var callback_def:String = null;	
+	public static var INTERVAL:String = "INTERVAL";
+	public static var FRAMES:String = "FRAMES";	
+	public static var MS:String = "MS";
+	private static var tweenModes:String = AnimationCore.INTERVAL;
+	private static var durationModes:String = AnimationCore.MS;
+	private static var overwriteModes:Boolean = true;
+	private static var equivalentsRemoved_static:Boolean = false;	
+	public var duration:Number;
+	public var easing:Function;
+	public var callback:String;
+	public var myAnimator:Animator;	
+	/*used to flag animations not to dispatch events. Used by Animator.*/
+	public var omitEvent:Boolean = false;	
+	private var easingParams:Array = null;
+	private var durationInFrames:Number;
+	private var startInitialized:Boolean = false;
+	private var startValue:Number;
+	private var startValues:Array;
+	private var endValue:Number;
+	private var endValues:Array;
+	private var currentValue:Number;
+	private var currentValues:Array;	
+	private var mc:MovieClip;
+	private var mcs:Array;
+	private var tweenMode:String = null;
+	private var durationMode:String = null;	
+	private var equivalentsRemoved:Boolean = null;
+	private var overwriteProperty:String;
+	private var rounded:Boolean = false;
+	private var forceEndVal:Boolean = true;	
+	private var locked:Boolean = false;	
+	private var myPause:Pause;
+	private var tweening:Boolean = false;
+	private var paused:Boolean = false;
+	private var initAnimation:Function;
+	private var invokeAnimation:Function;
+	
+	private function AnimationCore(noEvents:Boolean) {
+		super.init(noEvents);		
+	}	
+	
+	/*initialisation for classes with one identifier to animate*/
+	private function init():Void {
+		if(arguments[0] instanceof Array) {
+			var values:Array = arguments[0];
+			arguments.shift();
+			arguments.unshift(values.pop());				
+			this.initAnimation.apply(this, arguments);
+			this.setStartValue(values[0]);
+		} else if(arguments.length > 0) {
+			this.initAnimation.apply(this, arguments);
+		}
+	}
+		
+	public function run():Void {		
+		this.init.apply(this, arguments);
+		this.invokeAnimation(0, 100);		
+	}
+	
+	public function animate(start:Number, end:Number):Void {		
+		this.invokeAnimation(start, end);
+	}	
+	
+	public function goto(percentage:Number):Void {
+		this.invokeAnimation(percentage);
+	}
+	
+	public function accept(visitor:IVisitor):Void {
+		visitor.visit(this);
+	}
+	
+	public function getStartValue(Void):Number {
+		return this.startValue;
+	}
+	
+	public function setStartValue(startValue:Number, optional:Boolean):Boolean {
+		if(this.startInitialized == false || optional == null) {			
+			this.startInitialized = true;			
+			this.startValue = startValue;
+			return true;
+		}
+		return false;
+	}	
+	
+	public function getStartValues(Void):Array {
+		return this.startValues;
+	}
+	
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		if(this.startInitialized == false || optional != true) {			
+			this.startInitialized = true;			
+			this.startValues = startValues;			
+			return true;
+		}
+		return false;
+	}
+	
+	public function getEndValue(Void):Number {		
+		return this.endValue;
+	}
+	
+	public function setEndValue(endValue:Number):Boolean {
+		this.endValue = endValue;
+		return true;
+	}	
+	
+	public function getEndValues(Void):Array {		
+		return this.endValues;
+	}
+	
+	public function setEndValues(endValues:Array):Boolean {		
+		this.endValues = endValues;
+		return true;
+	}		
+	
+	public function getCurrentValue(Void):Number {		
+		return this.currentValue;
+	}
+	
+	public function getCurrentValues(Void):Array {		
+		return this.currentValues;
+	}
+	
+	public function getCurrentPercentage(Void):Number {
+		var start:Number;
+		var end:Number;
+		var current:Number;
+		/*
+		* if any values is null, AnimationCore assumes 
+		* that the animation has not yet started and therefore returns 0%.
+		*/
+		if(this.startValue == null) {
+			/*
+			* if start and end values are the same during animation
+			* it's impossible to compute the current percentage.
+			* Therefore, only compute values that have different start 
+			* and end values.
+			*/		
+			var startValues:Array = this.getStartValues();
+			if(startValues == null) {
+				return 0;
+			}
+			var endValues:Array = this.getEndValues();
+			if(endValues == null) {
+				return 0;
+			}
+			var i:Number = startValues.length;
+			while(--i>-1) {
+				if(startValues[i] != endValues[i]) {					
+					break;
+				}
+			}
+			start = startValues[i];			
+			end = endValues[i];
+			if(this.getCurrentValues()[i] != null) {
+				current = this.getCurrentValues()[i];
+			} else {
+				return 0;
+			}
+		} else {
+			if(this.getStartValue() != null) {
+				start = this.getStartValue();
+			} else {
+				return 0;
+			}
+			if(this.getEndValue() != null) {
+				end = this.getEndValue();
+			} else {
+				return 0;
+			}
+			if(this.getCurrentValue() != null) {
+				current = this.getCurrentValue();
+			} else {
+				return 0;
+			}
+		}
+		
+		if(start < end) {
+			return (current - start) / (end - start) * 100;
+		} else {
+			return 100 - ((current - end) / (start - end) * 100);
+		}
+	}
+	
+	public function getDurationElapsed(Void):Number {		
+		return this.myAnimator.getDurationElapsed();
+	}
+	
+	public function getDurationRemaining(Void):Number {		
+		return this.myAnimator.getDurationRemaining();
+	}
+	
+	/*animationStyle, getter, setter*/
+	public function animationStyle(duration:Number, easing:Object, callback:String):Void {                
+		var temp;
+		if(typeof(easing) == "string") {                        
+			temp = easing;                        
+			this.callback = temp;
+			this.easing = AnimationCore.easing_def;
+		} else if (easing == null) {                        
+			this.easing = AnimationCore.easing_def;
+			this.callback = callback;
+		} else if (easing instanceof Array) {
+			this.easing = easing[0];
+			this.easingParams = easing.slice(1);
+			this.callback = callback;
+		} else {                        
+			temp = easing;
+			this.easing = temp;
+			this.callback = callback;
+		}		
+		this.duration = (duration == null) ? AnimationCore.duration_def : duration;
+		
+		if(this.callback == null) {
+			this.callback = AnimationCore.callback_def;
+		}		
+	}
+	
+	public function get movieclip():MovieClip {
+		return this.mc;
+	}
+	
+	public function set movieclip(mc:MovieClip):Void {
+		this.mc = mc;
+	}
+	
+	public function get movieclips():Array {
+		return this.mcs;
+	}
+	
+	public function set movieclips(mcs:Array):Void {
+		this.mcs = mcs;
+	}
+	
+	public function checkIfRounded(Void):Boolean {
+		return this.rounded;
+	}
+	
+	public function roundResult(rounded:Boolean):Void {
+		this.rounded = rounded;
+	}
+	
+	public function forceEnd(forceEndVal:Boolean):Void {
+		this.forceEndVal = forceEndVal;
+	}
+	
+	public function getOptimizationMode(Void):Boolean {		
+		return this.equivalentsRemoved;
+	}
+	
+	public function setOptimizationMode(optimize:Boolean):Void {		
+		this.equivalentsRemoved = optimize;
+	}
+
+	/**
+	* @method AnimationCore.getOptimizationModes
+	* @description 	static, returns the optimization mode. 
+	* 				See AnimationCore.setOptimizationModes for more information.
+	* @usage   <tt>AnimationCore.getOptimizationModes();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	public static function getOptimizationModes(Void):Boolean {
+		return AnimationCore.equivalentsRemoved_static;
+	}
+
+	/**
+	* @method AnimationCore.setOptimizationModes
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that each IAnimatable class offers an instance method named setOptimizationMode 
+	* 				(without the "s") that allows you to remove parts only of the 
+	* 				animation instance that don't change during the animation.
+	* @usage   <pre>AnimationCore.setOptimizationModes(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	public static function setOptimizationModes(optimize:Boolean):Void {
+		AnimationCore.equivalentsRemoved_static = optimize;
+	}
+	
+	public function getTweenMode(Void):String {
+		if(this.tweenMode == null) {
+			return AnimationCore.tweenModes;
+		} else {
+			return this.tweenMode;
+		}
+	}
+	
+	public function setTweenMode(tweenMode:String):Boolean {
+		if(tweenMode == AnimationCore.INTERVAL) {
+			this.tweenMode = tweenMode;
+			this.durationMode = AnimationCore.MS;
+		} else if(tweenMode == AnimationCore.FRAMES) {
+			this.tweenMode = tweenMode;
+			this.durationMode = AnimationCore.FRAMES;
+		} else {
+			return false;
+		}
+		return true;
+	}	
+	
+	/**
+	* @method AnimationCore.getTweenModes
+	* @description 	static, returns the current tween mode, which is applied 
+	* . 			if no tween mode is specified to the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>AnimationCore.getTweenModes();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	public static function getTweenModes(Void):String {
+		return AnimationCore.tweenModes;
+	}
+	
+	/**
+	* @method AnimationCore.setTweenModes
+	* @description 	static, sets the current tween mode, which is applied 
+	* . 			if no tween mode is specified to the instance. The following 
+	* 				example shall demonstrate how AnimationCore.setTweenModes 
+	* 				works in combination with IAnimatable.setTweenMode available 
+	* 				on each IAnimatable instance.
+	* 			<p>
+	* 			Example 1: Note that the default is tween mode INTERVAL and duration mode MS.
+	* 			<blockquote><pre>
+	*			//change globally to frame based tweening 
+	*			AnimationCore.setTweenModes(AnimationCore.FRAMES);
+	*			
+	*			//tween in 100 frames
+	*			var myScale:Scale = new Scale(mc,150,150); 
+	*			myScale.animationStyle(100, Circ.easeInOut); 
+	*			myScale.animate(0,100);
+	*			
+	*			//override global tween mode with INTERVAL tweening on the IAnimatable instance Move.
+	*			var myMove:Move = new Move(mc2,mc2._x+100,mc2._y); 
+	*			myMove.setTweenMode(AnimationCore.INTERVAL);
+	*			myMove.animationStyle(1000, Circ.easeInOut); 
+	*			myMove.animate(0,100);
+	*			
+	*			//use the global frame based tweening with a local duration mode
+	*			var myRotation:Rotation = new Rotation(mc3,360); 
+	*			myRotation.setDurationMode(AnimationCore.MS);
+	*			myRotation.animationStyle(duration, Circ.easeInOut); 
+	*			myRotation.animate(0,100);
+	*			</pre></blockquote>  
+	*			<p>
+	* 			Also see AnimationCore.setDurationModes for more information.
+	* @usage   <tt>AnimationCore.setTweenModes();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	public static function setTweenModes(t:String):Boolean {
+		if(t == AnimationCore.INTERVAL) {
+			AnimationCore.tweenModes = t;
+			AnimationCore.durationModes = AnimationCore.MS;
+		} else if(t == AnimationCore.FRAMES) {
+			AnimationCore.tweenModes = t;
+			AnimationCore.durationModes = AnimationCore.FRAMES;
+		} else {
+			return false;
+		}
+		return true;
+	}
+	
+	public function getDurationMode(Void):String {
+		if(this.durationMode == null) {
+			return AnimationCore.durationModes;
+		} else {
+			return this.durationMode;
+		}
+	}
+		
+	public function setDurationMode(durationMode:String):Boolean {
+		
+		var isTweenModeFrames:Boolean = (this.getTweenMode() == AnimationCore.FRAMES);
+		var isDurationModeValid:Boolean = (durationMode == AnimationCore.MS || durationMode == AnimationCore.FRAMES);
+		
+		if(isTweenModeFrames && isDurationModeValid) {
+			this.durationMode = durationMode;
+			return true;
+		}
+		return false;
+	}	
+	
+	/**
+	* @method AnimationCore.getDurationModes
+	* @description 	static, returns the current duration mode, which is applied 
+	* . 			if no tween mode is specified to the instance.
+	* @usage   <tt>AnimationCore.getDurationModes();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	public static function getDurationModes(Void):String {		
+		return AnimationCore.durationModes;
+	}
+	
+	/**
+	* @method AnimationCore.setDurationModes
+	* @description 	static, sets the current duration mode. Only useful in tween mode AnimationCore.FRAMES. Only then 
+	* 				you can set the duration mode from AnimationCore.FRAMES, which is the default, to AnimationCore.MS. This allows you 
+	* 				to control animations with milliseconds in tween mode AnimationCore.FRAMES. Please note that AnimationPackage 
+	* 				internally still has to convert your specified milliseconds to frames. This is done by guessing 
+	* 				the frame rate (fps = frames per second) of your movie. Therefore, controlling animations with milliseconds in tween mode 
+	* 				AnimationCore.FRAMES might not be accurate. Since AnimationPackage calculates the fps as soon as you use it 
+	* 				for the first time, the example animation below, will start in a one second delay, since this is the time 
+	* 				AnimationPackage needs to calculate the fps. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* 				<p>
+	* 				Example 1:
+	* 				<blockquote><pre>
+	*				AnimationCore.setTweenModes(AnimationCore.FRAMES);
+	*				AnimationCore.setDurationModes(AnimationCore.MS);
+	*				var myRotation:Rotation = new Rotation(mc);
+	*				myRotation.animationStyle(1500,Sine.easeInOut);
+	*				myRotation.run(360);
+	*				</pre></blockquote>
+	* 				With <tt>APCore.setFPS()</tt> you can also set the fps manually. In this case or if 
+	* 				you have used any class of AnimationPackage earlier (at least one second), then no 
+	* 				start up time is required. See APCore for more information 
+	* 				about watching, unwatching, setting and getting your movie's frame rate (fps).
+	* @usage   <tt>AnimationCore.setDurationModes();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	public static function setDurationModes(d:String):Boolean {		
+		
+		var isTweenModeFrames:Boolean = (AnimationCore.tweenModes == AnimationCore.FRAMES);
+		var isDurationModeValid:Boolean = (d == AnimationCore.MS || d == AnimationCore.FRAMES);
+				
+		if(isTweenModeFrames && isDurationModeValid) {
+			AnimationCore.durationModes = d;
+			return true;
+		}
+		return false;
+	}
+	
+	
+	/**
+	* @method AnimationCore.getOverwriteModes
+	* @description 	static, see AnimationCore.setOverwriteModes for more information.
+	* @usage   <tt>AnimationCore.getOverwriteModes();</tt>
+	* @return Boolean
+	*/	
+	public static function getOverwriteModes(Void):Boolean {
+		return AnimationCore.overwriteModes;
+	}	
+	
+	
+	/**
+	* @method AnimationCore.setOverwriteModes
+	* @description 	static, Since version 1.07, AnimationPackage by default stops instances, 
+	* 				which animate on the same property/method and object. 
+	* 				This might come in handy i.e. if you want quickly create button animations as in: 				<p>
+	* 				Example 1:
+	* 				<blockquote><pre>			
+	*				mc.onRollOver = function() {
+	*					var myScale:Scale = new Scale(this,150,150);
+	*					myScale.animationStyle(500, Circ.easeOut);
+	*					myScale.animate(0,100);	
+	*				}
+	*				
+	*				mc.onRollOut = function() {
+	*					var myScale:Scale = new Scale(this,50,50);
+	*					myScale.animationStyle(500, Circ.easeIn);
+	*					myScale.animate(0,100);
+	*				}
+	*				</pre></blockquote>
+	*				If one button event triggers a Scale instance and another Scale instance 
+	* 				is still animating on the same properties of movieclip mc, 
+	* 				the currently animating Scale instance will be stopped. Previously you had to do 
+	* 				this yourself to prevent flickering, which requires to hold state of both 
+	* 				Scale instances and invoke the stop() method yourself.
+	* 				<p>
+	* 
+	* 				Example 2: One way to create a button animation on several movieclips
+	* 				<blockquote><pre>		
+	*				mc.onRollOver = coolMenuRollOver;
+	*				mc2.onRollOver = coolMenuRollOver;
+	*				mc3.onRollOver = coolMenuRollOver;
+	*				mc.onRollOut = coolMenuRollOut;
+	*				mc2.onRollOut = coolMenuRollOut;
+	*				mc3.onRollOut = coolMenuRollOut;
+	*				
+	*				function coolMenuRollOver() {
+	*					var myScale:Scale = new Scale(this,150,150);
+	*					myScale.animationStyle(500, Circ.easeOut);
+	*					myScale.animate(0,100);
+	*				}
+	*				
+	*				function coolMenuRollOut() {
+	*					var myScale:Scale = new Scale(this,50,50);
+	*					myScale.animationStyle(500, Circ.easeIn);
+	*					myScale.animate(0,100);
+	*				}
+	*				</pre></blockquote>
+	* 
+	* 				In case you don't want this behaviour, set AnimationCore.setOverwriteModes 
+	* 				to false. The default is true.
+	* @usage   <tt>AnimationCore.setOverwriteModes(overwriteModes);</tt> 	
+	* @param overwriteModes (Boolean)
+	*/
+	public static function setOverwriteModes(overwriteModes:Boolean):Void {
+		AnimationCore.overwriteModes = overwriteModes;
+	}
+
+	/**
+	* @method AnimationCore.pauseAll
+	* @description 	static, pauses all running animations whether locked or unlocked.
+	* @usage   <tt>AnimationCore.pauseAll();</tt> 	  
+	*/
+	public static function pauseAll(Void):Void {
+		//time based tweening.
+		TimeTween.pauseAll();
+		//frame based tweening.
+		FrameTween.pauseAll();
+	}
+	
+	/**
+	* @method AnimationCore.resumeAll
+	* @description 	static, resumes all running animations whether locked or unlocked. 
+	* @usage   <tt>AnimationCore.resumeAll();</tt> 	  
+	*/
+	public static function resumeAll(Void):Void {		
+		//time based tweening.
+		TimeTween.resumeAll();
+		//frame based tweening.
+		FrameTween.resumeAll();
+	}
+	
+	public function isTweening(Void):Boolean {		
+		return this.tweening;
+	}
+	
+	public function isPaused(Void):Boolean {
+		return this.paused;
+	}
+	
+	public function stop(Void):Boolean {
+		if(this.locked == true || this.tweening == false) {
+			this.paused = false;
+			return false;
+		} else {
+			this.tweening = false;
+			this.paused = false;
+			this.myAnimator.stopMe();
+			return true;
+		}
+	}	
+	
+	public function pause(duration:Number):Boolean {
+		if(this.locked == true || this.tweening == false) {			
+			return false;
+		} else {			
+			this.tweening = false;
+			this.paused = true;
+			this.myAnimator.paused = true;
+			if(duration != null) {	
+				if(this.myPause == null) {
+					this.myPause = new Pause();
+				} else {					
+					this.myPause.stop();
+				}
+				if(this.getTweenMode() == AnimationCore.INTERVAL) {
+					this.myPause.waitMS(duration, this, "resume");
+				} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+					if(this.getDurationMode() == AnimationCore.MS) {
+						duration = APCore.milliseconds2frames(duration);
+					}
+					this.myPause.waitFrames(duration, this, "resume");
+				}
+			}			
+			this.myAnimator.pauseMe();
+			return true;
+		}
+	}
+	
+	public function resume(Void):Boolean {		
+		if(this.locked == true || this.myAnimator.paused == false) {
+			return false;
+		} else {		
+			this.tweening = true;
+			this.paused = false;
+			this.myAnimator.paused = false;
+			this.myAnimator.resumeMe();
+			return true;
+		}
+	}	
+	
+	public function lock(Void):Void {		
+		if(this.locked == false) {
+			this.locked = true;
+		}
+	}
+	
+	public function unlock(Void):Void {		
+		if(this.locked == true) {
+			this.locked = false;
+		}
+	}
+
+	public function toString(Void):String {
+		return "AnimationCore";
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/AnimationCore.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Bevel.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Bevel.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Bevel.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,661 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.Filter;
+import flash.filters.BitmapFilter;
+import flash.filters.BevelFilter;
+
+/**
+* @class Bevel
+* @author Alex Uhlmann
+* @description  Manipulates the BevelFilter of a movieclip 
+* 			or a number of movieclips.
+* 			<p>	Please look into the DropShadow HTML documentation to get an idea 
+* 			how to use filter classes in AnimationPackage.
+* 			<p>
+* 			Example 1: <a href="Bevel_01.html">(Example .swf)</a> 
+* 			Showcase some of the Bevel features in 
+* 			a Sequence. See example no. 7 of DropShadow for more information.
+* 
+* 
+* @usage      
+* 			<pre>var myInstance:Bevel = new Bevel(mc);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mc, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mc, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:Bevel = new Bevel(mc, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mc, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:Bevel = new Bevel(mc, values);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mc, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mc, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:Bevel = new Bevel(mc, filterIndex, values);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mc, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mc, filterIndex, values, duration, easing, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mcs);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mcs, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mcs, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:Bevel = new Bevel(mcs, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mcs, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:Bevel = new Bevel(mcs, values);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mcs, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mcs, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:Bevel = new Bevel(mcs, filterIndex, values);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mcs, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Bevel = new Bevel(mcs, filterIndex, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param filterIndex (Number) position of the element in the Movieclip's filter property that shall be manipulated.
+* @param filter (BevelFilter) Targeted BevelFilter object to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Bevel 
+											extends Filter 
+											implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property filterIndex (Number)
+	* @property filters (Array)
+	* @property highlightColor (Number) 
+	* @property shadowColor (Number)
+	* @property quality (Number) 
+	* @property type: (String) 
+	* @property knockout (Boolean) 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public var filter:BevelFilter;
+	public var filterIndex:Number;
+	public var filters:Array;	
+	private var m_highlightColor:Number = 0xFFFFFF;
+	private var m_shadowColor:Number = 0x000000;
+	private var m_quality:Number = 1;
+	private var m_type:String = "inner";
+	private var m_knockout:Boolean = false;
+
+	public function Bevel() {
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		arguments.shift();
+		this.init.apply(this, arguments);	
+	}
+
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		this.hasStartValues = optional ? false : true;
+		
+		if(startValues[0] == null) {
+			startValues[0] = createEmptyFilter();
+		}
+		if(startValues[0] instanceof BevelFilter) {			
+			var filter:BevelFilter = startValues[0];
+			
+			if(this.hasStartValues) {
+				this.setNonAnimatedProperties(filter);
+			}
+			
+			return super.setStartValues([filter.distance, filter.angle, 
+										filter.highlightAlpha, filter.shadowAlpha, 
+										filter.blurX, filter.blurY, 
+										filter.strength], optional);	
+		} else {
+			return super.setStartValues(startValues, optional);
+		}
+	}
+	
+	public function setEndValues(endValues:Array):Boolean {
+		
+		if(endValues[0] == null) {
+			endValues[0] = createEmptyFilter();
+		}
+		if(endValues[0] instanceof BevelFilter) {
+			
+			var filter:BevelFilter = endValues[0];
+			this.setNonAnimatedProperties(filter);
+			
+			return super.setEndValues([filter.distance, filter.angle, 
+										filter.highlightAlpha, filter.shadowAlpha, 
+										filter.blurX, filter.blurY, 
+										filter.strength]);		
+		} else {
+			return super.setEndValues(endValues);
+		}
+
+	}
+	
+	private function initAnimation(filterIndex:Number, filterEnd:BevelFilter, 
+							duration:Number, easing:Object, callback:String):Void {
+	
+		if(arguments.length > 2) {
+			this.animationStyle(duration, easing, callback);
+		} else {			
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}	
+		
+		this.initializeFilter(filterIndex, filterEnd);
+		
+		this.setStartValues([this.filter], true);
+		this.setEndValues([filterEnd]);
+	}
+	
+	private function initializeFilter(filterIndex:Number, filterEnd:BevelFilter):Void {		
+		if(this.mc != null) {	
+			
+			if(filterIndex == null) {				
+				
+				this.filter = this.createEmptyFilter();
+				this.addFilter(this.filter);
+				
+			} else {			
+				
+				//if no filter of correct type is found at filterIndex, 
+				//a new filter will be created.
+				this.modifyOrCreateFilter(filterIndex);
+			}
+			
+		} else {
+			
+			this.filterIndex = filterIndex;
+			this.filter = filterEnd;
+			
+		}
+	}
+	
+	
+	private function modifyOrCreateFilter(filterIndex:Number):Void {		
+		this.filter = BevelFilter(this.findFilter(filterIndex));
+		this.filters = this.mc.filters;
+		this.filterIndex = filterIndex;
+	}
+
+	private function isFilterOfCorrectType(filter:BitmapFilter):Boolean {
+		return (filter instanceof BevelFilter == true);
+	}
+	
+	private function createEmptyFilter(Void):BevelFilter {
+		var filter:BevelFilter = new BevelFilter();
+		filter.distance = 0;
+		filter.angle = 0;
+		filter.highlightAlpha = 100;
+		filter.shadowAlpha = 100;
+		filter.blurX = 0;
+		filter.blurY = 0;
+		filter.strength = 0;
+		return filter;
+	}
+	
+	private function initSingleMC(Void):Void {
+		this.myAnimator.start = this.startValues;
+		
+		if(this.getOptimizationMode() 
+			&& this.myAnimator.hasEquivalents()) {
+				
+			this.myAnimator.setter = [[this,"setDistance"],
+								[this,"setAngle"],
+								[this,"setHighlightAlpha"],
+								[this,"setShadowAlpha"],
+								[this,"setBlurX"],
+								[this,"setBlurY"],
+								[this,"setStrength"]];							
+		} else {				
+			this.myAnimator.setter = [[this,"setBevel"]];	
+		}
+	}
+	
+	private function initMultiMC(Void):Void {
+		var myInstances:Array = [];			
+		var len:Number = this.mcs.length;
+		var mcs:Array = this.mcs;
+		var i:Number = len;
+		while(--i>-1) {
+			myInstances[i] = new Bevel(mcs[i],this.filterIndex,this.filter);			
+			var filter:BevelFilter = this.updateFilter(createEmptyFilter());
+			myInstances[i].setNonAnimatedProperties(filter);
+		}
+		this.myInstances = myInstances;
+
+		this.myAnimator.multiStart = ["getMultiDistanceValue","getMultiAngleValue",
+									"getMultiHighlightAlphaValue","getMultiShadowAlphaValue",
+									"getMultiBlurXValue","getMultiBlurYValue",
+									"getMultiStrengthValue"];
+									
+		this.myAnimator.multiSetter = [[this.myInstances,"setDistance"],
+									[this.myInstances,"setAngle"],
+									[this.myInstances,"setHighlightAlpha"],
+									[this.myInstances,"setShadowAlpha"],
+									[this.myInstances,"setBlurX"],
+									[this.myInstances,"setBlurY"],
+									[this.myInstances,"setStrength"]];	
+
+	}
+	
+	private function updateFilter(filter:BevelFilter):BevelFilter {		
+		filter.highlightColor = this.m_highlightColor;
+		filter.shadowColor = this.m_shadowColor;
+		filter.quality = this.m_quality;
+		filter.type = this.m_type;
+		filter.knockout = this.m_knockout;
+		return filter;
+	}	
+	
+	private function updateProperties(filter:BitmapFilter):Void {
+		this.filter = updateFilter(BevelFilter(filter));		
+		this.setStartValues([this.filter], true);		
+	}
+	
+	private function setNonAnimatedProperties(filter:BevelFilter):Void {
+		this.highlightColor = filter.highlightColor;
+		this.shadowColor = filter.shadowColor;
+		this.quality = filter.quality;
+		this.type = filter.type;
+		this.knockout = filter.knockout;		
+	}	
+	
+	public function getMultiDistanceValue(Void):Number {
+		return this.filter.distance;
+	}
+	
+	public function getMultiAngleValue(Void):Number {
+		return this.filter.angle;
+	}	
+	
+	public function getMultiHighlightAlphaValue(Void):Number {
+		return this.filter.highlightAlpha;
+	}
+	
+	public function getMultiShadowAlphaValue(Void):Number {
+		return this.filter.shadowAlpha;
+	}
+	
+	public function getMultiBlurXValue(Void):Number {
+		return this.filter.blurX;
+	}
+	
+	public function getMultiBlurYValue(Void):Number {
+		return this.filter.blurY;
+	}
+	
+	public function getMultiStrengthValue(Void):Number {
+		return this.filter.strength;
+	}	
+		
+	public function setBevel(distance:Number, angle:Number, 
+							highlightAlpha:Number, shadowAlpha:Number, 
+							blurX:Number, blurY:Number, strength:Number):Void {
+		
+		this.filter.distance = distance;
+		this.filter.angle = angle;
+		this.filter.highlightAlpha = highlightAlpha;
+		this.filter.shadowAlpha = shadowAlpha;
+		this.filter.blurX = blurX;
+		this.filter.blurY = blurY;
+		this.filter.strength = strength;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+
+	public function setDistance(distance:Number):Void {		
+		this.filter.distance = distance;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}	
+
+	public function setAngle(angle:Number):Void {		
+		this.filter.angle = angle;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}	
+	
+	public function setHighlightAlpha(highlightAlpha:Number):Void {		
+		this.filter.highlightAlpha = highlightAlpha;		
+		this.mc.filters = [this.filter];
+	}
+	
+	public function setShadowAlpha(shadowAlpha:Number):Void {		
+		this.filter.shadowAlpha = shadowAlpha;		
+		this.mc.filters = [this.filter];
+	}	
+
+	public function setBlurX(blurX:Number):Void {		
+		this.filter.blurX = blurX;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setBlurY(blurY:Number):Void {		
+		this.filter.blurY = blurY;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setStrength(strength:Number):Void {		
+		this.filter.strength = strength;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function get highlightColor():Number {
+		return this.m_highlightColor;
+	}
+	
+	public function set highlightColor(highlightColor:Number):Void {
+		this.filter.highlightColor = highlightColor;
+		this.m_highlightColor = highlightColor;
+	}
+	
+	public function get shadowColor():Number {
+		return this.m_shadowColor;
+	}
+	
+	public function set shadowColor(shadowColor:Number):Void {
+		this.filter.shadowColor = shadowColor;
+		this.m_shadowColor = shadowColor;
+	}
+	
+	public function get quality():Number {
+		return this.m_quality;
+	}
+	
+	public function set quality(quality:Number):Void {
+		this.filter.quality = quality;
+		this.m_quality = quality;
+	}
+	
+	public function get type():String {
+		return this.m_type;
+	}
+	
+	public function set type(type:String):Void {
+		this.filter.type = type;
+		this.m_type = type;
+	}
+	
+	public function get knockout():Boolean {
+		return this.m_knockout;
+	}
+	
+	public function set knockout(knockout:Boolean):Void {
+		this.filter.knockout = knockout;
+		this.m_knockout = knockout;
+	}
+
+	/*inherited from AnimationCore*/
+	
+	/**
+	* @method run
+	* @description  		
+	* @usage   
+	* 
+	* 		the same overloading applies to this method as described in the 
+	* 		constructor. Just without the mc and mcs parameters.
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/	
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Bevel";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Bevel.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blink.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blink.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blink.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,503 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Pause;
+import de.andre_michelle.events.FrameBasedInterval;
+import de.andre_michelle.events.ImpulsDispatcher;
+import ascb.util.Proxy;
+
+/**
+* @class Blink
+* @author Alex Uhlmann
+* @description Let a movieclip blink.	<p>		
+* @usage <tt>var myBlink:Blink = new Blink(mc);</tt> 
+* @param mc (MovieClip) Movieclip to animate.
+*/
+class de.alex_uhlmann.animationpackage.animation.Blink 
+										extends AnimationCore {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate.	
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/	
+	private var invisiblePause:Pause;
+	private var visiblePause:Pause;
+	private var blinkPause:Pause;
+	private var blinkMeID:Number;
+	private var endBlinkID:Number;	
+	private var speed:Number;
+	private var interval:Number;	
+	private var startTime:Number;
+	private var startPause:Number;
+	private var durationPaused:Number = 0;
+	private var elapsedDuration:Number = 0;
+	private var paused:Boolean = false;
+	private var stopped:Boolean = false;
+	private var finished:Boolean = false;
+	private var blinkMode:String = null;
+	private var framesDur:Number;
+	private var durationInFrames:Number;
+	private var durationOrig:Number;
+	
+	public function Blink(mc:MovieClip) {
+		super();
+		this.animationStyle();
+		this.mc = mc;
+	}	
+	
+	/**
+	* @method blinkInterval
+	* @description 	Every interval, the movieclip will be invisible 
+	* 				and visible again till speed expires. 
+	* 				This process stops when duration of animationStyle expires.
+	* 			<p>
+	* 			Example 1: Every second the movieclip is 100 milliseconds invisible. Lasts for 10 seconds.
+	* 			<blockquote><pre>
+	* 			var myBlink:Blink = new Blink(mc);
+	* 			myBlink.animationStyle(10000);
+	* 			myBlink.blinkInterval(1000,100);
+	*			</pre></blockquote>
+	* 			
+	* 		
+	* @usage   <pre>myBlink.blinkInterval(interval);</pre>
+	* 		<pre>myBlink.blinkInterval(interval, speed);</pre>
+	* 	  
+	* @param interval (Number) Every interval in millisecond or frames the movieclip is set to invisible.
+	* @param speed (Number) Optional. How long shall the movieclip be invisible. Defaults to 10 milliseconds.
+	* @return void
+	*/	
+	public function blinkInterval(interval:Number, speed:Number):Void {		
+		this.initAnimation(interval, speed);				
+	}
+	
+	/**
+	* @method blinkTimes
+	* @description 	Force the number of blinks in a specified time and optionally specify 
+	* 				the time the movieclip will be invisible.
+	* 			<p>
+	* 			Example 1: <a href="Blink_blinkTimes_01.html">(Example .swf)</a> let a movieclip blink 10 times in 10 seconds. Each blink the movieclip will be invisible for 500 milliseconds.
+	* 			<blockquote><pre>
+	*			var myBlink:Blink = new Blink(mc);
+	*			myBlink.animationStyle(10000);
+	*			myBlink.blinkTimes(10, 50);
+	*			</pre></blockquote>
+	* 			
+	* 		
+	* @usage   <pre>myBlink.blinkTimes(interval);</pre>
+	* 		<pre>myBlink.blinkTimes(interval, speed);</pre>
+	* 	  
+	* @param interval (Number) Times the movieclip will blink.
+	* @param speed (Number) Optional. How long shall the movieclip be invisible. Defaults to 10 milliseconds.
+	* @return void
+	*/
+	public function blinkTimes(blinkNum:Number, speed:Number):Void {		
+		this.initAnimation(this.duration / (blinkNum + 1), speed);
+	}
+	
+	/**
+	* @method blinkFast
+	* @description 	blinks a movieclip as fast as possible for a certain amount of time or frames. 
+	* 				Uses the frame-based ImpulsDispatcher for maximum speed. High frame rates recommended.
+	* 				Doesn't support durationMode MS in frame-based tweening. In general, where preciseness is 
+	* 				an issue you shouldn't use durationMode MS in frame-based tweening.
+	* 			<p>
+	* 			Example 1: <a href="Blink_blinkFast_01.html">(Example .swf)</a>
+	* 			let a movieclip blink as fast as possible for one second (default). Frame rate is 31.
+	* 			<blockquote><pre>
+	*			var myBlink:Blink = new Blink(mc);
+	*			myBlink.blinkFast()
+	*			</pre></blockquote>
+	* @usage   <pre>myBlink.blinkFast(duration);</pre>
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	*/
+	public function blinkFast(duration):Void {		
+		if(duration != null)this.duration = duration;
+		this.tweening = true;
+		this.finished = false;		
+		this.durationOrig = this.duration;
+		ImpulsDispatcher.addImpulsListener(this, "blinkSwitch");
+		this.blinkMode = "FAST";
+		this.blinkPause = new Pause();		
+		if(this.getTweenMode() == AnimationCore.INTERVAL) {
+			this.startTime = getTimer();
+			this.blinkPause.waitMS(this.duration, this, "endBlink");
+		} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+			this.startTime = FrameBasedInterval.frame;
+			this.blinkPause.waitFrames(this.duration, this, "endBlink");			
+		}	
+	}
+	
+	private function blinkSwitch(Void):Void {
+		var mc:MovieClip = this.mc;
+		if(mc._visible == true) {
+			mc._visible = false;
+		} else {
+			mc._visible = true;
+		}
+	}
+	
+	private function initAnimation(interval:Number, speed:Number):Void {		
+		this.speed = (speed == null) ? 10 : speed;
+		this.interval = (interval == null) ? 1000 : interval;
+		this.durationInFrames = APCore.milliseconds2frames(this.duration);
+		this.durationOrig = this.duration;
+		this.tweening = true;
+		this.finished = false;
+		this.dispatchEvent.apply(this, [ {type:"onStart"} ]);		
+		if(this.blinkMode == null) {
+			if(this.getTweenMode() == AnimationCore.INTERVAL) {				
+				this.startTime = getTimer();
+				this.blinkMode = AnimationCore.MS;
+			} else if(this.getTweenMode() == AnimationCore.FRAMES) {				
+				this.startTime = FrameBasedInterval.frame;
+				this.visiblePause = new Pause();
+				this.blinkMode = AnimationCore.FRAMES;		
+			}				
+		}
+		this.invokeAnimation();
+	}
+	
+	private function invokeAnimation(Void):Void {
+		this.invisiblePause = new Pause();
+		if(this.blinkMode == AnimationCore.MS) {			
+			var blinkWithMS:Function = Proxy.create(this, this.blinkWithMS);
+			var endBlink:Function = Proxy.create(this, this.endBlink);
+			this.blinkMeID = setInterval(blinkWithMS, this.interval);
+			this.endBlinkID = setInterval(endBlink, this.duration);				
+			
+		} else if(this.blinkMode == AnimationCore.FRAMES) {			
+			this.framesDur = this.duration;
+			if(this.getDurationMode() == AnimationCore.MS) {
+				var fps:Number = APCore.getFPS();
+				if(fps == 0) {
+					APCore.calculateFPS();
+					APCore.addListener(this);					
+				} else {
+					this.onFPSCalculated(fps);					
+				}				
+			} else if(this.getDurationMode() == AnimationCore.FRAMES) {
+				this.invokeFrameAnimation();
+			}
+		}		
+	}
+	
+	private function blinkWithMS(Void):Void {		
+		this.setInvisible(this.mc);
+		this.invisiblePause.waitMS(this.speed, this, "setVisible", [this.mc]);
+		updateAfterEvent();
+	}
+	
+	private function onFPSCalculated(fps:Number):Void {		
+		/*calculate frames with fps.*/
+		APCore.removeListener(this);
+		this.framesDur = APCore.milliseconds2frames(this.duration);
+		this.speed = APCore.milliseconds2frames(this.speed);
+		this.interval = APCore.milliseconds2frames(this.interval);
+		this.invokeFrameAnimation();
+	}
+	
+	private function invokeFrameAnimation(Void):Void {
+		this.visiblePause.waitFrames(this.interval, this, "blinkWithFrames");
+		this.blinkPause = new Pause();
+		this.blinkPause.waitFrames(this.framesDur, this, "endBlink");
+	}	
+	
+	private function blinkWithFrames(Void):Void {		
+		this.setInvisible(this.mc);
+		this.invisiblePause.addEventListener("onEnd", this);
+		this.invisiblePause.waitFrames(this.speed, this, "setVisible", [this.mc]);
+	}
+	
+	public function onEnd(eventObj:Object):Void {			
+		this.invisiblePause.removeEventListener("onEnd", this);
+		this.visiblePause.waitFrames(this.interval, this, "blinkWithFrames");
+	}
+	
+	private function setVisible(mc):Void {		
+		mc._visible = true;
+	}
+	
+	private function setInvisible(mc):Void {
+		mc._visible = false;
+	}
+	
+	private function endBlink(Void):Void {		
+		this.tweening = false;
+		this.finished = true;
+		this.clearBlink();
+		this.setVisible(this.mc);
+		APCore.broadcastMessage(this.callback, this);			
+		this.dispatchEvent.apply(this, [ {type:"onEnd"} ]);
+	}
+	
+	private function clearBlink(Void):Void {		
+		if(this.blinkMode == AnimationCore.MS) {
+			clearInterval(this.blinkMeID);
+			clearInterval(this.endBlinkID);
+		} else if(this.blinkMode == AnimationCore.FRAMES) {
+			this.invisiblePause.stop();
+			this.visiblePause.stop();
+		} else if(this.blinkMode == "FAST") {			
+			ImpulsDispatcher.removeImpulsListener(this);			
+		}
+	}
+	
+	public function stop(Void):Boolean {		
+		if(super.stop() == true) {			
+			this.stopped = true;
+			this.elapsedDuration = this.computeElapsedDuration();
+			this.clearBlink();
+			return true;
+		} else {
+			return false;
+		}	
+	}
+		
+	public function pause(duration:Number):Boolean {		
+		if(super.pause(duration) == false) {
+			return false;
+		}
+		this.tweening = false;
+		this.paused = true;
+		this.elapsedDuration = this.computeElapsedDuration();
+		
+		if(this.getTweenMode() == AnimationCore.INTERVAL) {				
+			this.startPause = getTimer();
+		} else if(this.getTweenMode() == AnimationCore.FRAMES) {				
+			this.startPause = FrameBasedInterval.frame;
+		}
+		
+		if(this.blinkMode == AnimationCore.MS) {			
+			clearInterval(this.blinkMeID);
+			clearInterval(this.endBlinkID);
+		} else if(this.blinkMode == AnimationCore.FRAMES) {			
+			this.invisiblePause.pauseMe();			
+			this.visiblePause.pauseMe();
+			this.blinkPause.pauseMe();			
+		} else if(this.blinkMode == "FAST") {			
+			this.blinkPause.pauseMe();
+			ImpulsDispatcher.removeImpulsListener(this);
+		}
+		return true;	
+	}
+	
+	public function resume(Void):Boolean {		
+		if(this.locked == true || this.paused == false) {
+			return false;
+		} else {
+			this.tweening = true;
+			this.paused = false;
+			this.duration -= this.elapsedDuration;			
+			if(this.getTweenMode() == AnimationCore.INTERVAL) {				
+				this.durationPaused += getTimer() - this.startPause;
+			} else if(this.getTweenMode() == AnimationCore.FRAMES) {				
+				this.durationPaused += FrameBasedInterval.frame - this.startPause;
+			}		
+			if(this.blinkMode == AnimationCore.MS) {				
+				this.invokeAnimation();
+			} else if(this.blinkMode == AnimationCore.FRAMES) {				
+				this.invisiblePause.resume();			
+				this.visiblePause.resume();
+				this.blinkPause.resume();
+			} else if(this.blinkMode == "FAST") {				
+				this.blinkPause.resume();
+				ImpulsDispatcher.addImpulsListener(this , "blinkSwitch");
+			}
+			return true;
+		}		
+	}
+
+	public function getDurationElapsed(Void):Number {		
+		if(this.paused == true || this.stopped == true) {
+			return this.elapsedDuration;
+		} else {
+			return this.computeElapsedDuration();
+		}
+	}
+	
+	public function getDurationRemaining(Void):Number {
+		var r:Number;
+		if(this.stopped == false) {
+			if(this.getTweenMode() == AnimationCore.INTERVAL) {
+				r = this.durationOrig - this.getDurationElapsed();
+			} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+				if(this.getDurationMode() == AnimationCore.MS) {	
+					r = this.durationOrig - this.getDurationElapsed();
+					if(this.finished == true) {
+						r = 0;
+					}
+				} else {
+					r = this.durationOrig - this.getDurationElapsed();
+				}
+			}			
+			if(r < 0) {
+				r = 0;
+			}
+		} else {
+			r = 0;
+		}
+		return r;
+	}
+	
+	private function computeElapsedDuration(Void):Number {
+		if(this.finished == true) {
+			return this.durationOrig;
+		} else {		
+			if(this.getTweenMode() == AnimationCore.INTERVAL) {
+				return getTimer() - this.startTime - this.durationPaused;
+			} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+				if(this.getDurationMode() == AnimationCore.MS) {
+					return APCore.fps * (FrameBasedInterval.frame - this.startTime - this.durationPaused);			
+				} else {
+					return FrameBasedInterval.frame - this.startTime - this.durationPaused;
+				}		
+			}		
+		}
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 		
+	* @usage   <pre>myBlink.animationStyle(duration);</pre>
+	* 		<pre>myBlink.animationStyle(duration, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myBlink.addEventListener(event, listener);</pre>
+	* 		    <pre>myBlink.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myBlink.removeEventListener(event, listener);</pre>
+	* 		    <pre>myBlink.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myBlink.removeAllEventListeners();</pre>
+	* 		    <pre>myBlink.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myBlink.eventListenerExists(event, listener);</pre>
+	* 			<pre>myBlink.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Blink";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blink.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blur.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blur.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blur.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,521 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.Filter;
+import flash.filters.BitmapFilter;
+import flash.filters.BlurFilter;
+
+/**
+* @class Blur
+* @author Alex Uhlmann
+* @description  Manipulates the BlurFilter of a movieclip 
+* 			or a number of movieclips.
+* 			<p>	Please look into the DropShadow HTML documentation to get an idea 
+* 			how to use filter classes in AnimationPackage.
+* 			<p>
+* 			Example 1: <a href="Blur_01.html">(Example .swf)</a>
+* 			<blockquote><pre>
+* 			import flash.filters.DropShadowFilter;
+* 			import flash.filters.BlurFilter;
+* 
+*			var dropShadowFilter:DropShadowFilter = new DropShadowFilter();
+*			mc.filters = [dropShadowFilter];
+*			var blurFilter:BlurFilter = new BlurFilter();
+*			mc.filters = [dropShadowFilter,blurFilter];
+*				
+*			var newBlurFilter:BlurFilter = new BlurFilter();
+*			newBlurFilter.blurX = 30;
+*			var myBlurIn:Blur = new Blur(mc,1,newBlurFilter);
+*			myBlurIn.animationStyle(1000,Circ.easeInOut);
+*			myBlurIn.addEventListener("onEnd",this);
+*			myBlurIn.animate(0,100);
+*				
+*			function onEnd(e:Object) {
+*				var myBlurOut:Blur = new Blur(mc,1,null);
+*				myBlurOut.animationStyle(1000,Circ.easeInOut);
+*				myBlurOut.animate(0,100);
+*			} 
+* 			</pre></blockquote>
+* 			<p>
+* @usage      
+* 			<pre>var myInstance:Blur = new Blur(mc);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mc, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mc, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:Blur = new Blur(mc, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mc, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:Blur = new Blur(mc, values);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mc, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mc, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:Blur = new Blur(mc, filterIndex, values);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mc, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mc, filterIndex, values, duration, easing, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mcs);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mcs, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mcs, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:Blur = new Blur(mcs, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mcs, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:Blur = new Blur(mcs, values);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mcs, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mcs, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:Blur = new Blur(mcs, filterIndex, values);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mcs, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Blur = new Blur(mcs, filterIndex, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param filterIndex (Number) position of the element in the Movieclip's filter property that shall be manipulated.
+* @param filter (BlurFilter) Targeted BlurFilter object to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Blur 
+											extends Filter 
+											implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property filterIndex (Number)
+	* @property filters (Array)
+	* @property quality (Number)
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	
+	
+	public var filter:BlurFilter;
+	private var m_quality:Number = 1;
+
+	public function Blur() {
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		arguments.shift();
+		this.init.apply(this, arguments);
+	}
+
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		this.hasStartValues = optional ? false : true;
+		
+		if(startValues[0] == null) {
+			startValues[0] = createEmptyFilter();
+		}
+		if(startValues[0] instanceof BlurFilter) {			
+			var filter:BlurFilter = startValues[0];
+			
+			if(this.hasStartValues) {
+				this.setNonAnimatedProperties(filter);
+			}
+			
+			return super.setStartValues([filter.blurX, filter.blurY], optional);			
+		} else {
+			return super.setStartValues(startValues, optional);
+		}
+	}
+	
+	public function setEndValues(endValues:Array):Boolean {
+		
+		if(endValues[0] == null) {
+			endValues[0] = createEmptyFilter();
+		}
+		if(endValues[0] instanceof BlurFilter) {
+			
+			var filter:BlurFilter = endValues[0];
+			this.setNonAnimatedProperties(filter);
+			
+			return super.setEndValues([filter.blurX, filter.blurY]);		
+		} else {
+			return super.setEndValues(endValues);
+		}
+
+	}
+	
+	private function initAnimation(filterIndex:Number, filterEnd:BlurFilter, 
+							duration:Number, easing:Object, callback:String):Void {
+	
+		if(arguments.length > 2) {
+			this.animationStyle(duration, easing, callback);
+		} else {			
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}	
+		
+		this.initializeFilter(filterIndex, filterEnd);
+		
+		this.setStartValues([this.filter], true);
+		this.setEndValues([filterEnd]);
+	}
+	
+	private function initializeFilter(filterIndex:Number, filterEnd:BlurFilter):Void {		
+		if(this.mc != null) {	
+			
+			if(filterIndex == null) {				
+				
+				this.filter = this.createEmptyFilter();
+				this.addFilter(this.filter);
+				
+			} else {			
+				
+				//if no filter of correct type is found at filterIndex, 
+				//a new filter will be created.
+				this.modifyOrCreateFilter(filterIndex);
+			}
+			
+		} else {
+			
+			this.filterIndex = filterIndex;
+			this.filter = filterEnd;
+			
+		}
+	}	
+	
+	private function modifyOrCreateFilter(filterIndex:Number):Void {		
+		this.filter = BlurFilter(this.findFilter(filterIndex));
+		this.filters = this.mc.filters;
+		this.filterIndex = filterIndex;
+	}
+
+	private function isFilterOfCorrectType(filter:BitmapFilter):Boolean {
+		return (filter instanceof BlurFilter == true);
+	}
+	
+	private function createEmptyFilter(Void):BlurFilter {
+		var filter:BlurFilter = new BlurFilter();
+		filter.blurX = 0;
+		filter.blurY = 0;
+		return filter;
+	}
+	
+	private function initSingleMC(Void):Void {
+		this.myAnimator.start = this.startValues;
+		
+		if(this.getOptimizationMode() 
+			&& this.myAnimator.hasEquivalents()) {
+				
+			this.myAnimator.setter = [[this,"setBlurX"],
+								[this,"setBlurY"]];							
+		} else {
+			this.myAnimator.setter = [[this,"setBlur"]];	
+		}
+	}
+	
+	private function initMultiMC(Void):Void {
+		var myInstances:Array = [];			
+		var len:Number = this.mcs.length;
+		var mcs:Array = this.mcs;
+		var i:Number = len;
+		while(--i>-1) {
+			myInstances[i] = new Blur(mcs[i],this.filterIndex,this.filter);			
+			var filter:BlurFilter = this.updateFilter(createEmptyFilter());
+			myInstances[i].setNonAnimatedProperties(filter);			
+		}
+		this.myInstances = myInstances;
+
+		this.myAnimator.multiStart = ["getMultiBlurXValue","getMultiBlurYValue"];
+									
+		this.myAnimator.multiSetter = [[this.myInstances,"setBlurX"],
+									[this.myInstances,"setBlurY"]];	
+
+	}
+	
+	private function updateFilter(filter:BlurFilter):BlurFilter {		
+		filter.quality = this.m_quality;
+		return filter;
+	}	
+	
+	private function updateProperties(filter:BitmapFilter):Void {
+		this.filter = updateFilter(BlurFilter(filter));
+		this.setStartValues([this.filter], true);		
+	}
+	
+	private function setNonAnimatedProperties(filter:BlurFilter):Void {
+		this.quality = filter.quality;	
+	}	
+	
+	public function getMultiBlurXValue(Void):Number {
+		return this.filter.blurX;
+	}
+	
+	public function getMultiBlurYValue(Void):Number {
+		return this.filter.blurY;
+	}
+		
+	public function setBlur(blurX:Number, blurY:Number):Void {
+		
+		this.filter.blurX = blurX;
+		this.filter.blurY = blurY;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+
+	public function setBlurX(blurX:Number):Void {		
+		this.filter.blurX = blurX;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setBlurY(blurY:Number):Void {		
+		this.filter.blurY = blurY;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function get quality():Number {
+		return this.m_quality;
+	}
+	
+	public function set quality(quality:Number):Void {
+		this.filter.quality = quality;
+		this.m_quality = quality;
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/	
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Blur";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Blur.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/BlurDuplicate.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/BlurDuplicate.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/BlurDuplicate.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,597 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.animation.Alpha;
+
+/**
+* @class Blur
+* @author Alex Uhlmann
+* @description Creates, removes and manipulates movieclip instances 
+* 			inside a container movieclip to simulate a blur effect.<p>		
+* 			There are two ways to use this class. One way is to specify 
+* 			the duration, easing equation and callback properties outside 
+* 			the current method, either with setting the properies directly 
+* 			or with the animationStyle() method like it is used in 
+* 			de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>
+*			var myBlur:BlurDuplicate = new BlurDuplicate(mc.inner_mc);
+*			myBlur.animationStyle(3000,Sine.easeIn,"onCallback");
+*			myBlur.alphaIn();
+*			myBlur.put(10,1,2,2);
+*			</pre></blockquote>  			
+* 			Example 2: The alternative way is shorter.
+* 			<blockquote><pre>	
+* 			var myBlur:BlurDuplicate = new BlurDuplicate(mc.inner_mc);
+*			myBlur.alphaIn(3000,Sine.easeIn,"onCallback");
+*			myBlur.put(10,1,2,2);
+* 			</pre></blockquote>
+* 			Example 3: <a href="BlurDuplicate_03.html">(Example .swf)</a> Blur in, blur out loop. Use animationStyle() to define default animation properties. 
+* 			Later, modify animation properties directly, to customize animation.
+*   			<blockquote><pre>
+* 			var myBlur:BlurDuplicate = new BlurDuplicate(mc.inner_mc);
+*			myBlur.animationStyle(3000,Sine.easeIn,"onCallback");
+*			myBlur.alphaIn();
+*			myBlur.put(10,1,2,0);
+*			myListener.onCallback = function()
+*			{
+*				myBlur.callback = "onCallback2";
+*				myBlur.alphaOut();
+*			}
+*			myListener.onCallback2 = function()
+*			{		
+*				myBlur.callback = "onCallback";	
+*				myBlur.alphaIn();	
+*				myBlur.put(10,1,2,0);
+*			}
+*			</pre></blockquote> 
+* @usage <tt>var myBlur:BlurDuplicate = new BlurDuplicate(inner_mc);</tt> 
+* @param inner_mc (MovieClip) Movieclip to animate. Movieclip should have a parent clip.
+*/
+class de.alex_uhlmann.animationpackage.animation.BlurDuplicate extends AnimationCore {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate. Movieclip should have a parent clip.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/		
+	private var outer_mc:MovieClip;
+	private var currParam:Array;
+	private var fade:Boolean = false;
+	private var alphaInst:Alpha;
+	private var alphaMeth:Function;
+	private var instancesArr:Array = new Array();
+	private var blurMode:String;
+	
+	public function BlurDuplicate(inner_mc:MovieClip) {
+		super();
+		this.animationStyle();
+		this.init(inner_mc);		
+	}
+		
+	private function init():Void {
+		var inner_mc:MovieClip = arguments[0];
+		this.outer_mc = inner_mc._parent;		
+		this.mc = inner_mc;
+	}
+	
+	/**
+	* @method alphaIn
+	* @description 	Fade in blur. Works in combination with put method.		
+	* 			<p>		
+	* 			Example 1: Put a blur gradually with animation. Note: The alphaIn method 
+	* 			has to be above the put method.
+	* 			<blockquote><pre>			
+	*			var myBlur:BlurDuplicate = new BlurDuplicate(mc.inner_mc);
+	*			myBlur.alphaIn(3000,Sine.easeIn,"onCallback");
+	*			myBlur.put(10,1,2,2);
+	*			</pre></blockquote>
+	* 			Example 2: Define animation properties outside of method.
+	* 			<blockquote><pre>
+	* 			var myBlur:BlurDuplicate = new BlurDuplicate(mc.inner_mc);
+	*			myBlur.animationStyle(3000,Sine.easeIn,"onCallback");
+	*			myBlur.alphaIn();
+	*			myBlur.put(10,1,2,2);
+	* 			</pre></blockquote>
+	* 
+	* @usage   <pre>myBlur.alphaIn();</pre>
+	* 		<pre>myBlur.alphaIn(duration);</pre>
+	* 		<pre>myBlur.alphaIn(duration, callback);</pre>
+	* 		<pre>myBlur.alphaIn(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	public function alphaIn(duration:Number, easing:Object, callback:String):Void {
+				
+		var paramLen:Number = 0;
+		if (arguments.length > paramLen) {			
+			this.animationStyle.apply(this,[duration, easing, callback]);			
+		}		
+		this.dispatchEvent.apply(this, [ {type:"onStart"} ]);		
+		this.fade = true;
+		this.blurMode = "IN";
+		this.currParam = [null, this.duration, this.easing];
+	}	
+	
+	/*adapted from Ralf Bokelberg http://ww.qlod.com 02-2002*/
+	/*It isn't possible to duplicate textfields and container mc's. ) : */	
+	/**
+	* @method put
+	* @description 	Creates the blur. 			
+	* 			<p> 
+	* 			Example 1: Put a blur instantly.		
+	* 			<blockquote><pre>
+	*			var myBlur:BlurDuplicate = new BlurDuplicate(mc.inner_mc);				
+	*			myBlur.put(10,1,2,2);
+	* 			</pre></blockquote> 			
+	* 			Example 2: Put a blur gradually with animation. Note: The alphaIn method 
+	* 			has to be placed above the put method.
+	* 			<blockquote><pre>			
+	*			var myBlur:BlurDuplicate = new BlurDuplicate(mc.inner_mc);
+	*			myBlur.alphaIn(3000,Sine.easeIn,"onCallback");
+	*			myBlur.put(10,1,2,2);
+	*			</pre></blockquote>
+	* 		
+	* @usage   <pre>myBlur.put(strength);</pre>
+	* 		<pre>myBlur.put(strength, posFactor, scaleFactor, rotFactor);</pre>
+	* 	  
+	* @param strength (Number) Blur power.
+	* @param posFactor (Number) Specifies how far the blur instances are positioned from inner_mc. Defaults to 0.
+	* @param scaleFactor (Number) Specifies how much the blur instances are scaled from inner_mc. Defaults to 0.
+	* @param rotFactor (Number) Specifies how much the blur instances are rotated from inner_mc. Defaults to 0.
+	* @return void
+	*/
+	public function put(strength:Number, posFactor:Number, scaleFactor:Number, rotFactor:Number):Void {
+		
+		if(posFactor == null) {
+			posFactor = 0;
+		}
+		if(scaleFactor == null) {
+			scaleFactor = 0;
+		}
+		if(rotFactor == null) {
+			rotFactor = 0;
+		}
+		this.tweening = true;
+		var astep:Number = 100/strength;		
+		var dp:Number;
+		var i:Number = strength;
+		for (i=1; i<strength; i++) {
+			/*Flash Player 7 feature disabled*/
+			//var dp:Number = this.mc._parent.getNextHighestDepth();			
+			dp = this.getNextDepth(this.mc._parent);			
+			var targ:MovieClip = this.mc.duplicateMovieClip("apBlur"+dp+"_mc", dp);	
+			var a:Number = astep * i;
+			if(this.fade) {
+				targ._alpha = 0;
+				this.currParam[0] = 100-a;
+				this.alphaInst = new Alpha(targ);				
+				this.alphaMeth = this.alphaInst["run"];
+				this.instancesArr.push(this.alphaInst);
+				this.invokeFunc(this.alphaInst, this.alphaMeth, false, i-1);				
+			}			
+			targ._x -= Math.random() * i * posFactor;
+			targ._y -= Math.random() * i * posFactor;
+			targ._width += scaleFactor * i;
+			targ._height += scaleFactor * i;
+			targ._alpha -= a;
+			targ._rotation += i * rotFactor;
+		}		
+		this.myAnimator = this.alphaInst.myAnimator;
+		this.alphaInst.addEventListener("onEnd", this);
+		delete this.currParam;		
+	}
+	
+	/**
+	* @method alphaOut
+	* @description 	Fade out blur.	
+	* 			<p>		
+	* 			Example 1: Fade out a blur gradually with Default animation style properties.
+	* 			Note: The alphaOut method has to be placed below the put method.
+	* 			<blockquote><pre>			
+	*			var myBlur:Blur = new Blur(mc.inner_mc);
+	*			myBlur.put(10,1,0);
+	*			myBlur.alphaOut();
+	*			</pre></blockquote>
+	* 			Example 2: Do the same just with customized animation style properties.
+	* 			<blockquote><pre>
+	* 			var myBlur:Blur = new Blur(mc.inner_mc);
+	*			myBlur.put(10,1,0);
+	*			myBlur.alphaOut(3000,Sine.easeIn,"onCallback");
+	* 			</pre></blockquote>
+	* 
+	* @usage   <pre>myBlur.alphaOut();</pre>
+	* 		<pre>myBlur.alphaOut(duration);</pre>
+	* 		<pre>myBlur.alphaOut(duration, callback);</pre>
+	* 		<pre>myBlur.alphaOut(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	public function alphaOut(duration:Number, easing:Object, callback:String):Void {
+		var paramLen:Number = 0;
+		if (arguments.length > paramLen) {			
+			this.animationStyle.apply(this,[duration, easing, callback]);	
+		}
+		this.dispatchEvent.apply(this, [ {type:"onStart"} ]);		
+		this.tweening = true;
+		this.blurMode = "OUT";
+		this.applyFunc(this.alphaInst, "run", [0, this.duration, this.easing]);
+		this.myAnimator = this.alphaInst.myAnimator;
+	}
+	
+	/**
+	* @method remove
+	* @description 	Removes blur instances. Note: alphaOut method removes blur instances automatically.	
+	* 			<p>		
+	* 			Example 1: <a href="Blur_remove_01.html">(Example .swf)</a> Remove a blur after fade in animation instantly.
+	* 			<blockquote><pre>			
+	*			var myBlur:Blur = new Blur(mc.inner_mc);
+	*			myBlur.alphaIn(3000,Sine.easeIn,"onCallback");
+	*			myBlur.put(10,1,2,2);
+	*			myListener.onCallback = function()
+	*			{	
+	*				myBlur.remove();				
+	*			}
+	*			</pre></blockquote>
+	* 			Example 2: To delete blur instances of a movieclip directly, 
+	* 			specify the movieclip as a parameter. Do the same like above to illustrate this. 
+	* 			<blockquote><pre>
+	* 			var myBlur:Blur = new Blur(mc.inner_mc);
+	*			var myOtherBlur:Blur = new Blur();
+	*			myBlur.alphaIn(3000,Sine.easeIn,"onCallback");
+	*			myBlur.put(10,1,2,2);
+	*			delete myBlur;
+	*			myListener.onCallback = function()
+	*			{	
+	*				myOtherBlur.remove(mc);
+	*			}
+	*			</pre></blockquote>
+	* 
+	* @usage   <pre>myBlur.remove();</pre>
+	* 		<pre>myBlur.remove(mc);</pre>
+	* 	  
+	* @param mc (MovieClip) Container movieclip. Movieclip that contains the blur instances.	
+	* @return MovieClip that contained the blur instances.
+	*/
+	public function remove(mc:MovieClip):MovieClip {			
+		if(mc == null) {
+			mc = this.outer_mc;
+		}		
+		var clips:String;
+		for (clips in mc) {
+			if (clips.substring(0,6) == "apBlur") {
+				mc[clips].removeMovieClip();				
+			}	
+		}
+		this.instancesArr.length = 0;
+		return mc;
+	}	
+	
+	/**
+	* @method applyFunc
+	* @description 	Invoke a specified method of a class with parameters that effects all blur instances. 
+	* 			The class needs to have a movieclip property, which applyFunc will use to set the Blur movieclip instance. 
+	* 			If the last paremeter is a String it is treated as a callback 
+	* 			and therefore send only to one Blur movieclip. Therefore I recommend 
+	* 			using the functions of AnimationPackage that are compatible to these limitations. 
+	* 			Furthermore, you cannot use pause(), stop() and resume() methods on animations created by myBlur.applyFunc().
+	* 			<p>
+	* 			Example 1: <a href="Blur_applyFunc_01.html">(Example .swf)</a> colors blur movieclips slightly red after fading in.
+	* 			<blockquote><pre>			
+	*			var myBlur:Blur = new Blur(mc.inner_mc);
+	*			myBlur.alphaIn(3000,Sine.easeIn,"onCallback");
+	*			myBlur.put(10,1,2,0);
+	*			myListener.onCallback = function()
+	*			{	
+	*				myBlur.applyFunc(new ColorTransform(), "run", [0xff0000, 100, 4000, Quad.easeOut]);
+	*			}
+	*			</pre></blockquote>
+	* 
+	* @usage   <pre>myBlur.applyFunc(scope, funcStr);</pre> 		
+	* 		<pre>myBlur.applyFunc(scope, funcStr, param);</pre>
+	* 	  
+	* @param scope (Number) Object.
+	* @param funcStr (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param param (Array) An optional array of parameters passed to funcStr. Note the limitations described in description. 
+	* @return void
+	*/
+	public function applyFunc(scope:Object, funcStr:String, param:Array):Void {		
+		var i:Number = 0;
+		var func:Function = scope[funcStr];		
+		this.currParam = param;
+		var hasCallback:Boolean = false;		
+		var lastArg = arguments[arguments.length-1][arguments.length+1];
+		if(typeof(lastArg) == "string") {			
+			hasCallback = true;
+		}
+		var clips:String;
+		for (clips in this.outer_mc) {			
+			if (clips.substring(0,6) == "apBlur") {
+				/*save all Alpha instances for pausing, resuming and stopping*/
+				if(scope instanceof Alpha) {
+					this.alphaInst = new Alpha(this.outer_mc[clips]);					
+					this.instancesArr.push(this.alphaInst);
+					func = this.alphaInst[funcStr];			
+					this.invokeFunc(this.alphaInst, func, hasCallback, i);
+				} else {
+					scope.movieclip = this.outer_mc[clips];				
+					this.invokeFunc(scope, func, hasCallback, i);
+				}
+				i++;				
+			}
+		}
+		this.alphaInst.addEventListener("onEnd", this);
+		delete this.currParam;
+	}
+	
+	private function invokeFunc(scope:Object, func:Object, 
+								hasCallback:Boolean, i:Number):Void {
+		
+		//invoke only one callback. The callback of first inst.
+		//CLUNKY: Be carefull if your func's last argument is a String but not a callback.					
+		if(hasCallback == true && i == 0) {			
+			func.apply(scope, this.currParam);
+			this.currParam.pop();				
+		}else {
+			func.apply(scope, this.currParam);
+		}		
+	}	
+
+	private function onEnd(eventObj:Object):Void {			
+		eventObj.target.removeEventListener("onEnd", this);
+		if(this.blurMode == "OUT") {
+			this.remove();
+		}
+		this.tweening = false;
+		this.instancesArr.length = 0;
+		APCore.broadcastMessage(this.callback, this);
+		this.dispatchEvent.apply(this, [ {type:"onEnd", target:this} ]);
+	}
+	
+	public function getStartValue(Void):Number {
+		return 0;
+	}
+	
+	public function getEndValue(Void):Number {	
+		return 100;
+	}
+	
+	public function getCurrentValue(Void):Number {		
+		var start:Number = this.alphaInst.getStartValue();
+		var end:Number = this.alphaInst.getEndValue();
+		if(start < end) {	
+			return this.alphaInst.getCurrentValue() / end * 100;
+		} else {
+			return 100 - this.alphaInst.getCurrentValue() / start * 100;
+		}
+	}
+	
+	public function stop(Void):Boolean {
+		if(this.locked == true || this.tweening == false) {
+			return false;
+		} else {
+			this.tweening = false;
+			var len:Number = this.instancesArr.length;
+			var i:Number;
+			for (i=0; i<len; i++) {				
+				this.instancesArr[i].stop();
+			}
+			return true;
+		}
+	}
+	
+	public function pause(duration:Number):Boolean {
+		if(this.locked == true || this.tweening == false) {
+			return false;
+		} else {
+			this.tweening = false;
+			var len:Number = this.instancesArr.length;		
+			var i:Number;
+			for (i=0; i<len; i++) {
+				this.instancesArr[i].pause(duration);				
+			}
+			return true;
+		}
+	}
+	
+	public function resume(Void):Boolean {		
+		if(!this.locked) {
+			this.tweening = true;
+			var len:Number = this.instancesArr.length;		
+			var i:Number;
+			for (i=0; i<len; i++) {
+				this.instancesArr[i].resume();	
+			}
+			return true;
+		} else {
+			return false;
+		}
+	}
+		
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage. 
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/	
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>			
+	* 		
+	* @usage   <pre>myBlur.addEventListener(event, listener);</pre>
+	* 		    <pre>myBlur.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myBlur.removeEventListener(event, listener);</pre>
+	* 		    <pre>myBlur.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myBlur.removeAllEventListeners();</pre>
+	* 		    <pre>myBlur.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myBlur.eventListenerExists(event, listener);</pre>
+	* 			<pre>myBlur.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "BlurDuplicate";
+	}		
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/BlurDuplicate.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorBrightness.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorBrightness.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorBrightness.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,508 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.ColorFX;
+
+/**
+* @class ColorBrightness
+* @author Alex Uhlmann
+* @description Manipulates the brightness of a movieclip or a number of movieclips 
+* 			with help of ColorFX class, 
+* 			which extends the build-in Color class. Value range is like 
+* 			the Flash IDE's property inspector.<p>		
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>			
+*			var myColorBrightness:ColorBrightness = new ColorBrightness(mc);
+*			myColorBrightness.animationStyle(3000,Quad.easeOut,"onCallback");
+*			myColorBrightness.run(50);
+*			</pre></blockquote>  			
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new ColorBrightness(mc).run(50,3000,Quad.easeOut,"onCallback");
+* 			</pre></blockquote>
+* 			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 
+* 			<blockquote><pre>	
+* 			var myColorBrightness:ColorBrightness = new ColorBrightness(mc,-50,1000,Circ.easeInOut,"onCallback");
+* 			myColorBrightness.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValue or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+* 			<blockquote><pre>
+* 			var myColorBrightness:ColorBrightness = new ColorBrightness(mc,[-100,100],3000,Quad.easeOut);
+* 			myColorBrightness.run();
+* 			</pre></blockquote>	
+* 			<p>
+* 			Example 5: Brighten up a movieclip to value 50 in 1 second using linear easing. 		
+* 			<blockquote><pre>
+*			new ColorBrightness(mc).run(50,1000);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 6: <a href="ColorBrightness_run_02.html">(Example .swf)</a> Brighten a movieclip to its minima and maxima in 4 seconds 
+* 			using Sine easing. Note that I nullify the callback property, 
+* 			which would call the onCallback method again.
+* 			<blockquote><pre>			
+*			var myColorBrightness:ColorBrightness = new ColorBrightness(mc);
+*			myColorBrightness.animationStyle(2000,Sine.easeOut,"onCallback");
+*			myColorBrightness.run(-100);
+*			myListener.onCallback = function() {	
+*				myColorBrightness.callback = null;
+*				myColorBrightness.run(100);	
+*			}
+*			</pre></blockquote>
+* 			Example 7: To animate many movieclips the same way, this class also accepts 
+* 			an Array of movieclips instead of one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want to animate. Different 
+* 			start values of your movieclip properties are considered when animating multiple movieclips 
+* 			within one animation instance.
+* 			<blockquote><pre>
+* 			var mcs:Array = new Array(mc1,mc2,mc3);
+*			var myColorFX:ColorFX = new ColorFX(mc);
+*			myColorFX.setBrightness(50);
+*			
+*			var myColorBrightness:ColorBrightness = new ColorBrightness(mcs);
+*			myColorBrightness.animationStyle(2000,Sine.easeOut,"onCallback");
+*			
+*			myColorBrightness.run(-100);
+*			myListener.onCallback = function() {	
+*				myColorBrightness.callback = null;
+*				myColorBrightness.run(100);	
+*			}
+* 			</pre></blockquote>
+* 
+* @usage 
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mc);</pre>
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mc, amount);</pre>
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mc, amount, duration);</pre>
+*		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mc, amount, duration, callback);</pre>
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mc, amount, duration, easing, callback);</pre>
+*		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mc, values);</pre> 
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mc, values, duration, callback);</pre> 
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mc, values, duration, easing, callback);</pre> 
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mcs);</pre>
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mcs, amount);</pre>
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mcs, amount, duration);</pre>
+*		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mcs, amount, duration, callback);</pre>
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mcs, amount, duration, easing, callback);</pre>
+*		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mcs, values);</pre> 
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mcs, values, duration, callback);</pre> 
+* 		<pre>var myColorBrightness:ColorBrightness = new ColorBrightness(mcs, values, duration, easing, callback);</pre> 
+* 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param amount (Number) Targeted brigthness value (like in the Flash IDE's Effects panel) to animated to. 
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation 
+*/
+class de.alex_uhlmann.animationpackage.animation.ColorBrightness 
+										extends AnimationCore 
+										implements ISingleAnimatable,
+													IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	private var myColorFX:ColorFX;
+	private var overwriteProperty:String = "movieclip";
+	
+	public function ColorBrightness() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+			this.myColorFX = new ColorFX(this.mc);
+		} else {
+			this.mcs = arguments[0];
+			this.myColorFX = new ColorFX(this.mcs[0]);
+		}	
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function initAnimation(amount:Number, duration:Number, easing:Object, callback:String):Void {		
+		if (arguments.length > 1) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		this.setStartValue(this.myColorFX.getBrightness(), true);
+		this.setEndValue(amount);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = [this.endValue];
+		
+		if(this.mc != null) {
+			this.myAnimator.start = [this.startValue];
+			this.myAnimator.setter = [[this.myColorFX,"setBrightness"]];
+		} else {
+			
+			var myColorFXs:Array = [];
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				myColorFXs[i] = new ColorFX(this.mcs[i]);
+			}
+			
+			this.myAnimator.multiStart = ["getBrightness"];										
+			this.myAnimator.multiSetter = [[myColorFXs,"setBrightness"]];			
+		}
+
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	/**
+	* @method run
+	* @description 
+	* 		
+	* @usage    
+	* 		<pre>myColorBrightness.run();</pre>
+	* 		<pre>myColorBrightness.run(amount);</pre>
+	* 		<pre>myColorBrightness.run(amount, duration);</pre>
+	* 		<pre>myColorBrightness.run(amount, duration, callback);</pre>
+	*		<pre>myColorBrightness.run(amount, duration, easing, callback);</pre>
+	* 		<pre>myColorBrightness.run(values, duration);</pre>
+	* 		<pre>myColorBrightness.run(values, duration, callback);</pre>
+	*		<pre>myColorBrightness.run(values, duration, easing, callback);</pre>
+	* 
+	* @param amount (Number) Targeted brigthness value (like in the Flash IDE's Effects panel) to animated to. 
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation
+	* @return void
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myColorBrightness.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.		
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of duration to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. 
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. 
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. 
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. 
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. 
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myColorBrightness.addEventListener(event, listener);</pre>
+	* 		    <pre>myColorBrightness.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myColorBrightness.removeEventListener(event, listener);</pre>
+	* 		    <pre>myColorBrightness.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myColorBrightness.removeAllEventListeners();</pre>
+	* 		    <pre>myColorBrightness.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myColorBrightness.eventListenerExists(event, listener);</pre>
+	* 			<pre>myColorBrightness.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "ColorBrightness";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorBrightness.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorDodge.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorDodge.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorDodge.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,552 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.ColorToolkit;
+import de.alex_uhlmann.animationpackage.utility.ColorFX;
+
+/**
+* @class ColorDodge
+* @author Alex Uhlmann
+* @description Manipulates color of a movieclip or a number of movieclips 
+* 			with help of ColorToolkit and ColorFX class, 
+* 			which extends the build-in Color class.<p>		
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>			
+*			var myColorDodge:ColorDodge = new ColorDodge(mc);
+*			myColorDodge.animationStyle(3000,Quad.easeOut,"onCallback")
+*			myColorDodge.run(0xff0000);
+*			</pre></blockquote>  			
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new ColorDodge(mc).run(0xff0000,3000,Quad.easeOut,"onCallback");
+* 			</pre></blockquote>
+*  			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 
+* 			<blockquote><pre>
+* 			var myColorDodge:ColorDodge = new ColorDodge(mc,0xff0000,2000,Circ.easeInOut,"onCallback");		
+* 			myColorDodge.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValues or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+* 			<blockquote><pre>
+*			var myColorDodge:ColorDodge = new ColorDodge(mc,[0xff0000,0x0000ff],2000);
+*			myColorDodge.run();
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 5: <a href="ColorDodge_run_01.html">(Example .swf)</a> Set movieclip to solid white and fade via color dodge to original color.		
+* 			<blockquote><pre>
+*			var myColorToolkit:ColorToolkit = new ColorToolkit(mc);
+*			myColorToolkit.setColorOffsetHex(0xffffff);
+*			var myColorDodge:ColorDodge = new ColorDodge(mc);
+*			myColorDodge.animationStyle(5000,Sine.easeOut);
+*			myColorDodge.run(0x000000);
+*			</pre></blockquote>
+* 			Example 7: To animate many movieclips the same way, this class also accepts 
+* 			an Array of movieclips instead of one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want to animate. Different 
+* 			start values of your movieclip properties are considered when animating multiple movieclips 
+* 			within one animation instance.
+* 			<blockquote><pre>
+* 			var mcs:Array = new Array(mc1,mc2);
+*			var myColorToolkit:ColorToolkit = new ColorToolkit(mc1);
+*			myColorToolkit.setColorOffsetHex(0xffffff);
+*			var myColorToolkit:ColorToolkit = new ColorToolkit(mc2);
+*			myColorToolkit.setColorOffsetHex(0x00ffff);
+*			
+*			var myColorDodge:ColorDodge = new ColorDodge(mcs);
+*			myColorDodge.animationStyle(5000,Sine.easeOut);
+*			myColorDodge.run(0x000000);
+* 			</pre></blockquote> 
+* 
+* @usage 
+* 		<pre>var myColorDodge:ColorDodge = new ColorDodge(mc);</pre>
+*		<pre>var myColorDodge:ColorDodge = new ColorDodge(mc, rgb);</pre>
+* 		<pre>var myColorDodge:ColorDodge = new ColorDodge(mc, rgb, duration);</pre>
+*		<pre>var myColorDodge:ColorDodge = new ColorDodge(mc, rgb, duration, callback);</pre>
+*	 	<pre>var myColorDodge:ColorDodge = new ColorDodge(mc, rgb, duration, easing, callback);</pre> 
+*		<pre>var myColorDodge:ColorDodge = new ColorDodge(mc, values);</pre> 
+* 		<pre>var myColorDodge:ColorDodge = new ColorDodge(mc, values, duration, callback);</pre> 
+* 		<pre>var myColorDodge:ColorDodge = new ColorDodge(mc, values, duration, easing, callback);</pre> 
+* 		<pre>var myColorDodge:ColorDodge = new ColorDodge(mcs);</pre>
+*		<pre>var myColorDodge:ColorDodge = new ColorDodge(mcs, rgb);</pre>
+* 		<pre>var myColorDodge:ColorDodge = new ColorDodge(mcs, rgb, duration);</pre>
+*		<pre>var myColorDodge:ColorDodge = new ColorDodge(mcs, rgb, duration, callback);</pre>
+*	 	<pre>var myColorDodge:ColorDodge = new ColorDodge(mcs, rgb, duration, easing, callback);</pre> 
+*		<pre>var myColorDodge:ColorDodge = new ColorDodge(mcs, values);</pre> 
+* 		<pre>var myColorDodge:ColorDodge = new ColorDodge(mcs, values, duration, callback);</pre> 
+* 		<pre>var myColorDodge:ColorDodge = new ColorDodge(mcs, values, duration, easing, callback);</pre>
+* 
+* @param mc (MovieClip) Movieclip to animate. 
+* @param mcs (Array) array of movieclips to animate.
+* @param rgb (Number) Targeted color value (as a hex number) to animated to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.ColorDodge 
+										extends AnimationCore 
+										implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	private var myCTK:ColorToolkit;
+	private var myColorFX:ColorFX;
+	private var overwriteProperty:String = "movieclip";
+	
+	public function ColorDodge() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+			this.myCTK = new ColorToolkit(this.mc);		
+			this.myColorFX = new ColorFX(this.mc);			
+		} else {
+			this.mcs = arguments[0];
+			this.myCTK = new ColorToolkit(this.mcs[0]);		
+			this.myColorFX = new ColorFX(this.mcs[0]);			
+		}
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function init():Void {
+		if(arguments[0] instanceof Array) {
+			var values:Array = arguments[0];
+			arguments.shift();
+			arguments.unshift(values.pop());				
+			this.initAnimation.apply(this, arguments);
+			this.setStartValues([values[0]]);
+		} else if(arguments.length > 0) {
+			this.initAnimation.apply(this, arguments);
+		}
+	}	
+	
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		var rgb:Object = this.myCTK.hexrgb2rgb(startValues[0]);
+		var startRGB:Object = rgb;		
+		/*use centralMC as dummy in order to retrieve correct color dodge values.*/
+		var myCF:ColorFX = new ColorFX(APCore.getCentralMC());
+		myCF.setColorDodge(rgb);		
+		var startDodge:Object = myCF.getColorDodge();		
+		return super.setStartValues([startRGB.r, startRGB.g, startRGB.b, 
+							startDodge.r, startDodge.g, startDodge.b], optional);
+	}	
+
+	public function setEndValues(endValues:Array):Boolean {
+		var rgb:Object = this.myCTK.hexrgb2rgb(endValues[0]);
+		var endRGB:Object = rgb;
+		var endDodge:Object = rgb;
+		return super.setEndValues([endRGB.r, endRGB.g, endRGB.b, 
+							endDodge.r, endDodge.g, endDodge.b]);
+	}
+	
+	private function initAnimation(rgb:Number, duration:Number, easing:Object, callback:String):Void {		
+		
+		if (arguments.length > 1) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		
+		this.setStartValues([this.myCTK.getColorOffsetHex()], true);
+		this.setEndValues([rgb]);		
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		this.startInitialized = false;		
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = this.endValues;
+	
+		
+		if(this.mc != null) {
+		
+			this.myAnimator.start = this.startValues;				
+			this.myAnimator.setter = [[this.myCTK, "setRedOffset"], 
+									[this.myCTK, "setGreenOffset"], 
+									[this.myCTK, "setBlueOffset"],
+									[this.myColorFX, "setRedDodge"], 
+									[this.myColorFX, "setGreenDodge"], 
+									[this.myColorFX, "setBlueDodge"]];		
+		
+		} else {
+			
+			var myCTKs:Array = [];
+			var myColorFXs:Array = [];
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				myCTKs[i] = new ColorToolkit(this.mcs[i]);
+				myColorFXs[i] = new ColorFX(this.mcs[i]);
+			}
+			
+			this.myAnimator.multiStart = ["getRedOffset", 
+									"getGreenOffset", 
+									"getBlueOffset",
+									"getRedDodge", 
+									"getGreenDodge", 
+									"getBlueDodge"];			
+			
+			this.myAnimator.multiSetter = [[myCTKs, "setRedOffset"], 
+									[myCTKs, "setGreenOffset"], 
+									[myCTKs, "setBlueOffset"],
+									[myColorFXs, "setRedDodge"], 
+									[myColorFXs, "setGreenDodge"], 
+									[myColorFXs, "setBlueDodge"]];
+		}
+		
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	/**
+	* @method run
+	* @description 		
+	* @usage   
+	* 		<pre>myColorDodge.run();</pre>
+	* 		<pre>myColorDodge.run(rgb);</pre>
+	* 		<pre>myColorDodge.run(rgb, duration);</pre>
+	*		<pre>myColorDodge.run(rgb, duration, callback);</pre>
+	* 		<pre>myColorDodge.run(rgb, duration, easing, callback);</pre>
+	* 		<pre>myColorDodge.run(values, duration);</pre>
+	* 		<pre>myColorDodge.run(values, duration, callback);</pre>
+	*		<pre>myColorDodge.run(values, duration, easing, callback);</pre>
+	* 	  
+	* @param rgb (Number) Targeted color value (as a hex number) to animated to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myColorDodge.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.		
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/	
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValues
+	* @description 	returns the original, starting values of the current tween. RGB and color dodge values.
+	* @usage   <tt>myInstance.getStartValues();</tt>
+	* @return (Array) 6 elements. From 0 - 5:  r, g, b, color doge r, color dodge g, color dodge b.
+	*/
+	
+	/**
+	* @method setStartValues
+	* @description 	sets the original, starting values of the current tween. RGB and color dodge values.
+	* @usage   <tt>myInstance.setStartValues(startValues);</tt>
+	* @param startValues (Array) 6 elements. From 0 - 5:  r, g, b, color doge r, color dodge g, color dodge b.
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	
+	/**
+	* @method getEndValues
+	* @description 	returns the targeted values of the current tween. RGB and color dodge values.
+	* @usage   <tt>myInstance.getEndValues();</tt>
+	* @return (Array) 6 elements. From 0 - 5:  r, g, b, color doge r, color dodge g, color dodge b.
+	*/
+	
+	/**
+	* @method setEndValues
+	* @description 	sets the targeted value of the current tween. RGB and color dodge values.
+	* @usage   <tt>myInstance.setEndValues(endValues);</tt>
+	* @param endValues (Array) 6 elements. From 0 - 5:  r, g, b, color doge r, color dodge g, color dodge b.	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValues
+	* @description 	returns the current values of the current tween. RGB and color dodge values.
+	* @usage   <tt>myInstance.getCurrentValues();</tt>
+	* @return (Array) 6 elements. From 0 - 5:  r, g, b, color doge r, color dodge g, color dodge b.
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Array) values to animate.<p>
+	* 		
+	* @usage   <pre>myColorDodge.addEventListener(event, listener);</pre>
+	* 		    <pre>myColorDodge.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myColorDodge.removeEventListener(event, listener);</pre>
+	* 		    <pre>myColorDodge.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myColorDodge.removeAllEventListeners();</pre>
+	* 		    <pre>myColorDodge.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myColorDodge.eventListenerExists(event, listener);</pre>
+	* 			<pre>myColorDodge.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "ColorDodge";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorDodge.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorNegative.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorNegative.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorNegative.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,510 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.ColorFX;
+
+/**
+* @class ColorNegative
+* @author Alex Uhlmann
+* @description  Invert the colors of a movieclip or a number of movieclips with help of ColorFX class, 
+* 			which extends the build-in Color class. Can be used on both, vector 
+* 			and bitmap images, however to see the full potential use a bitmap. <p>		
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>			
+*			var myColorNegative:ColorNegative = new ColorNegative(mc);
+*			myColorNegative.animationStyle(3000,Quad.easeOut,"onCallback");
+*			myColorNegative.run(50);
+*			</pre></blockquote>  			
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new ColorNegative(mc).run(50,3000,Quad.easeOut,"onCallback");
+* 			</pre></blockquote>		
+*  			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 
+* 			<blockquote><pre>
+* 			var myColorNegative:ColorNegative = new ColorNegative(mc,200,2000,Circ.easeInOut,"onCallback");
+* 			myColorNegative.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValue or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+* 			<blockquote><pre>
+*			var myColorNegative:ColorNegative = new ColorNegative(mc,[-255,0],3000,Quad.easeOut);
+*			myColorNegative.run();
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 5: Invert movieclip's colors in 1 second using linear easing. 		
+* 			<blockquote><pre>
+*			new ColorNegative(mc).run(255,1000);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 6: <a href="ColorNegative_run_02.html">(Example .swf)</a> Invert a movieclip to amount 100 in 10 seconds using Sine easing.
+* 			After animation invert it back to -255, results in an extremely bright movieclip.		
+* 			Note that I nullify the callback property, which would call 
+* 			the onCallback method again.
+* 			<blockquote><pre>			
+*			var myColorNegative:ColorNegative = new ColorNegative(mc);
+*			myColorNegative.animationStyle(6000,Sine.easeOut,"onCallback");
+*			myColorNegative.run(255);
+*			myListener.onCallback = function() {	
+*				myColorNegative.callback = null;
+*				myColorNegative.run(-255);	
+*			}
+*			</pre></blockquote>
+* 			Example 7: To animate many movieclips the same way, this class also accepts 
+* 			an Array of movieclips instead of one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want to animate. Different 
+* 			start values of your movieclip properties are considered when animating multiple movieclips 
+* 			within one animation instance.
+* 			<blockquote><pre>
+* 			var mcs:Array = new Array(mc1,mc2,mc3);
+*			var myColorFX:ColorFX = new ColorFX(mc);
+*			myColorFX.setNegative(50);
+*			
+*			var myColorNegative:ColorNegative = new ColorNegative(mcs);
+*			myColorNegative.animationStyle(6000,Sine.easeOut,"onCallback");
+*			myColorNegative.run(255);
+*			myListener.onCallback = function() {	
+*				myColorNegative.callback = null;
+*				myColorNegative.run(-255);	
+*			}
+* 			</pre></blockquote>	
+* 		
+* @usage 	
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mc);</pre> 
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mc, amount);</pre>
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mc, amount, duration);</pre>
+*			<pre>var myColorNegative:ColorNegative = new ColorNegative(mc, amount, duration, callback);</pre>
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mc, amount, duration, easing, callback);</pre>
+*			<pre>var myColorNegative:ColorNegative = new ColorNegative(mc, values);</pre> 
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mc, values, duration, callback);</pre> 
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mc, values, duration, easing, callback);</pre> 
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mcs);</pre> 
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mcs, amount);</pre>
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mcs, amount, duration);</pre>
+*			<pre>var myColorNegative:ColorNegative = new ColorNegative(mcs, amount, duration, callback);</pre>
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mcs, amount, duration, easing, callback);</pre>
+*			<pre>var myColorNegative:ColorNegative = new ColorNegative(mcs, values);</pre> 
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mcs, values, duration, callback);</pre> 
+* 			<pre>var myColorNegative:ColorNegative = new ColorNegative(mcs, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate. 
+* @param mcs (Array) array of movieclips to animate.
+* @param amount (Number) Targeted negative value to animated to. (-255 - 255)
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.ColorNegative 
+											extends AnimationCore 
+											implements ISingleAnimatable,
+													IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	private var myColorFX:ColorFX;
+	private var overwriteProperty:String = "movieclip";
+	
+	public function ColorNegative() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+			this.myColorFX = new ColorFX(this.mc);
+		} else {
+			this.mcs = arguments[0];
+			this.myColorFX = new ColorFX(this.mcs[0]);
+		}
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function initAnimation(amount:Number, duration:Number, easing:Object, callback:String):Void {		
+		if (arguments.length > 1) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}		
+		this.setStartValue(this.myColorFX.getNegative(), true);
+		this.setEndValue(amount);
+	}	
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = [this.endValue];		
+		
+		if(this.mc != null) {
+			this.myAnimator.start = [this.startValue];
+			this.myAnimator.setter = [[this.myColorFX,"setNegative"]];
+		} else {
+			
+			var myColorFXs:Array = [];
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				myColorFXs[i] = new ColorFX(this.mcs[i]);
+			}
+			
+			this.myAnimator.multiStart = ["getNegative"];										
+			this.myAnimator.multiSetter = [[myColorFXs,"setNegative"]];			
+		}		
+
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}		
+	}
+	
+	/**
+	* @method run
+	* @description 	invert the colors of a movieclip to a specified amount 
+	* 			in a specified time and easing equation. Can be used on both, vector 
+	* 			and bitmap images, however to see the full potential use a bitmap. 
+
+	* 		
+	* @usage   
+	* 		<pre>myColorNegative.run();</pre>
+	* 		<pre>myColorNegative.run(amount);</pre>
+	* 		<pre>myColorNegative.run(amount, duration);</pre>
+	*		<pre>myColorNegative.run(amount, duration, callback);</pre>
+	* 		<pre>myColorNegative.run(amount, duration, easing, callback);</pre>
+	* 		<pre>myColorNegative.run(values, duration);</pre>
+	* 		<pre>myColorNegative.run(values, duration, callback);</pre>
+	*		<pre>myColorNegative.run(values, duration, easing, callback);</pre>
+	* 	  
+	* @param amount (Number) Targeted negative value to animated to. (-255 - 255)
+	* @param values (Array) optional start and end values.	
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myColorNegative.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(event, listener);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy.
+	*                  				<code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. 
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. 
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. 
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. 
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. 
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myColorNegative.addEventListener(event, listener);</pre>
+	* 		    <pre>myColorNegative.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myColorNegative.removeEventListener(event, listener);</pre>
+	* 		    <pre>myColorNegative.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myColorNegative.removeAllEventListeners();</pre>
+	* 		    <pre>myColorNegative.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myColorNegative.eventListenerExists(event, listener);</pre>
+	* 			<pre>myColorNegative.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "ColorNegative";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorNegative.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorTransform.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorTransform.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorTransform.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,813 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.ColorToolkit;
+
+/**
+* @class ColorTransform
+* @author Alex Uhlmann
+* @description Manipulates the colors of a movieclip or a number of movieclips 
+* 			with help of the ColorToolkit class, 
+* 			which extends the build-in Color class via the ColorCore class.
+* 			ColorTransform accepts two kinds of color input values.<p>
+* 			<b>Way no. 1 "easy way": One offset and one percentage value.</b><p>
+* 			A number in the range 0 to 16777215 (0xFFFFFF), representing the new RGB offsets 
+* 			of the movieclip. Can be a decimal integer or a hexadecimal integer. 
+* 			Another number to specify the color transformation percentages of the movieclip. Does not allow 
+* 			the manipulation of alpha components and of single color percentage values. Use "the complex way" 
+* 			for that.<p>
+* 			<b>Way no. 2 "complex way": A transform object like the one returned by Color.getTransform().</b><p>
+* 			Takes one object with both, the offset and percentage values for a movieclip's 
+* 			red, green, blue and alpha components. The properties can be: 
+* 			ra, rb, ga, gb, ba, bb, aa, ab. Take a look into the Color 
+* 			class of your Flash manual for more information about the properties
+* 			of the Color transformObject or get <a href="http://www.moock.org">Colin Moock's</a> 
+* 			ASDG for an in depth discussion. The transformationObject doesn't need to be complete. 
+* 			If you haven't specified some of the eight properties, ColorTransform will retrieve the 
+* 			missing color properties from the current color of your movieclip. Way no. 2 offers more 
+* 			complex color manipulations than way no. 1, since you have access to all single 
+* 			offset and percentage values of the movieclip including the alpha components.<p>
+*  
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1a: Way no. 1
+* 			<blockquote><pre>			
+*			var myCT:ColorTransform = new ColorTransform(mc);
+*			myCT.animationStyle(3000,Quad.easeOut,"onCallback");
+*			myCT.run(0xff0000,50);
+*			</pre></blockquote> 
+* 			Example 1b: Way no. 2
+* 			<blockquote><pre>			
+*			var myCT:ColorTransform = new ColorTransform(mc);
+*			myCT.animationStyle(3000,Quad.easeOut,"onCallback");
+*			var brightRed:Object = {ra:50,rb:255,ga:50,gb:0,ba:50,bb:0,aa:100,ab:0};
+*			myCT.run(brightRed);
+*			</pre></blockquote>
+* 			Note that 
+* 			<pre><blockquote>
+* 			var brightRed:Object = {ra:50,rb:255,ga:50,gb:0,ba:50,bb:0,aa:100,ab:0}; 			
+* 			</pre></blockquote>
+* 			is just another syntax for
+* 			<pre><blockquote>
+* 			var brightRed:Object = new Object();
+* 			brightRed.ra = 50;
+* 			brightRed.rb = 255;
+* 			brightRed.ga = 50;
+* 			brightRed.gb = 0;
+* 			brightRed.ba = 50;
+* 			brightRed.bb = 0;
+* 			brightRed.aa = 100;
+* 			brightRed.ab = 0; 			
+* 			</pre></blockquote> 			
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new ColorTransform(mc).run(0xff0000,50,3000,Quad.easeOut,"onCallback");
+* 			</pre></blockquote>
+*  			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end paremeters might also be useful. 
+* 			<blockquote><pre>
+* 			var myColorTransform:ColorTransform = new ColorTransform(mc,0xff0000,50,2000,Circ.easeInOut,"onCallback");
+* 			myColorTransform.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValues or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+* 			<blockquote><pre>
+*			var myCT:ColorTransform = new ColorTransform(mc,[0x0000ff,20,0xff0000,20],3000,Quad.easeOut);
+*			myCT.run();
+* 			</pre></blockquote>	
+*  			<p> 
+* 			Example 5: Transform the color of a movieclip to an opaque red tone
+* 			using default animationStyle properties (1 second, using linear easing). 
+* 			<blockquote><pre>
+*			var myCT:ColorTransform = new ColorTransform(mc);
+*			myCT.run(0xff0000,0);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 6: <a href="ColorTransform_run_02.html">(Example .swf)</a> Colorize a movieclip to red with 50 percentage and then to green
+* 			with 50 percentage in 6 seconds using Quad easing. Note that I nullify 
+* 			the callback property, which would call the onCallback method again. 
+* 			<blockquote><pre>			
+*			var myCT:ColorTransform = new ColorTransform(mc);
+*			myCT.animationStyle(3000,Quad.easeOut,"onCallback");
+*			myCT.run(0xff0000,50);
+*			myListener.onCallback = function() {	
+*				myCT.callback = null;
+*				myCT.run(0x00ff00,50);	
+*			}
+*			</pre></blockquote>
+* 			<p>
+* 			Example 7: Use the transformationObject to fade a movieclip from 
+* 			opaque red to opaque green in 3 seconds.
+* 			<blockquote><pre>
+*			var myCT:ColorTransform = new ColorTransform(mc);
+*			myCT.animationStyle(3000);
+*			//Note that you don't have to specify all of the possible properties in the tansformationObject.
+* 			//ColorTransform will retrieve the missing properties from your current movieclip.
+*			var red:Object = {ra:0,rb:255,ga:0,gb:0,ba:0,bb:0};
+*			var green:Object = {ra:0,rb:0,ga:0,gb:255,ba:0,bb:0};
+*			
+*			myCT.setStartValues([red]);
+*			myCT.setEndValues([green]);			
+*			myCT.run();
+*			</pre></blockquote>
+* 			<p>
+* 			Example 8: Do the same like in example 7 just use way no. 1. Notice that I listen to all 
+* 			events from ColorTransform (onStart, onUpdate and onEnd). Inside the handler methods you 
+* 			can access the color values of the current state of the animation. There are two ways to 
+* 			accomblish this. One way is to ask the "value" property of the eventObject 
+* 			send by EventDispatcher. 
+* 			See addEventListener documentation. Another way is to ask the getStartValues, getCurrentValues 
+* 			and getEndValues methods of ColorTransform. This way you can access the color values depending 
+* 			on how you initialized ColorTransform. See getStartValues documentation for more information. 
+* 			Notice that in this example I modify the result of getCurrentValues method 
+* 			inside the onUpdate handler in order to trace hexadecimal numbers instead of decimal numbers. 
+* 			
+* 			<blockquote><pre>
+*			var myCT:ColorTransform = new ColorTransform(mc);
+*			myCT.animationStyle(3000);
+*			myCT.setStartValues([0xff0000,0]);
+*			myCT.setEndValues([0x00ff00,0]);
+*			myCT.addEventListener("onStart",this);
+*			myCT.addEventListener("onUpdate",this);
+*			myCT.addEventListener("onEnd",this);
+*			myCT.run();
+*			
+*			function onStart(eventObject:Object){	
+*				trace("onStart "+eventObject.value);
+*				trace("getStartValues "+myCT.getStartValues());
+*			}
+*			function onUpdate(eventObject:Object){	
+*				trace("onUpdate "+eventObject.value);
+*				var currentValues:Array = myCT.getCurrentValues();
+*				var rgbNumber:Number = currentValues[0];
+*				var hexrgb:String = rgbNumber.toString(16);
+*				trace("getCurrentValues "+hexrgb);
+*			}
+*			function onEnd(eventObject:Object){
+*				trace("onEnd "+eventObject.value);
+*				trace("getEndValues "+myCT.getEndValues());	
+*			}
+*			</pre></blockquote>
+* 			Example 9: To animate many movieclips the same way, this class also accepts 
+* 			an Array of movieclips instead of one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want to animate. Different 
+* 			start values of your movieclip properties are considered when animating multiple movieclips 
+* 			within one animation instance.
+* 			<blockquote><pre>
+* 			var mcs:Array = new Array(mc1,mc2,mc3);
+*			var myCT:ColorTransform = new ColorTransform(mcs);
+*			myCT.setOptimizationMode(true);
+*			myCT.animationStyle(3000);
+*			var red:Object = {ra:0,rb:255,ga:0,gb:0,ba:0,bb:0};
+*			var green:Object = {ra:0,rb:0,ga:0,gb:255,ba:0,bb:0};
+*			myCT.setStartValues([red]);
+*			myCT.setEndValues([green]);
+*			myCT.run();
+* 			</pre></blockquote>
+* 
+* 			<p>
+*  
+* @usage 
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mc);</pre> 
+*		<pre>var myCT:ColorTransform = new ColorTransform(mc, rgb, percentage);</pre>
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mc, rgb, percentage, duration);</pre>
+*		<pre>var myCT:ColorTransform = new ColorTransform(mc, rgb, percentage, duration, callback);</pre>
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mc, rgb, percentage, duration, easing, callback);</pre>
+*		<pre>var myCT:ColorTransform = new ColorTransform(mc, transformationObject);</pre>
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mc, transformationObject, duration);</pre>
+*		<pre>var myCT:ColorTransform = new ColorTransform(mc, transformationObject, duration, callback);</pre>
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mc, transformationObject, duration, easing, callback);</pre>
+*		<pre>var myCT:ColorTransform = new ColorTransform(mc, values);</pre> 
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mc, values, duration, callback);</pre> 
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mc, values, duration, easing, callback);</pre> 
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mcs);</pre> 
+*		<pre>var myCT:ColorTransform = new ColorTransform(mcs, rgb, percentage);</pre>
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mcs, rgb, percentage, duration);</pre>
+*		<pre>var myCT:ColorTransform = new ColorTransform(mcs, rgb, percentage, duration, callback);</pre>
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mcs, rgb, percentage, duration, easing, callback);</pre>
+*		<pre>var myCT:ColorTransform = new ColorTransform(mcs, transformationObject);</pre>
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mcs, transformationObject, duration);</pre>
+*		<pre>var myCT:ColorTransform = new ColorTransform(mcs, transformationObject, duration, callback);</pre>
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mcs, transformationObject, duration, easing, callback);</pre>
+*		<pre>var myCT:ColorTransform = new ColorTransform(mcs, values);</pre> 
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mcs, values, duration, callback);</pre> 
+* 		<pre>var myCT:ColorTransform = new ColorTransform(mcs, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param rgb (Number) Targeted color value (as a hex number) to animated to. 
+* @param percentage (Number) Targeted percentage value to animated to. 0 is opaque. (-255 - 255).
+* @param transformationObject (Object) Targeted amounts to animate to. Same transformationObject like returned from the build-in Color.getTransfrom().
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation
+*/
+class de.alex_uhlmann.animationpackage.animation.ColorTransform 
+											extends AnimationCore 
+											implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	private var myCTK:ColorToolkit;
+	private var colorTransformMode:Boolean = false;
+	private var startRGB:Number;
+	private var startPercentage:Object;
+	private var endRGB:Number;
+	private var endPercentage:Number;
+	private var transformObject:Object;
+	private var hasStartValues:Boolean;
+	private var overwriteProperty:String = "movieclip";
+	
+	public function ColorTransform() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+			this.myCTK = new ColorToolkit(this.mc);
+		} else {
+			this.mcs = arguments[0];
+			this.myCTK = new ColorToolkit(this.mcs[0]);
+		}
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}		
+	}
+	
+	private function init():Void {
+		if(arguments[0] instanceof Array) {				
+			var values:Array = arguments[0];
+			if(values.length == 4) {
+				var endValues:Array = values.slice(-2);
+				arguments.shift();
+				arguments.splice(0, 0, endValues[0], endValues[1]);
+				this.initAnimation.apply(this, arguments);
+				this.setStartValues([values[0], {r:values[1], 
+													g:values[1], 
+													b:values[1], 
+													a:values[1]}]);
+			} else {
+				var endValues:Array = values.slice(-1);
+				arguments.shift();
+				arguments.splice(0, 0, endValues[0]);
+				this.initAnimation.apply(this, arguments);				
+				this.setStartValues([values[0]]);					
+			}
+		} else if(arguments.length > 0) {			
+			this.initAnimation.apply(this, arguments);
+		}		
+	}
+	
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		if(startValues[0] instanceof Object) {
+			
+			this.colorTransformMode = true;
+			var colorObj:Object = this.transformObject = this.myCTK.getTransform();
+			var obj:Object = startValues[0];			
+			var p:String;
+			for(p in obj) {				
+				colorObj[p] = obj[p];				
+			}
+			if(optional) {
+				this.hasStartValues = false;
+			} else {
+				this.hasStartValues = true;
+			}
+			return super.setStartValues([colorObj.ra, colorObj.rb, 
+										colorObj.ga, colorObj.gb, 
+										colorObj.ba, colorObj.bb, 
+										colorObj.aa, colorObj.ab], optional);						
+		} else if(startValues.length == 2) {
+					
+			this.colorTransformMode = false;
+			this.startRGB = startValues[0];
+			if(typeof(startValues[1]) == "number") {
+				this.startPercentage = {r:startValues[1], g:startValues[1], b:startValues[1]};
+			} else {
+				this.startPercentage = startValues[1];
+			}			
+			var startRGB:Object = this.myCTK.hexrgb2rgb(this.startRGB);
+			var startPercentage:Object = this.startPercentage;
+			return super.setStartValues([startPercentage.r, startRGB.r, 
+										startPercentage.g, startRGB.g, 
+										startPercentage.b, startRGB.b, 
+										100, 0], optional);									
+		} else {
+			return super.setStartValues.apply(this,arguments);
+		}					
+	}
+	
+	public function setEndValues(endValues:Array):Boolean {
+		if(endValues[0] instanceof Object) {			
+			
+			this.colorTransformMode = true;
+			var colorObj:Object = this.myCTK.getTransform();
+			var obj:Object = endValues[0];
+			var p:String;
+			for(p in obj) {				
+				colorObj[p] = obj[p];				
+			}			
+			return super.setEndValues([colorObj.ra, colorObj.rb, 
+										colorObj.ga, colorObj.gb, 
+										colorObj.ba, colorObj.bb, 
+										colorObj.aa, colorObj.ab]);						
+		} else if(endValues.length == 2) {
+			
+			this.colorTransformMode = false;
+			this.endRGB = endValues[0];
+			this.endPercentage = endValues[1];
+			var endRGB:Object = this.myCTK.hexrgb2rgb(this.endRGB);;
+			var endPercentage:Number = this.endPercentage;
+			return super.setEndValues([endPercentage, endRGB.r, 
+										endPercentage, endRGB.g, 
+										endPercentage, endRGB.b, 
+										100, 0]);		
+		} else {
+			return super.setEndValues.apply(this,arguments);
+		}				
+	}
+	
+	/*
+	* If the user specified one offset and one percentage 
+	* value, only the percentage value of red will be returned. As soon as the ColorTransform 
+	* modifies the movieclip all percentage values will have the same value anyway in this 
+	* mode.
+	*/
+	public function getStartValues(Void):Array {		
+		if(this.colorTransformMode == false && this.mc != null) {
+			return [this.startRGB, this.startPercentage.r];			
+		}
+		return this.startValues;			
+	}
+	
+	public function getCurrentValues(Void):Array {		
+		if(this.colorTransformMode == false && this.mc != null) {
+			var colors:Array = this.currentValues;			
+			var currentRGB:Number = this.myCTK.rgb2hexrgb(colors[1], colors[3], colors[5]);
+			var currentPercentage:Number = colors[0];
+			return [currentRGB, currentPercentage];			
+		}
+		return this.currentValues;		
+	}
+	
+	public function getEndValues(Void):Array {		
+		if(this.colorTransformMode == false && this.mc != null) {
+			return [this.endRGB, this.endPercentage];			
+		}
+		return this.endValues;			
+	}
+	
+	private function initAnimation():Void {		
+		if(arguments[0] instanceof Object) {
+			
+			if(arguments.length > 1) {			
+				this.animationStyle(arguments[1], arguments[2], arguments[3]);
+			} else {
+				this.animationStyle(this.duration, this.easing, this.callback);
+			}
+			
+			this.setStartValues([this.myCTK.getTransform()], true);
+			this.setEndValues([arguments[0]]);			
+		
+		} else {			
+			
+			if(arguments.length > 2) {			
+				this.animationStyle(arguments[2], arguments[3], arguments[4]);
+			} else {
+				this.animationStyle(this.duration, this.easing, this.callback);
+			}
+			
+			this.setStartValues([this.myCTK.getColorOffsetHex(), this.myCTK.getColorPercent()], true);
+			this.setEndValues([arguments[0], arguments[1]]);	
+		}	
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		
+		this.startInitialized = false;
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = this.endValues;
+		
+		if(this.mc != null) {
+			//colorize movieclip right away when a fixed start value has been set.
+			if(this.colorTransformMode) {
+				this.myCTK.setTransform(this.transformObject);		
+			}			
+			this.myAnimator.start = this.startValues;				
+			this.myAnimator.setter = [[this.myCTK, "setRedPercent"], 
+								[this.myCTK, "setRedOffset"], 
+								[this.myCTK, "setGreenPercent"], 
+								[this.myCTK, "setGreenOffset"], 
+								[this.myCTK, "setBluePercent"], 
+								[this.myCTK, "setBlueOffset"],
+								[this.myCTK, "setAlphaPercent"], 
+								[this.myCTK, "setAlphaOffset"]];		
+		} else {
+			
+			var myCTKs:Array = [];
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			if(this.colorTransformMode == true && this.hasStartValues == true) {
+				while(--i>-1) {
+					myCTKs[i] = new ColorToolkit(this.mcs[i]);
+					myCTKs[i].setTransform(this.transformObject);
+				}				
+			} else {
+				while(--i>-1) {
+					myCTKs[i] = new ColorToolkit(this.mcs[i]);
+				}				
+			}
+			
+			this.myAnimator.multiStart = ["getRedPercent", 
+									"getRedOffset", 
+									"getGreenPercent",
+									"getGreenOffset", 
+									"getBluePercent", 
+									"getBlueOffset",
+									"getAlphaPercent", 
+									"getAlphaOffset"];			
+			
+			this.myAnimator.multiSetter = [[myCTKs, "setRedPercent"], 
+									[myCTKs, "setRedOffset"], 
+									[myCTKs, "setGreenPercent"],
+									[myCTKs, "setGreenOffset"], 
+									[myCTKs, "setBluePercent"], 
+									[myCTKs, "setBlueOffset"],
+									[myCTKs, "setAlphaPercent"],
+									[myCTKs, "setAlphaOffset"]];
+		}
+		
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}	
+		
+	}
+	
+	/**
+	* @method run
+	* @description 	manipulates the color of a movieclip in a specified time and easing equation. 
+	* 				See class documentation.
+	* @usage   
+	* 
+	* 		<pre>myCT.run();</pre>
+	* 		<pre>myCT.run(rgb, percentage);</pre>
+	* 		<pre>myCT.run(rgb, percentage, duration);</pre>
+	*		<pre>myCT.run(rgb, percentage, duration, callback);</pre>
+	* 		<pre>myCT.run(rgb, percentage, duration, easing, callback);</pre>
+	* 		<pre>myCT.run(transformationObject);</pre>
+	* 		<pre>myCT.run(transformationObject, duration);</pre>
+	*		<pre>myCT.run(transformationObject, duration, callback);</pre>
+	* 		<pre>myCT.run(transformationObject, duration, easing, callback);</pre> 
+	* 		<pre>myCT.run(values, duration);</pre>
+	* 		<pre>myCT.run(values, duration, callback);</pre>
+	*		<pre>myCT.run(values, duration, easing, callback);</pre>
+	* 	  
+	* @param rgb (Number) Targeted color value (as a hex number) to animated to. 
+	* @param percentage (Number) Targeted percentage value to animated to. 0 is opaque. (-255 - 255).
+	* @param transformationObject (Object) Targeted amounts to animate to. Same transformationObject like returned from the build-in Color.getTransfrom().	
+	* @param values (Array) optional start and end values.	
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation
+	* @return void
+	*/	
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myCT.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.		
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/	
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValues
+	* @description 	returns the original, starting values of the current tween. 
+	* 				The values returned depend on how you used/started the ColorTransform class.
+	* 				If you used one offset value (i.e. in form of a hexadecimal number) 
+	* 				and one percentage number to initialize ColorTransform, 
+	* 				the offset and percentage numbers will be returned by this method. 				
+	* 				If you've used a transformObject to initialize ColorTransform, 
+	*				the values returned are all properties of the transformObject 
+	* 				of the Color class. They are returned in an array of the following order: 
+	* 				From 0 - 7:  ra, rb, ga, gb, ba, bb, aa, ab. Take a look into the Color 
+	* 				class of your Flash manual for more information about the properties
+	* 				of the Color transformObject or get <a href="http://www.moock.org">Colin Moock's</a> 
+	* 				ASDG for an in depth discussion.
+	* @usage   <tt>myInstance.getStartValues();</tt>
+	* @return (Array)
+	*/
+	
+	/**
+	* @method setStartValues
+	* @description 	sets the original, starting values of the current tween. See class documentation.				
+	* @usage   <tt>myInstance.setStartValues(startValues);</tt>
+	* @param startValues (Array)
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValues
+	* @description 	returns the targeted values of the current tween.
+	* 				The values returned depend on how you used/started the ColorTransform class.
+	* 				See getStartValues for more information.
+	* @usage   <tt>myInstance.getEndValues();</tt>
+	* @return (Array)
+	*/
+	
+	/**
+	* @method setEndValues
+	* @description 	sets the targeted value of the current tween. See class documentation.
+	* @usage   <tt>myInstance.setEndValues(endValues);</tt>
+	* @param endValues (Array)
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+
+	/**
+	* @method getCurrentValues
+	* @description 	returns the current values of the current tween.
+	* 				The values returned depend on how you used/started the ColorTransform class.
+	* 				See getStartValues for more information.
+	* @usage   <tt>myInstance.getCurrentValues();</tt>
+	* @return (Array)
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Array) values to animate. See getStartValues and class documentation.<p>
+	* 		
+	* @usage   <pre>myCT.addEventListener(event, listener);</pre>
+	* 		    <pre>myCT.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myCT.removeEventListener(event, listener);</pre>
+	* 		    <pre>myCT.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myCT.removeAllEventListeners();</pre>
+	* 		    <pre>myCT.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myCT.eventListenerExists(event, listener);</pre>
+	* 			<pre>myCT.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "ColorTransform";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ColorTransform.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/DropShadow.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/DropShadow.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/DropShadow.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,890 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.Filter;
+import flash.filters.BitmapFilter;
+import flash.filters.DropShadowFilter;
+
+/**
+* @class DropShadow
+* @author Alex Uhlmann
+* @description  Animates the DropShadowFilter of a movieclip 
+* 			or a number of movieclips. 
+* 			<p>	
+* 			Example 1: <a href="DropShadow_01.html">(Example .swf)</a> 
+* 			apply a filter animation with default values. 
+* 
+* 			<blockquote><pre>
+* 			import flash.filters.DropShadowFilter;
+* 			
+*			var filterEnd:DropShadowFilter = new DropShadowFilter();
+*			new DropShadow(mc,filterEnd).animate(0,100);
+* 			</pre></blockquote>
+* 			<p>	
+* 			Example 2: <a href="DropShadow_02.html">(Example .swf)</a> 
+* 			do the same, just the other way around
+* 
+* 			<blockquote><pre>
+* 			import flash.filters.DropShadowFilter;
+* 			
+*			var filterEnd:DropShadowFilter = new DropShadowFilter();
+*			new DropShadow(mc,filterEnd).animate(100,0);
+* 			</pre></blockquote>
+* 			<p>	
+* 			Example 3: <a href="DropShadow_02.html">(Example .swf)</a> 
+* 			As with other IAnimatable classes 
+* 			you can set specific start and end values. To do the same as 
+* 			in example 2 you can apply a default filter instance 
+* 			as start value and a "null" value as end value. null 
+* 			defines a filter instance that won't be visible.
+* 
+* 			<blockquote><pre>
+* 			import flash.filters.DropShadowFilter;
+* 			
+*			var filterStart:DropShadowFilter = new DropShadowFilter();
+*			var myDropShadow:DropShadow = new DropShadow(mc,[filterStart,null]);
+*			myDropShadow.animationStyle(1000,Linear.easeNone);
+*			myDropShadow.animate(0,100);
+* 			</pre></blockquote>
+* 			<p>		
+* 			Example 4: <a href="DropShadow_03.html">(Example .swf)</a> 
+* 			Instances of the flash.filters classes are stacked 
+* 			to the filters Array of the movieclip you use. AnimationPackage 
+* 			offers you control if you want to animate existing 
+* 			filters, if you want to create a new filter, or replace an 
+* 			existing filter. By default, and in the examples above, we've 
+* 			always added a new filter instance to our movieclip mc. If 
+* 			you want to animate an existing filter you have to specify the 
+* 			index of the element in the movieclip's filters Array you 
+* 			want to manipulate. This example applies two different filters 
+* 			to the filters Array of movieclip mc and then animates element 1, 
+* 			which is the DropShadowFilter. You would replace the GlowFilter 
+* 			at index 0 and add new filter with specifying either no filterIndex 
+* 			as in the examples above or an index higher than 1.
+* 			<blockquote><pre>
+* 			import flash.filters.GlowFilter;
+* 			import flash.filters.DropShadowFilter;
+* 			
+*			var glowFilter:GlowFilter = new GlowFilter();
+*			mc.filters = [glowFilter];
+*			var dropShadowFilter:DropShadowFilter = new DropShadowFilter();
+*			mc.filters = [glowFilter,dropShadowFilter];
+*			
+*			var newDropShadowFilter:DropShadowFilter = new DropShadowFilter();
+*			newDropShadowFilter.distance = 60;
+*			var myDropShadowIn:DropShadow = new DropShadow(mc,1,newDropShadowFilter);
+*			myDropShadowIn.animationStyle(1000,Circ.easeInOut);
+*			myDropShadowIn.addEventListener("onEnd",this);
+*			myDropShadowIn.animate(0,100);
+* 			</pre></blockquote>
+* 
+* 			<p>
+* 			Example 5: <a href="DropShadow_04.html">(Example .swf)</a> 
+* 			Filter classes can have properties 
+* 			that don't animate. You can set those properties either 
+* 			as start value to the flash.filters instance or 
+* 			to AnimationPackage's filter class itself as 
+* 			done in this example. When the animation is invoked  
+* 			the property will be applied. In the following we apply the knockout 
+* 			property directly to the DropShadow instance. Only distance, blurX and blurY 
+* 			will animate.
+* 			<blockquote><pre>
+*			import flash.filters.DropShadowFilter;
+*			
+*			var filterEnd:DropShadowFilter = new DropShadowFilter();
+*			filterEnd.distance = 8;
+*			filterEnd.blurX = 15;
+*			filterEnd.blurY = 15;
+*			var myDropShadow:DropShadow = new DropShadow(mc,filterEnd);
+*			myDropShadow.knockout = true;
+*			myDropShadow.animationStyle(3000,Sine.easeInOut);
+*			myDropShadow.animate(0,100);
+* 			</pre></blockquote>
+*			<p>
+* 			Example 6: <a href="DropShadow_05.html">(Example .swf)</a> 
+* 			To animate many movieclips the same way, 
+* 			this class also accepts an Array of movieclips instead of 
+* 			one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want 
+* 			to animate. Different start values of your movieclip 
+* 			properties are considered when animating multiple movieclips 
+* 			within one animation instance. Here, we animate a drop shadow 
+* 			in and out.
+* 			<blockquote><pre>
+*			import flash.filters.DropShadowFilter;
+*			
+*			var mcs:Array = new Array(mc1, mc2, mc3);
+*			
+*			var dropShadowFilter:DropShadowFilter = new DropShadowFilter();
+*			var myDropShadowIn:DropShadow = new DropShadow(mcs,dropShadowFilter);
+*			myDropShadowIn.setOptimizationMode(true);
+*			myDropShadowIn.animationStyle(1000,Circ.easeOut);
+*			myDropShadowIn.addEventListener("onEnd",this);
+*			myDropShadowIn.animate(0,100);
+*			function onEnd(e:Object) {
+*				var myDropShadowOut:DropShadow = new DropShadow(mcs,0,null);
+*				myDropShadowOut.animationStyle(1000,Circ.easeIn);
+*				myDropShadowOut.animate(0,100);
+*			}
+*
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 7: <a href="DropShadow_06.html">(Example .swf)</a> 
+* 			Showcase some of the DropShadow features in 
+* 			a Sequence.
+* 			<blockquote><pre>
+* 				import flash.filters.DropShadowFilter;
+*				
+*				var filter1:DropShadowFilter = new DropShadowFilter();
+*				var myDropShadow1:DropShadow = new DropShadow(mc,filter1);
+*				
+*				var filter2:DropShadowFilter = new DropShadowFilter();
+*				filter2.distance = 50;
+*				var myDropShadow2:DropShadow = new DropShadow(mc,filter2);
+*				myDropShadow2.setStartValues([dropShadowFilter1]);
+* 
+*				var filter3:DropShadowFilter = new DropShadowFilter();
+*				filter3.distance = 4;
+*				var myDropShadow3:DropShadow = new DropShadow(mc,filter3);
+*				myDropShadow3.setStartValues([dropShadowFilter2]);
+* 
+*				var filter4:DropShadowFilter = new DropShadowFilter();
+*				filter4.angle = 180;
+*				var myDropShadow4:DropShadow = new DropShadow(mc,filter4);
+*				myDropShadow4.setStartValues([dropShadowFilter3]);
+* 
+*				var filter5:DropShadowFilter = new DropShadowFilter();
+*				filter5.angle = 45;
+*				filter5.blurX = 20;
+*				filter5.blurY = 20;
+*				var myDropShadow5:DropShadow = new DropShadow(mc,filter5);
+*				myDropShadow5.setStartValues([dropShadowFilter4]);
+* 
+*				var filter6:DropShadowFilter = new DropShadowFilter();
+*				filter6.strength = 4;
+*				filter6.alpha = 50;
+*				var myDropShadow6:DropShadow = new DropShadow(mc,filter6);
+*				myDropShadow6.setStartValues([dropShadowFilter5]);
+* 
+*				var mySequence:Sequence = new Sequence();
+*				mySequence.addChild(myDropShadow1);
+*				mySequence.addChild(myDropShadow2);
+*				mySequence.addChild(myDropShadow3);
+*				mySequence.addChild(myDropShadow4);
+*				mySequence.addChild(myDropShadow5);
+*				mySequence.addChild(myDropShadow6);
+*				
+*				mySequence.addEventListener("onEnd",this,"knockout");
+*				mySequence.animationStyle(3000,Circ.easeInOut);
+*				mySequence.animate(0,100);
+*				
+*				var innerStatus:Text = new Text();
+*				innerStatus.setText("inner "+false,0,0);
+*				var knockoutStatus:Text = new Text();
+*				knockoutStatus.setText("knockout "+false,0,15);
+*				var hideObjectStatus:Text = new Text();
+*				hideObjectStatus.setText("hideObject "+false,0,30);
+*				
+*				function knockout(e:Object) {	
+*					innerStatus.updateText("inner "+false);
+*					knockoutStatus.updateText("knockout "+true);
+*					hideObjectStatus.updateText("hideObject "+false);
+*				
+*					var children:Array = mySequence.getChildren();
+*					for(var i:Number=0; i &lt; children.length; i++) {
+*						children[i].inner = false;
+*						children[i].knockout = true;
+*						children[i].hideObject = false;
+*					}
+*					mySequence.removeEventListener("onEnd",this,"knockout");
+*					mySequence.addEventListener("onEnd",this,"inner");
+*					mySequence.animate(0,100);
+*				}
+*				
+*				function inner(e:Object) {
+*					innerStatus.updateText("inner "+true);
+*					knockoutStatus.updateText("knockout "+false);
+*					hideObjectStatus.updateText("hideObject "+false);
+*					
+*					var children:Array = mySequence.getChildren();
+*					for(var i:Number=0; i &lt; children.length; i++) {
+*						children[i].knockout = false;
+*						children[i].inner = true;
+*						children[i].hideObject = false;
+*					}
+*					mySequence.removeEventListener("onEnd",this,"inner");
+*					mySequence.addEventListener("onEnd",this,"innerAndKnockout");
+*					mySequence.animate(0,100);
+*				}
+*				function innerAndKnockout(e:Object) {
+*					innerStatus.updateText("inner "+true);
+*					knockoutStatus.updateText("knockout "+true);
+*					hideObjectStatus.updateText("hideObject "+false);
+*					
+*					var children:Array = mySequence.getChildren();
+*					for(var i:Number=0; i &lt; children.length; i++) {
+*						children[i].inner = true;
+*						children[i].knockout = true;
+*						children[i].hideObject = false;
+*					}
+*					mySequence.removeEventListener("onEnd",this,"innerAndKnockout");
+*					mySequence.addEventListener("onEnd",this,"hideObject");
+*					mySequence.animate(0,100);
+*				}
+*				
+*				function hideObject(e:Object) {
+*					innerStatus.updateText("inner "+false);
+*					knockoutStatus.updateText("knockout "+false);
+*					hideObjectStatus.updateText("hideObject "+true);	
+*					
+*					var children:Array = mySequence.getChildren();
+*					for(var i:Number=0; i &lt; children.length; i++) {
+*						children[i].inner = false;
+*						children[i].knockout = false;		
+*						children[i].hideObject = true;
+*					}
+*					mySequence.removeEventListener("onEnd",this,"hideObject");
+*					mySequence.addEventListener("onEnd",this,"original");
+*					mySequence.animate(0,100);
+*				}
+*				
+*				function original(e:Object) {
+*					innerStatus.updateText("inner "+false);
+*					knockoutStatus.updateText("knockout "+false);
+*					hideObjectStatus.updateText("hideObject "+false);		
+*					
+*					var children:Array = mySequence.getChildren();
+*					for(var i:Number=0; i &lt; children.length; i++) {
+*						children[i].inner = false;
+*						children[i].knockout = false;		
+*						children[i].hideObject = false;
+*					}
+*					mySequence.removeEventListener("onEnd",this,"original");
+* 					mySequence.addEventListener("onEnd",this,"knockout");
+*					mySequence.animate(0,100);
+*				}
+* 			</pre></blockquote>
+*
+* @usage      
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:DropShadow = new DropShadow(mc, values);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc, values, duration, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:DropShadow = new DropShadow(mc, filterIndex, values);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mc, filterIndex, values, duration, easing, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:DropShadow = new DropShadow(mcs, values);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs, values, duration, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:DropShadow = new DropShadow(mcs, filterIndex, values);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:DropShadow = new DropShadow(mcs, filterIndex, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param filterIndex (Number) position of the element in the Movieclip's filter property that shall be manipulated.
+* @param filter (DropShadowFilter) Targeted DropShadowFilter object to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.DropShadow 
+											extends Filter 
+											implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property filterIndex (Number)
+	* @property filters (Array)
+	* @property color (Number) 
+	* @property quality (Number)
+	* @property inner (Boolean)
+	* @property knockout (Boolean) 
+	* @property hideObject (Boolean) 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public var filter:DropShadowFilter;
+	private var m_color:Number = 0x000000;
+	private var m_quality:Number = 1;
+	private var m_inner:Boolean = false;
+	private var m_knockout:Boolean = false;
+	private var m_hideObject:Boolean = false;
+
+	public function DropShadow() {
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		arguments.shift();
+		this.init.apply(this, arguments);
+	}
+
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		this.hasStartValues = optional ? false : true;
+		
+		if(startValues[0] == null) {
+			startValues[0] = createEmptyFilter();
+		}
+		if(startValues[0] instanceof DropShadowFilter) {			
+			var filter:DropShadowFilter = startValues[0];
+			
+			if(this.hasStartValues) {
+				this.setNonAnimatedProperties(filter);
+			}
+			
+			return super.setStartValues([filter.distance, filter.angle, 
+										filter.alpha, filter.blurX, 
+										filter.blurY, filter.strength], optional);			
+		} else {
+			return super.setStartValues(startValues, optional);
+		}
+	}
+	
+	public function setEndValues(endValues:Array):Boolean {
+		
+		if(endValues[0] == null) {
+			endValues[0] = createEmptyFilter();
+		}
+		if(endValues[0] instanceof DropShadowFilter) {
+			
+			var filter:DropShadowFilter = endValues[0];
+			this.setNonAnimatedProperties(filter);
+			
+			return super.setEndValues([filter.distance, filter.angle, 
+										filter.alpha, filter.blurX, 
+										filter.blurY, filter.strength]);		
+		} else {
+			return super.setEndValues(endValues);
+		}
+
+	}
+	
+	private function initAnimation(filterIndex:Number, filterEnd:DropShadowFilter, 
+							duration:Number, easing:Object, callback:String):Void {
+
+		if(arguments.length > 2) {
+			this.animationStyle(duration, easing, callback);
+		} else {			
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}	
+		
+		this.initializeFilter(filterIndex, filterEnd);
+		
+		this.setStartValues([this.filter], true);
+		this.setEndValues([filterEnd]);
+	}
+	
+	private function initializeFilter(filterIndex:Number, filterEnd:DropShadowFilter):Void {		
+		if(this.mc != null) {	
+			
+			if(filterIndex == null) {				
+				
+				this.filter = this.createEmptyFilter();
+				this.addFilter(this.filter);
+				
+			} else {			
+				
+				//if no filter of correct type is found at filterIndex, 
+				//a new filter will be created.
+				this.modifyOrCreateFilter(filterIndex);
+			}
+			
+		} else {
+			
+			this.filterIndex = filterIndex;
+			this.filter = filterEnd;
+			
+		}
+	}
+	
+	
+	private function modifyOrCreateFilter(filterIndex:Number):Void {		
+		this.filter = DropShadowFilter(this.findFilter(filterIndex));
+		this.filters = this.mc.filters;
+		this.filterIndex = filterIndex;
+	}
+
+	private function isFilterOfCorrectType(filter:BitmapFilter):Boolean {
+		return (filter instanceof DropShadowFilter == true);
+	}
+	
+	private function createEmptyFilter(Void):DropShadowFilter {
+		var filter:DropShadowFilter = new DropShadowFilter();
+		filter.distance = 0;
+		filter.angle = 0;
+		filter.alpha = 0;
+		filter.blurX = 0;
+		filter.blurY = 0;
+		filter.strength = 0;
+		return filter;
+	}
+	
+	private function initSingleMC(Void):Void {
+		this.myAnimator.start = this.startValues;
+		
+		if(this.getOptimizationMode() 
+			&& this.myAnimator.hasEquivalents()) {
+				
+			this.myAnimator.setter = [[this,"setDistance"],
+								[this,"setAngle"],
+								[this,"setAlpha"],
+								[this,"setBlurX"],
+								[this,"setBlurY"],
+								[this,"setStrength"]];							
+		} else {				
+			this.myAnimator.setter = [[this,"setShadow"]];	
+		}
+	}
+	
+	private function initMultiMC(Void):Void {
+		var myInstances:Array = [];			
+		var len:Number = this.mcs.length;
+		var mcs:Array = this.mcs;
+		var i:Number = len;
+		while(--i>-1) {
+			myInstances[i] = new DropShadow(mcs[i],this.filterIndex,this.filter);			
+			var filter:DropShadowFilter = this.updateFilter(createEmptyFilter());
+			myInstances[i].setNonAnimatedProperties(filter);
+		}
+		this.myInstances = myInstances;
+
+		this.myAnimator.multiStart = ["getMultiDistanceValue","getMultiAngleValue",
+									"getMultiAlphaValue","getMultiBlurXValue",
+									"getMultiBlurYValue","getMultiStrengthValue"];
+									
+		this.myAnimator.multiSetter = [[this.myInstances,"setDistance"],
+									[this.myInstances,"setAngle"],
+									[this.myInstances,"setAlpha"],
+									[this.myInstances,"setBlurX"],
+									[this.myInstances,"setBlurY"],
+									[this.myInstances,"setStrength"]];	
+
+	}
+	
+	private function updateFilter(filter:DropShadowFilter):DropShadowFilter {		
+		filter.color = this.m_color;
+		filter.quality = this.m_quality;
+		filter.inner = this.m_inner;
+		filter.knockout = this.m_knockout;
+		filter.hideObject = this.m_hideObject;		
+		return filter;
+	}
+	
+	private function updateProperties(filter:BitmapFilter):Void {
+		this.filter = updateFilter(DropShadowFilter(filter));
+		this.setStartValues([this.filter], true);		
+	}
+	
+	private function setNonAnimatedProperties(filter:DropShadowFilter):Void {
+		this.color = filter.color;
+		this.quality = filter.quality;
+		this.inner = filter.inner;
+		this.knockout = filter.knockout;
+		this.hideObject = filter.hideObject;
+	}	
+	
+	public function getMultiDistanceValue(Void):Number {
+		return this.filter.distance;
+	}	
+	
+	public function getMultiAngleValue(Void):Number {
+		return this.filter.angle;
+	}
+	
+	public function getMultiAlphaValue(Void):Number {
+		return this.filter.alpha;
+	}
+	
+	public function getMultiBlurXValue(Void):Number {
+		return this.filter.blurX;
+	}
+	
+	public function getMultiBlurYValue(Void):Number {
+		return this.filter.blurY;
+	}
+	
+	public function getMultiStrengthValue(Void):Number {
+		return this.filter.strength;
+	}	
+		
+	public function setShadow(distance:Number, angle:Number, 
+							alpha:Number, blurX:Number, 
+							blurY:Number, strength:Number):Void {
+		
+		this.filter.distance = distance;
+		this.filter.angle = angle;
+		this.filter.alpha = alpha;
+		this.filter.blurX = blurX;
+		this.filter.blurY = blurY;
+		this.filter.strength = strength;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+
+	public function setDistance(distance:Number):Void {		
+		this.filter.distance = distance;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}	
+
+	public function setAngle(angle:Number):Void {		
+		this.filter.angle = angle;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}	
+	
+	public function setAlpha(alpha:Number):Void {		
+		this.filter.alpha = alpha;		
+		this.mc.filters = [this.filter];
+	}	
+
+	public function setBlurX(blurX:Number):Void {		
+		this.filter.blurX = blurX;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setBlurY(blurY:Number):Void {		
+		this.filter.blurY = blurY;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setStrength(strength:Number):Void {		
+		this.filter.strength = strength;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+
+	public function get color():Number {
+		return this.m_color;
+	}
+	
+	public function set color(color:Number):Void {
+		this.filter.color = color;
+		this.m_color = color;
+	}
+	
+	public function get quality():Number {
+		return this.m_quality;
+	}
+	
+	public function set quality(quality:Number):Void {
+		this.filter.quality = quality;
+		this.m_quality = quality;
+	}
+	
+	public function get inner():Boolean {
+		return this.m_inner;
+	}
+	
+	public function set inner(inner:Boolean):Void {
+		this.filter.inner = inner;
+		this.m_inner = inner;
+	}	
+	
+	public function get knockout():Boolean {
+		return this.m_knockout;
+	}
+	
+	public function set knockout(knockout:Boolean):Void {
+		this.filter.knockout = knockout;
+		this.m_knockout = knockout;
+	}
+	
+	public function get hideObject():Boolean {
+		return this.m_hideObject;
+	}
+	
+	public function set hideObject(hideObject:Boolean):Void {
+		this.filter.hideObject = hideObject;
+		this.m_hideObject = hideObject;
+	}
+	
+	/*inherited from AnimationCore*/
+	
+	/**
+	* @method run
+	* @description  		
+	* @usage   
+	* 
+	* 		the same overloading applies to this method as described in the 
+	* 		constructor. Just without the mc and mcs parameters.
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/	
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "DropShadow";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/DropShadow.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Filter.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Filter.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Filter.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,109 @@
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import flash.filters.BitmapFilter;
+
+/*
+* @class Filter
+* @author Alex Uhlmann
+* @description  Base class for all filter classes.
+* 			<p>
+*/
+class de.alex_uhlmann.animationpackage.animation.Filter 
+											extends AnimationCore {
+	
+
+	public var filterIndex:Number;
+	public var filters:Array;
+	
+	private var initialized:Boolean = false;
+	private var myInstances:Array;
+	private var hasStartValues:Boolean = false;
+	//abstract methods
+	private var createEmptyFilter:Function;
+	private var isFilterOfCorrectType:Function;
+	private var updateProperties:Function;
+
+	public function Filter() {
+		super();
+	}
+	
+	private function init():Void {
+		if(typeof(arguments[0]) != "number") {
+			arguments.unshift(null);
+		}
+		if(arguments[1] instanceof Array) {
+			var values:Array = arguments[1];
+			var endValues:Array = values.slice(-1);
+			arguments.splice(1, 1, endValues[0]);
+			this.initAnimation.apply(this, arguments);
+			this.setStartValues([values[0]]);
+		} else {
+			this.initAnimation.apply(this, arguments);
+		}
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = this.endValues;
+
+		if(this.mc != null) {
+			this.initSingleMC();			
+		} else {			
+			this.initMultiMC();			
+		}
+		
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+
+		this.startInitialized = false;
+	}
+	
+	private function addFilter(filter:BitmapFilter):Void {				
+		if(hasFilters(this.mc.filters)) {			
+			this.addToEnd(filter);
+		} else {
+			this.createFilters(filter);
+		}		
+		this.filters.push(filter);
+	}	
+
+	private function addToEnd(filter:BitmapFilter):Void {
+		this.filters = this.mc.filters;
+		this.filterIndex = this.filters.length;
+	}
+	
+	private function createFilters(filter:BitmapFilter):Void {
+		this.filters = new Array();
+		this.filterIndex = 0;
+	}
+	
+	private function findFilter(filterIndex:Number):BitmapFilter {
+		var filter:BitmapFilter = this.mc.filters[filterIndex];
+		
+		var isOfCorrectType:Boolean = this.isFilterOfCorrectType(filter);
+
+		if(!isOfCorrectType && filter != null) {
+			trace("Warning: de.alex_uhlmann.animationpackage.animation."+this+": "
+				+"Element "+filterIndex+" of "+this.mc+".filters will be overwritten.");
+		}
+		
+		if(filter == null || !isOfCorrectType) {
+			filter = this.createEmptyFilter();
+		}
+		return filter;
+	}	
+	
+	private function hasFilters(filters:Array):Boolean {
+		return (filters.length > 0);
+	}
+
+	public function toString(Void):String {
+		return "Filter";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Filter.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Glow.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Glow.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Glow.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,617 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.Filter;
+import flash.filters.BitmapFilter;
+import flash.filters.GlowFilter;
+
+/**
+* @class Glow
+* @author Alex Uhlmann
+* @description  Manipulates the GlowFilter of a movieclip 
+* 			or a number of movieclips.
+* 			<p>	Please look into the DropShadow HTML documentation to get an idea 
+* 			how to use filter classes in AnimationPackage.
+* 			<p>
+* 			Example 1: <a href="Glow_01.html">(Example .swf)</a>
+* 			<blockquote><pre>
+* 			import flash.filters.GlowFilter;
+* 			var mcs:Array = new Array(mc1, mc2, mc3);
+* 
+*			var glowFilter:GlowFilter = new GlowFilter();
+*			var myGlowIn:Glow = new Glow(mcs,glowFilter);
+*			myGlowIn.setOptimizationMode(true);
+*			myGlowIn.animationStyle(1000,Circ.easeOut);
+*			myGlowIn.addEventListener("onEnd",this);
+*			myGlowIn.animate(0,100);
+*			function onEnd(e:Object) {
+*				var myGlowOut:Glow = new Glow(mcs,0,null);
+*				myGlowOut.animationStyle(1000,Circ.easeIn);
+*				myGlowOut.animate(0,100);
+*			}
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 2: <a href="Glow_02.html">(Example .swf)</a>
+* 			Showcase some of the Glow features in 
+* 			a Sequence. See example no. 7 of DropShadow for more information.
+* 			<p>
+* @usage      
+* 			<pre>var myInstance:Glow = new Glow(mc);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mc, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mc, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:Glow = new Glow(mc, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mc, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:Glow = new Glow(mc, values);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mc, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mc, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:Glow = new Glow(mc, filterIndex, values);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mc, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mc, filterIndex, values, duration, easing, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mcs);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mcs, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mcs, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:Glow = new Glow(mcs, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mcs, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:Glow = new Glow(mcs, values);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mcs, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mcs, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:Glow = new Glow(mcs, filterIndex, values);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mcs, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:Glow = new Glow(mcs, filterIndex, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param filterIndex (Number) position of the element in the Movieclip's filter property that shall be manipulated.
+* @param filter (GlowFilter) Targeted GlowFilter object to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Glow 
+											extends Filter 
+											implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property filterIndex (Number)
+	* @property filters (Array)
+	* @property color (Number) 
+	* @property quality (Number)
+	* @property inner (Boolean)
+	* @property knockout (Boolean) 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public var filter:GlowFilter;
+	private var m_color:Number = 0xff0000;
+	private var m_quality:Number = 1;
+	private var m_inner:Boolean = false;
+	private var m_knockout:Boolean = false;
+
+	public function Glow() {
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		arguments.shift();
+		this.init.apply(this, arguments);
+	}
+
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		this.hasStartValues = optional ? false : true;
+		
+		if(startValues[0] == null) {
+			startValues[0] = createEmptyFilter();			
+		}
+		if(startValues[0] instanceof GlowFilter) {			
+			var filter:GlowFilter = startValues[0];
+			
+			if(this.hasStartValues) {
+				this.setNonAnimatedProperties(filter);
+			}
+			
+			return super.setStartValues([filter.alpha, filter.blurX, 
+										filter.blurY, filter.strength], optional);			
+		} else {
+			return super.setStartValues(startValues, optional);
+		}
+	}
+	
+	public function setEndValues(endValues:Array):Boolean {
+		
+		if(endValues[0] == null) {
+			endValues[0] = createEmptyFilter();
+		}
+		
+		if(endValues[0] instanceof GlowFilter) {
+			
+			var filter:GlowFilter = endValues[0];
+			this.setNonAnimatedProperties(filter);
+			
+			return super.setEndValues([filter.alpha, filter.blurX, 
+										filter.blurY, filter.strength]);		
+		} else {
+			return super.setEndValues(endValues);
+		}
+
+	}
+	
+	private function initAnimation(filterIndex:Number, filterEnd:GlowFilter, 
+							duration:Number, easing:Object, callback:String):Void {
+	
+		if(arguments.length > 2) {
+			this.animationStyle(duration, easing, callback);
+		} else {			
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		
+		this.initializeFilter(filterIndex, filterEnd);
+		
+		this.setStartValues([this.filter], true);
+		this.setEndValues([filterEnd]);		
+	}
+	
+	private function initializeFilter(filterIndex:Number, filterEnd:GlowFilter):Void {		
+		if(this.mc != null) {	
+			
+			if(filterIndex == null) {				
+				
+				this.filter = this.createEmptyFilter();
+				this.addFilter(this.filter);
+				
+			} else {			
+				
+				//if no filter of correct type is found at filterIndex, 
+				//a new filter will be created.
+				this.modifyOrCreateFilter(filterIndex);
+			}
+			
+		} else {
+			
+			this.filterIndex = filterIndex;
+			this.filter = filterEnd;
+			
+		}	
+	}	
+	
+	private function modifyOrCreateFilter(filterIndex:Number):Void {		
+		this.filter = GlowFilter(this.findFilter(filterIndex));
+		this.filters = this.mc.filters;
+		this.filterIndex = filterIndex;
+	}
+	
+	private function isFilterOfCorrectType(filter:BitmapFilter):Boolean {
+		return (filter instanceof GlowFilter == true);
+	}
+	
+	private function createEmptyFilter(Void):GlowFilter {
+		var filter:GlowFilter = new GlowFilter();
+		filter.alpha = 0;
+		filter.blurX = 0;
+		filter.blurY = 0;
+		filter.strength = 0;
+		return filter;
+	}
+	
+	private function initSingleMC(Void):Void {
+		this.myAnimator.start = this.startValues;
+		
+		if(this.getOptimizationMode() 
+			&& this.myAnimator.hasEquivalents()) {
+
+			this.myAnimator.setter = [[this,"setAlpha"],
+									[this,"setBlurX"],
+									[this,"setBlurY"],
+									[this,"setStrength"]];			
+
+		} else {				
+			this.myAnimator.setter = [[this,"setGlow"]];
+		}
+	}
+	
+	private function initMultiMC(Void):Void {
+		var myInstances:Array = [];
+		var len:Number = this.mcs.length;
+		var mcs:Array = this.mcs;
+		var i:Number = len;
+		while(--i>-1) {			
+			myInstances[i] = new Glow(mcs[i],this.filterIndex,this.filter);			
+			var filter:GlowFilter = this.updateFilter(createEmptyFilter());
+			myInstances[i].setNonAnimatedProperties(filter);
+		}
+		this.myInstances = myInstances;
+		
+		this.myAnimator.multiStart = ["getMultiAlphaValue","getMultiBlurXValue",
+									"getMultiBlurYValue","getMultiStrengthValue"];
+									
+		this.myAnimator.multiSetter = [[this.myInstances,"setAlpha"],
+									[this.myInstances,"setBlurX"],
+									[this.myInstances,"setBlurY"],
+									[this.myInstances,"setStrength"]];
+	}
+	
+	private function updateFilter(filter:GlowFilter):GlowFilter {		
+		filter.color = this.m_color;
+		filter.quality = this.m_quality;
+		filter.inner = this.m_inner;
+		filter.knockout = this.m_knockout;
+		return filter;
+	}
+	
+	private function updateProperties(filter:BitmapFilter):Void {		
+		this.filter = updateFilter(GlowFilter(filter));
+		this.setStartValues([this.filter], true);		
+	}
+
+	private function setNonAnimatedProperties(filter:GlowFilter):Void {
+		this.color = filter.color;
+		this.quality = filter.quality;
+		this.inner = filter.inner;
+		this.knockout = filter.knockout;
+	}
+	
+	
+	public function getMultiAlphaValue(Void):Number {
+		return this.filter.alpha;
+	}
+	
+	public function getMultiBlurXValue(Void):Number {
+		return this.filter.blurX;
+	}
+	
+	public function getMultiBlurYValue(Void):Number {
+		return this.filter.blurY;
+	}
+	
+	public function getMultiStrengthValue(Void):Number {
+		return this.filter.strength;
+	}
+		
+	public function setGlow(alpha:Number, blurX:Number, 
+							blurY:Number, strength:Number):Void {
+		
+		this.filter.alpha = alpha;
+		this.filter.blurX = blurX;
+		this.filter.blurY = blurY;
+		this.filter.strength = strength;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+
+	public function setAlpha(alpha:Number):Void {		
+		this.filter.alpha = alpha;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = [this.filter];
+	}	
+
+	public function setBlurX(blurX:Number):Void {		
+		this.filter.blurX = blurX;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setBlurY(blurY:Number):Void {		
+		this.filter.blurY = blurY;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setStrength(strength:Number):Void {		
+		this.filter.strength = strength;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+
+	public function get color():Number {
+		return this.m_color;
+	}
+	
+	public function set color(color:Number):Void {
+		this.filter.color = color;
+		this.m_color = color;
+	}
+	
+	public function get quality():Number {
+		return this.m_quality;
+	}
+	
+	public function set quality(quality:Number):Void {
+		this.filter.quality = quality;
+		this.m_quality = quality;
+	}
+	
+	public function get inner():Boolean {
+		return this.m_inner;
+	}
+	
+	public function set inner(inner:Boolean):Void {
+		this.filter.inner = inner;
+		this.m_inner = inner;
+	}	
+	
+	public function get knockout():Boolean {
+		return this.m_knockout;
+	}
+	
+	public function set knockout(knockout:Boolean):Void {
+		this.filter.knockout = knockout;
+		this.m_knockout = knockout;
+	}
+	
+	/*inherited from AnimationCore*/
+	
+	/**
+	* @method run
+	* @description  		
+	* @usage   
+	* 
+	* 		the same overloading applies to this method as described in the 
+	* 		constructor. Just without the mc and mcs parameters.
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/	
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Glow";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Glow.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientBevel.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientBevel.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientBevel.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,661 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.Filter;
+import flash.filters.BitmapFilter;
+import flash.filters.GradientBevelFilter;
+
+/**
+* @class GradientBevel
+* @author Alex Uhlmann
+* @description  Manipulates the GradientBevelFilter of a movieclip 
+* 			or a number of movieclips.
+* 			<p>	Please look into the DropShadow HTML documentation to get an idea 
+* 			how to use filter classes in AnimationPackage.
+* 			<p>
+* 			Example 1: <a href="GradientBevel_01.html">(Example .swf)</a>
+* 			<blockquote><pre>
+* 			import flash.filters.GradientBevelFilter;
+*			
+*			var filter:GradientBevelFilter = new GradientBevelFilter();
+*			filter.colors = [0xFFFFFF, 0xFF0000, 0x000000];
+*			filter.alphas = [1, 1, 1];
+*			filter.ratios = [0, 128, 255];
+*			filter.quality = 3; 
+*			filter.type = "inner"; 
+*			filter.knockout = true;
+*			filter.distance = 5;
+*			filter.angle = 225; 
+*			filter.blurX = 8;
+*			filter.blurY = 8; 
+*			filter.strength = 2;
+*			
+*			var myGradientBevelIn:GradientBevel = new GradientBevel(mc,filter);
+*			myGradientBevelIn.setOptimizationMode(true);
+*			myGradientBevelIn.animationStyle(3000,Circ.easeOut);
+*			myGradientBevelIn.animate(0,100);
+* 			</pre></blockquote>
+* 			<p>
+*
+* @usage      
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:GradientBevel = new GradientBevel(mc, values);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc, values, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:GradientBevel = new GradientBevel(mc, filterIndex, values);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mc, filterIndex, values, duration, easing, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, values);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, values, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, filterIndex, values);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientBevel = new GradientBevel(mcs, filterIndex, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param filterIndex (Number) position of the element in the Movieclip's filter property that shall be manipulated.
+* @param filter (GradientBevelFilter) Targeted GradientBevelFilter object to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.GradientBevel 
+											extends Filter 
+											implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property filterIndex (Number)
+	* @property filters (Array)
+	* @property colors (Array) 
+	* @property alphas (Array)
+	* @property ratios (Array)
+	* @property quality (Number)
+	* @property type (String)
+	* @property knockout (Boolean)
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public var filter:GradientBevelFilter;
+	private var m_colors:Array = [0xFFFFFF, 0x000000, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF];
+	private var m_alphas:Array = [0, 100, 0, 100, 0];
+	private var m_ratios:Array = [0, 64, 128, 192, 255];
+	private var m_quality:Number = 1;
+	private var m_type:String = "inner";
+	private var m_knockout:Boolean = false;
+
+	public function GradientBevel() {
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		arguments.shift();
+		this.init.apply(this, arguments);
+	}
+
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		this.hasStartValues = optional ? false : true;
+		
+		if(startValues[0] == null) {
+			startValues[0] = createEmptyFilter();
+		}
+		if(startValues[0] instanceof GradientBevelFilter) {			
+			var filter:GradientBevelFilter = startValues[0];
+			
+			if(this.hasStartValues) {
+				this.setNonAnimatedProperties(filter);
+			}
+			
+			return super.setStartValues([filter.distance, filter.angle, 
+										filter.blurX, filter.blurY, 
+										filter.strength], optional);			
+		} else {
+			return super.setStartValues(startValues, optional);
+		}
+	}
+	
+	public function setEndValues(endValues:Array):Boolean {
+		
+		if(endValues[0] == null) {
+			endValues[0] = createEmptyFilter();
+		}
+		if(endValues[0] instanceof GradientBevelFilter) {
+			
+			var filter:GradientBevelFilter = endValues[0];
+			this.setNonAnimatedProperties(filter);
+			
+			return super.setEndValues([filter.distance, filter.angle, 
+										filter.blurX, filter.blurY, 
+										filter.strength]);		
+		} else {
+			return super.setEndValues(endValues);
+		}
+
+	}
+	
+	private function initAnimation(filterIndex:Number, filterEnd:GradientBevelFilter, 
+							duration:Number, easing:Object, callback:String):Void {
+
+		if(arguments.length > 2) {
+			this.animationStyle(duration, easing, callback);
+		} else {			
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}	
+		
+		this.initializeFilter(filterIndex, filterEnd);
+		
+		this.setStartValues([this.filter], true);
+		this.setEndValues([filterEnd]);
+	}
+	
+	private function initializeFilter(filterIndex:Number, filterEnd:GradientBevelFilter):Void {		
+		if(this.mc != null) {	
+			
+			if(filterIndex == null) {				
+				
+				this.filter = this.createEmptyFilter();
+				this.addFilter(this.filter);
+				
+			} else {			
+				
+				//if no filter of correct type is found at filterIndex, 
+				//a new filter will be created.
+				this.modifyOrCreateFilter(filterIndex);
+			}
+			
+		} else {
+			
+			this.filterIndex = filterIndex;
+			this.filter = filterEnd;
+			
+		}
+	}	
+	
+	private function modifyOrCreateFilter(filterIndex:Number):Void {		
+		this.filter = GradientBevelFilter(this.findFilter(filterIndex));
+		this.filters = this.mc.filters;
+		this.filterIndex = filterIndex;
+	}
+
+	private function isFilterOfCorrectType(filter:BitmapFilter):Boolean {
+		return (filter instanceof GradientBevelFilter == true);
+	}
+	
+	private function createEmptyFilter(Void):GradientBevelFilter {
+		var filter:GradientBevelFilter = new GradientBevelFilter();
+		filter.distance = 0;
+		filter.angle = 0;
+		filter.blurX = 0;
+		filter.blurY = 0;
+		filter.strength = 0;
+		return filter;
+	}
+	
+	private function initSingleMC(Void):Void {
+		this.myAnimator.start = this.startValues;
+		
+		if(this.getOptimizationMode() 
+			&& this.myAnimator.hasEquivalents()) {
+				
+			this.myAnimator.setter = [[this,"setDistance"],
+								[this,"setAngle"],
+								[this,"setBlurX"],
+								[this,"setBlurY"],
+								[this,"setStrength"]];							
+		} else {				
+			this.myAnimator.setter = [[this,"setGradientBevel"]];	
+		}
+	}
+	
+	private function initMultiMC(Void):Void {
+		var myInstances:Array = [];			
+		var len:Number = this.mcs.length;
+		var mcs:Array = this.mcs;
+		var i:Number = len;
+		while(--i>-1) {
+			myInstances[i] = new GradientBevel(mcs[i],this.filterIndex,this.filter);			
+			var filter:GradientBevelFilter = this.updateFilter(createEmptyFilter());
+			myInstances[i].setNonAnimatedProperties(filter);
+		}
+		this.myInstances = myInstances;
+
+		this.myAnimator.multiStart = ["getMultiDistanceValue","getMultiAngleValue",
+									"getMultiBlurXValue","getMultiBlurYValue",
+									"getMultiStrengthValue"];
+									
+		this.myAnimator.multiSetter = [[this.myInstances,"setDistance"],
+									[this.myInstances,"setAngle"],
+									[this.myInstances,"setBlurX"],
+									[this.myInstances,"setBlurY"],
+									[this.myInstances,"setStrength"]];	
+
+	}
+	
+	private function updateFilter(filter:GradientBevelFilter):GradientBevelFilter {		
+		filter.colors = this.m_colors;
+		filter.alphas = this.m_alphas;
+		filter.ratios = this.m_ratios;
+		filter.quality = this.m_quality;
+		filter.type = this.m_type;
+		filter.knockout = this.m_knockout;	
+		return filter;
+	}
+	
+	private function updateProperties(filter:BitmapFilter):Void {
+		this.filter = updateFilter(GradientBevelFilter(filter));
+		this.setStartValues([this.filter], true);		
+	}
+
+	private function setNonAnimatedProperties(filter:GradientBevelFilter):Void {
+		this.colors = filter.colors;
+		this.alphas = filter.alphas;
+		this.ratios = filter.ratios;
+		this.quality = filter.quality;
+		this.type = filter.type;
+		this.knockout = filter.knockout;		
+	}	
+	
+	public function getMultiDistanceValue(Void):Number {
+		return this.filter.distance;
+	}	
+	
+	public function getMultiAngleValue(Void):Number {
+		return this.filter.angle;
+	}
+	
+	public function getMultiBlurXValue(Void):Number {
+		return this.filter.blurX;
+	}
+	
+	public function getMultiBlurYValue(Void):Number {
+		return this.filter.blurY;
+	}
+	
+	public function getMultiStrengthValue(Void):Number {
+		return this.filter.strength;
+	}	
+		
+	public function setGradientBevel(distance:Number, angle:Number, 
+							blurX:Number, blurY:Number, 
+							strength:Number):Void {
+
+		this.filter.distance = distance;
+		this.filter.angle = angle;
+		this.filter.blurX = blurX;
+		this.filter.blurY = blurY;
+		this.filter.strength = strength;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+
+	public function setDistance(distance:Number):Void {		
+		this.filter.distance = distance;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}	
+
+	public function setAngle(angle:Number):Void {		
+		this.filter.angle = angle;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}	
+
+	public function setBlurX(blurX:Number):Void {		
+		this.filter.blurX = blurX;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setBlurY(blurY:Number):Void {		
+		this.filter.blurY = blurY;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setStrength(strength:Number):Void {		
+		this.filter.strength = strength;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function get colors():Array {
+		return this.m_colors;
+	}
+	
+	public function set colors(colors:Array):Void {
+		this.filter.colors = colors;
+		this.m_colors = colors;
+	}
+	
+	public function get alphas():Array {
+		return this.m_alphas;
+	}
+	
+	public function set alphas(alphas:Array):Void {
+		this.filter.alphas = alphas;
+		this.m_alphas = alphas;
+	}
+	
+	public function get ratios():Array {
+		return this.m_ratios;
+	}
+	
+	public function set ratios(ratios:Array):Void {
+		this.filter.ratios = ratios;
+		this.m_ratios = ratios;
+	}	
+	
+	public function get quality():Number {
+		return this.m_quality;
+	}
+	
+	public function set quality(quality:Number):Void {
+		this.filter.quality = quality;
+		this.m_quality = quality;
+	}
+	
+	public function get type():String {
+		return this.m_type;
+	}
+	
+	public function set type(type:String):Void {
+		this.filter.type = type;
+		this.m_type = type;
+	}
+	
+	public function get knockout():Boolean {
+		return this.m_knockout;
+	}
+	
+	public function set knockout(knockout:Boolean):Void {
+		this.filter.knockout = knockout;
+		this.m_knockout = knockout;
+	}
+	
+	/*inherited from AnimationCore*/
+	
+	/**
+	* @method run
+	* @description  		
+	* @usage   
+	* 
+	* 		the same overloading applies to this method as described in the 
+	* 		constructor. Just without the mc and mcs parameters.
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/	
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "GradientBevel";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientBevel.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientGlow.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientGlow.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientGlow.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,661 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.Filter;
+import flash.filters.BitmapFilter;
+import flash.filters.GradientGlowFilter;
+
+/**
+* @class GradientGlow
+* @author Alex Uhlmann
+* @description  Manipulates the GradientGlowFilter of a movieclip 
+* 			or a number of movieclips.
+* 			<p>	Please look into the DropShadow HTML documentation to get an idea 
+* 			how to use filter classes in AnimationPackage.
+* 			<p>
+* 			Example 1: <a href="GradientGlow_01.html">(Example .swf)</a>
+* 			<blockquote><pre>
+* 			import flash.filters.GradientGlowFilter;
+*			
+*			var filter:GradientGlowFilter = new GradientGlowFilter();
+*			filter.colors = [0xFFFFFF, 0xFF0000, 0xFFFF00, 0x00CCFF];
+*			filter.alphas = [0, 1, 1, 1, 1];
+*			filter.ratios = [0, 63, 126, 255];
+*			filter.quality = 3; 
+*			filter.type = "outer"; 
+*			filter.knockout = false;
+*			filter.distance = 0;
+*			filter.angle = 0;
+*			filter.blurX = 8;
+*			filter.blurY = 8; 
+*			filter.strength = 2.5;
+*			
+*			var myGradientGlowIn:GradientGlow = new GradientGlow(mc1,filter);
+*			myGradientGlowIn.setOptimizationMode(true);
+*			myGradientGlowIn.animationStyle(3000,Circ.easeOut);
+*			myGradientGlowIn.animate(0,100);
+* 			</pre></blockquote>
+* 			<p>
+* 
+* @usage      
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:GradientGlow = new GradientGlow(mc, values);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc, values, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:GradientGlow = new GradientGlow(mc, filterIndex, values);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mc, filterIndex, values, duration, easing, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, filter, duration, easing, callback);</pre>
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, filterIndex, filter, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, filterIndex, filter, duration, easing, callback);</pre>
+*			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, values);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, values, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, values, duration, easing, callback);</pre> 
+*			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, filterIndex, values);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, filterIndex, values, duration, callback);</pre> 
+* 			<pre>var myInstance:GradientGlow = new GradientGlow(mcs, filterIndex, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param filterIndex (Number) position of the element in the Movieclip's filter property that shall be manipulated.
+* @param filter (GradientGlowFilter) Targeted GradientGlowFilter object to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.GradientGlow 
+											extends Filter 
+											implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property filterIndex (Number)
+	* @property filters (Array)
+	* @property colors (Array) 
+	* @property alphas (Array)
+	* @property ratios (Array)
+	* @property quality (Number)
+	* @property type (String)
+	* @property knockout (Boolean)
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public var filter:GradientGlowFilter;
+	private var m_colors:Array = [0x0000FF, 0x0000FF, 0xFF0000, 0xFFFFFF];;
+	private var m_alphas:Array = [0, 100, 100, 100];
+	private var m_ratios:Array = [0, 128, 192, 255];
+	private var m_quality:Number = 1;
+	private var m_type:String = "inner";
+	private var m_knockout:Boolean = false;
+
+	public function GradientGlow() {
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		arguments.shift();
+		this.init.apply(this, arguments);
+	}
+
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		this.hasStartValues = optional ? false : true;
+		
+		if(startValues[0] == null) {
+			startValues[0] = createEmptyFilter();
+		}
+		if(startValues[0] instanceof GradientGlowFilter) {			
+			var filter:GradientGlowFilter = startValues[0];
+			
+			if(this.hasStartValues) {
+				this.setNonAnimatedProperties(filter);
+			}
+			
+			return super.setStartValues([filter.distance, filter.angle, 
+										filter.blurX, filter.blurY, 
+										filter.strength], optional);			
+		} else {
+			return super.setStartValues(startValues, optional);
+		}
+	}
+	
+	public function setEndValues(endValues:Array):Boolean {
+		
+		if(endValues[0] == null) {
+			endValues[0] = createEmptyFilter();
+		}
+		if(endValues[0] instanceof GradientGlowFilter) {
+			
+			var filter:GradientGlowFilter = endValues[0];
+			this.setNonAnimatedProperties(filter);
+			
+			return super.setEndValues([filter.distance, filter.angle, 
+										filter.blurX, filter.blurY, 
+										filter.strength]);		
+		} else {
+			return super.setEndValues(endValues);
+		}
+
+	}
+	
+	private function initAnimation(filterIndex:Number, filterEnd:GradientGlowFilter, 
+							duration:Number, easing:Object, callback:String):Void {
+
+		if(arguments.length > 2) {
+			this.animationStyle(duration, easing, callback);
+		} else {			
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}	
+		
+		this.initializeFilter(filterIndex, filterEnd);
+		
+		this.setStartValues([this.filter], true);
+		this.setEndValues([filterEnd]);
+	}
+	
+	private function initializeFilter(filterIndex:Number, filterEnd:GradientGlowFilter):Void {		
+		if(this.mc != null) {	
+			
+			if(filterIndex == null) {				
+				
+				this.filter = this.createEmptyFilter();
+				this.addFilter(this.filter);
+				
+			} else {			
+				
+				//if no filter of correct type is found at filterIndex, 
+				//a new filter will be created.
+				this.modifyOrCreateFilter(filterIndex);
+			}
+			
+		} else {
+			
+			this.filterIndex = filterIndex;
+			this.filter = filterEnd;
+			
+		}
+	}
+	
+	private function modifyOrCreateFilter(filterIndex:Number):Void {		
+		this.filter = GradientGlowFilter(this.findFilter(filterIndex));
+		this.filters = this.mc.filters;
+		this.filterIndex = filterIndex;
+	}
+
+	private function isFilterOfCorrectType(filter:BitmapFilter):Boolean {
+		return (filter instanceof GradientGlowFilter == true);
+	}
+	
+	private function createEmptyFilter(Void):GradientGlowFilter {
+		var filter:GradientGlowFilter = new GradientGlowFilter();
+		filter.distance = 0;
+		filter.angle = 0;
+		filter.blurX = 0;
+		filter.blurY = 0;
+		filter.strength = 0;
+		return filter;
+	}
+	
+	private function initSingleMC(Void):Void {
+		this.myAnimator.start = this.startValues;
+		
+		if(this.getOptimizationMode() 
+			&& this.myAnimator.hasEquivalents()) {
+				
+			this.myAnimator.setter = [[this,"setDistance"],
+								[this,"setAngle"],
+								[this,"setBlurX"],
+								[this,"setBlurY"],
+								[this,"setStrength"]];							
+		} else {				
+			this.myAnimator.setter = [[this,"setGradientGlow"]];	
+		}
+	}
+	
+	private function initMultiMC(Void):Void {
+		var myInstances:Array = [];			
+		var len:Number = this.mcs.length;
+		var mcs:Array = this.mcs;
+		var i:Number = len;
+		while(--i>-1) {
+			myInstances[i] = new GradientGlow(mcs[i],this.filterIndex,this.filter);			
+			var filter:GradientGlowFilter = this.updateFilter(createEmptyFilter());
+			myInstances[i].setNonAnimatedProperties(filter);
+		}
+		this.myInstances = myInstances;
+
+		this.myAnimator.multiStart = ["getMultiDistanceValue","getMultiAngleValue",
+									"getMultiBlurXValue","getMultiBlurYValue",
+									"getMultiStrengthValue"];
+									
+		this.myAnimator.multiSetter = [[this.myInstances,"setDistance"],
+									[this.myInstances,"setAngle"],
+									[this.myInstances,"setBlurX"],
+									[this.myInstances,"setBlurY"],
+									[this.myInstances,"setStrength"]];	
+
+	}
+	
+	private function updateFilter(filter:GradientGlowFilter):GradientGlowFilter {		
+		filter.colors = this.m_colors;
+		filter.alphas = this.m_alphas;
+		filter.ratios = this.m_ratios;
+		filter.quality = this.m_quality;
+		filter.type = this.m_type;
+		filter.knockout = this.m_knockout;
+		return filter;
+	}	
+	
+	private function updateProperties(filter:BitmapFilter):Void {
+		this.filter = updateFilter(GradientGlowFilter(filter));
+		this.setStartValues([this.filter], true);		
+	}
+
+	private function setNonAnimatedProperties(filter:GradientGlowFilter):Void {
+		this.colors = filter.colors;
+		this.alphas = filter.alphas;
+		this.ratios = filter.ratios;
+		this.quality = filter.quality;
+		this.type = filter.type;
+		this.knockout = filter.knockout;		
+	}	
+	
+	public function getMultiDistanceValue(Void):Number {
+		return this.filter.distance;
+	}	
+	
+	public function getMultiAngleValue(Void):Number {
+		return this.filter.angle;
+	}
+	
+	public function getMultiBlurXValue(Void):Number {
+		return this.filter.blurX;
+	}
+	
+	public function getMultiBlurYValue(Void):Number {
+		return this.filter.blurY;
+	}
+	
+	public function getMultiStrengthValue(Void):Number {
+		return this.filter.strength;
+	}	
+		
+	public function setGradientGlow(distance:Number, angle:Number, 
+							blurX:Number, blurY:Number, 
+							strength:Number):Void {
+		
+		this.filter.distance = distance;
+		this.filter.angle = angle;
+		this.filter.blurX = blurX;
+		this.filter.blurY = blurY;
+		this.filter.strength = strength;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+
+	public function setDistance(distance:Number):Void {		
+		this.filter.distance = distance;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}	
+
+	public function setAngle(angle:Number):Void {		
+		this.filter.angle = angle;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}	
+
+	public function setBlurX(blurX:Number):Void {		
+		this.filter.blurX = blurX;
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setBlurY(blurY:Number):Void {		
+		this.filter.blurY = blurY;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function setStrength(strength:Number):Void {		
+		this.filter.strength = strength;		
+		this.filters[this.filterIndex] = this.filter;
+		this.mc.filters = this.filters;
+	}
+	
+	public function get colors():Array {
+		return this.m_colors;
+	}
+	
+	public function set colors(colors:Array):Void {
+		this.filter.colors = colors;
+		this.m_colors = colors;
+	}
+	
+	public function get alphas():Array {
+		return this.m_alphas;
+	}
+	
+	public function set alphas(alphas:Array):Void {
+		this.filter.alphas = alphas;
+		this.m_alphas = alphas;
+	}
+	
+	public function get ratios():Array {
+		return this.m_ratios;
+	}
+	
+	public function set ratios(ratios:Array):Void {
+		this.filter.ratios = ratios;
+		this.m_ratios = ratios;
+	}	
+	
+	public function get quality():Number {
+		return this.m_quality;
+	}
+	
+	public function set quality(quality:Number):Void {
+		this.filter.quality = quality;
+		this.m_quality = quality;
+	}
+	
+	public function get type():String {
+		return this.m_type;
+	}
+	
+	public function set type(type:String):Void {
+		this.filter.type = type;
+		this.m_type = type;
+	}
+	
+	public function get knockout():Boolean {
+		return this.m_knockout;
+	}
+	
+	public function set knockout(knockout:Boolean):Void {
+		this.filter.knockout = knockout;
+		this.m_knockout = knockout;
+	}
+	
+	/*inherited from AnimationCore*/
+	
+	/**
+	* @method run
+	* @description  		
+	* @usage   
+	* 
+	* 		the same overloading applies to this method as described in the 
+	* 		constructor. Just without the mc and mcs parameters.
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/	
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "GradientGlow";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/GradientGlow.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IAnimatable.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IAnimatable.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IAnimatable.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,25 @@
+import de.alex_uhlmann.animationpackage.IAnimationPackage;
+interface de.alex_uhlmann.animationpackage.animation.IAnimatable extends IAnimationPackage {
+	public function run():Void;	
+	public function animate(start:Number, end:Number):Void;
+	public function goto(percentage:Number):Void;
+	public function animationStyle(duration:Number, easing:Object, callback:String):Void;
+	public function roundResult(rounded:Boolean):Void;
+	public function forceEnd(forceEndVal:Boolean):Void;
+	public function getOptimizationMode(Void):Boolean;
+	public function setOptimizationMode(optimize:Boolean):Void;
+	public function getTweenMode(Void):String;
+	public function setTweenMode(tweenMode:String):Boolean;
+	public function getDurationMode(Void):String;
+	public function setDurationMode(durationMode:String):Boolean;
+	public function stop(Void):Boolean;
+	public function pause(duration:Number):Boolean;
+	public function resume(Void):Boolean;
+	public function lock(Void):Void;
+	public function unlock(Void):Void;
+	public function isTweening(Void):Boolean;
+	public function isPaused(Void):Boolean;
+	public function getDurationElapsed(Void):Number;
+	public function getDurationRemaining(Void):Number;
+	public function getCurrentPercentage(Void):Number;
+}


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IAnimatable.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IMultiAnimatable.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IMultiAnimatable.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IMultiAnimatable.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,8 @@
+import de.alex_uhlmann.animationpackage.animation.IAnimatable;
+interface de.alex_uhlmann.animationpackage.animation.IMultiAnimatable extends IAnimatable {
+	public function getStartValues(Void):Array;
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean;
+	public function getCurrentValues(Void):Array;
+	public function getEndValues(Void):Array;
+	public function setEndValues(endValues:Array):Boolean;	
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/IMultiAnimatable.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ISingleAnimatable.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ISingleAnimatable.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ISingleAnimatable.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,8 @@
+import de.alex_uhlmann.animationpackage.animation.IAnimatable;
+interface de.alex_uhlmann.animationpackage.animation.ISingleAnimatable extends IAnimatable {
+	public function getStartValue(Void):Number;
+	public function setStartValue(startValue:Number, optional:Boolean):Boolean;
+	public function getCurrentValue(Void):Number;
+	public function getEndValue(Void):Number;
+	public function setEndValue(endValue:Number):Boolean;
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/ISingleAnimatable.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskCore.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskCore.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskCore.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,131 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.drawing.Rectangle;
+
+/*
+* @class MaskCore
+* @author Alex Uhlmann, Ben Jackson
+*/
+class de.alex_uhlmann.animationpackage.animation.MaskCore extends AnimationCore {
+	
+	private var mask_mc:MovieClip;
+	private var mcBounds:Object;
+	private var mask_mcBounds:Object;	
+	private var mask_mcW:Number;
+	private var mask_mcH:Number;
+	private var resetXscale:Number;
+	private var resetYscale:Number;	
+	private var effect:String;
+	private var adjustmentObj:Object;
+	private var myMaskAnimation:Object;
+	
+	private function MaskCore(mc:MovieClip, mask_mc:MovieClip) {
+		super();
+		this.init.apply(this,arguments);
+	}
+	
+	private function init():Void {	
+		var mc:MovieClip = arguments[0];
+		var mask_mc:MovieClip = arguments[1];
+		this.mc = mc;
+		if (mask_mc == null) {
+			var dp:Number = this.getNextDepth(mc._parent);
+			mask_mc = this.createClip({parentMC:mc._parent, name:"apMask", x:0, y:0});
+			var myRectangle:Rectangle = new Rectangle(mask_mc, mc._width/2, mc._height/2, mc._width, mc._height);
+			myRectangle.draw();
+		}
+		this.mask_mc = mask_mc;
+		this.hideMask();
+	}
+	
+	private function hideMask(Void):Void {	
+		this.mask_mc._visible = false;	
+	}
+	
+	private function unhideMask(Void):Void {	
+		this.mask_mc._visible = true;		
+	}
+	
+	private function getBounds(Void):Void {			
+		this.mcBounds = this.mc.getBounds(_root);		
+		this.mask_mcBounds = this.mask_mc.getBounds(_root);		
+	}
+	
+	public function matchSize(amount:Number):Void {				
+		this.unhideMask();
+		if(amount === undefined) {
+			amount = 120;
+		} else if(amount === null) {
+			return;
+		}
+		var areaWidth:Number = this.mcBounds.xMax - this.mcBounds.xMin;
+		var areaHeight:Number = this.mcBounds.yMax - this.mcBounds.yMin;
+		var mask_mcWidth:Number = this.mask_mcBounds.xMax - this.mask_mcBounds.xMin;
+		var mask_mcHeight:Number = this.mask_mcBounds.yMax - this.mask_mcBounds.yMin;	
+		var distXrel:Number;
+		if(mask_mcWidth > mask_mcHeight) {			
+			distXrel = areaWidth / mask_mcWidth * amount;						
+		} else {			
+			distXrel = areaHeight / mask_mcHeight * amount;				
+		}		
+		this.mask_mc._xscale = distXrel;			
+		this.mask_mc._yscale = distXrel;		
+		this.resetXscale = this.mask_mc._xscale;
+		this.resetYscale = this.mask_mc._yscale;
+		this.hideMask();
+	}
+	
+	public function forceEnd(forceEndVal:Boolean):Void {
+		this.myMaskAnimation.forceEnd(forceEndVal);
+	}
+	
+	public function setMask(Void):Void {		
+		this.mc.setMask(this.mask_mc);
+	}
+	
+	public function deleteMask(Void):Void {		
+		this.mc.setMask(null);
+	}	
+
+	public function getStartValues(Void):Array {		
+		return this.myMaskAnimation.getStartValues();
+	}
+	
+	public function getEndValues(Void):Array {		
+		return this.myMaskAnimation.getEndValues();
+	}	
+	
+	public function getCurrentValues(Void):Array {		
+		return this.myMaskAnimation.getCurrentValues();
+	}
+	
+	public function getCurrentPercentage(Void):Number {
+		return this.myMaskAnimation.getCurrentPercentage();
+	}
+	
+	public function get maskMovieclip():MovieClip {
+		return this.mask_mc;
+	}
+	
+	public function set maskMovieclip(mask_mc:MovieClip):Void {
+		this.mask_mc = mask_mc;
+	}
+	
+	private function onStart(eventObject:Object):Void {		
+		this.dispatchEvent({type:eventObject.type, value:this.getStartValues()});
+	}
+	
+	private function onUpdate(eventObject:Object):Void {
+		this.dispatchEvent({type:eventObject.type, value:this.getCurrentValues()});
+	}
+	
+	private function onEnd(eventObject:Object):Void {		
+		this.tweening = false;
+		APCore.broadcastMessage(this.callback, this, this.getCurrentValues());
+		this.dispatchEvent({type:eventObject.type, value:this.getCurrentValues()});
+	}
+	
+	public function toString(Void):String {		
+		return "MaskCore";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskCore.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskMoveFX.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskMoveFX.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskMoveFX.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,712 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.MaskCore;
+import de.alex_uhlmann.animationpackage.animation.Move;
+
+/*inspired from Jon Williams, shovemedia.com, ActionScript Timeline Class v2.0 beta*/
+/**
+* @class MaskMoveFX
+* @author Alex Uhlmann, Ben Jackson
+* @description	Animates a mask using move effects. 
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing. 
+* 			You can also send the animationStyle properties via the run() method or via the constructor. See the following examples.
+*			The move effect needs to 
+* 			be specified as a string abbreviation. Available mask move effects are:
+* 			<blockquote><pre>
+* 			"L" = left, moves the mask to the left.
+* 			"R" = right, moves the mask to the right.
+* 			"T" = top, moves the mask to the top.
+* 			"B" = bottom, moves the mask to the bottom.
+* 			"TL" = top left, moves the mask to the top left corner. 
+* 			"TR" = top right, moves the mask to the top right corner.
+* 			"BL" = bottom left, moves the mask to the bottom left corner.
+* 			"BR" = bottom right, moves the mask to the bottom right corner.
+* 			"CUSTOM" = moves the mask according to the adjustmentObj parameter.
+* 			</pre></blockquote>
+* 			<p> 
+* 			Example 1: <a href="MaskMoveFX_01.html">(Example .swf)</a> Draw a rectangle and use it as a mask over movieclip mc.
+* 			<blockquote><pre>
+*			var myRect:Rectangle = new Rectangle(50,50,100,50);
+*			myRect.draw();
+*			var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc,myRect.movieclip);
+*			myMaskMoveFX.animationStyle(2000,Circ.easeInOut);
+*			myMaskMoveFX.run("L",0,100);
+* 			</pre></blockquote>
+* 			If you don't specify a mask movieclip, 
+* 			a Rectangle will be created in the parent timeline of mc.
+* 			<p>
+* 			You can alter a predefined move effect or you can define a custom move effect 
+* 			via the adjustmentObj. The adjustmentObj of MaskMoveFX is an Object that contains five optional properties.
+* 			<blockquote><pre>
+* 			scaleOffset = Specifies the scaling of the mask. Defaults to 120 or 160, depening on the specified move effect. If null is specified, the mask movieclip won't be scaled at all.
+* 			startX = Start point to move the mask from. Coordinate point x.
+* 			startY = Start point to move the mask from. Coordinate point y.
+*			endX = End point to move the mask to. Coordinate point x.
+*			endY = End point to move the mask to. Coordinate point y.
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 2: <a href="MaskMoveFX_02.html">(Example .swf)</a> Mask only a specific part in the masked movieclip. Move according to the adjustmentObj. 
+* 			Note that you can prevent automatic scaling of your mask movieclip if you set scaleOffset to null.
+* 			<blockquote><pre>			
+*			var myRect:Rectangle = new Rectangle(50,50,158,25);
+*			myRect.draw();
+*			var mcBounds:Object = mc.getBounds(_root);
+*			var myMaskMoveFX1:MaskMoveFX = new MaskMoveFX(mc,myRect.movieclip);
+*			AnimationCore.duration_def = 2000;
+*			AnimationCore.easing_def = Circ.easeInOut;
+*			myMaskMoveFX1.run("CUSTOM",0,100,{
+*							scaleOffset:null, 
+*							startX:mcBounds.xMin,
+*							startY:mcBounds.yMax-22, 
+*							endX:mcBounds.xMax-92, 
+*							endY:mcBounds.yMax-22
+*							});
+*			</pre></blockquote>
+* 			<p>
+* 			Note that the start and end values (0 and 100) in example 2 have no effect when using the CUSTOM move effect.
+* 			Furthermore, note that you can also alter predefined move effects via the properties of the adjustmentObj. 
+* 			You don't have to specify the CUSTOM move effect, when you want to customize a move effect.
+* 			<p>
+* 			Note that all examples above created a mask movieclip above the masked mc. 
+* 			If you want to manipulate physical movieclip properties of the masked movieclip, and at the same time 
+* 			animate the movieclip with a mask effect, the mask effect would be disturbed. Here is a solution:
+* 			<p>
+* 			Example 3: <a href="MaskMoveFX_03.html">(Example .swf)</a> Using the Parallel class we use a mask effect and manipulate many physical properties of movieclip "mc" at the same time.
+* 			<pre><blockquote>
+* 			var myMoveOnQuadCurve:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,300,300,500,100);
+*			var myScale:Scale = new Scale(mc,50,50);
+*			var myColorTransform:ColorTransform = new ColorTransform(mc,0xff0000,50);
+* 			//create the mask movieclip inside the movieclip mc to reflect all manipulations to mc.
+*			var mask_mc:MovieClip = mc.createEmptyMovieClip("mask_mc",1);
+*			var myRect:Rectangle = new Rectangle(mask_mc,50,50,100,50);
+*			myRect.draw();
+* 			//since the mask is inside mc you have to mask a movieclip inside mc.
+* 			var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc.inner_mc,myRect.movieclip,"TL");
+*			
+*			var myParallel:Parallel = new Parallel();
+*			myParallel.addChild(myMoveOnQuadCurve);
+*			myParallel.addChild(myScale);
+*			myParallel.addChild(myColorTransform);
+*			myParallel.addChild(myMaskMoveFX);
+*			myParallel.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			myParallel.animate(0,100);
+*			myListener.onCallback = function(source) {	
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</blockquote></pre>
+* 			<p>
+* 
+* @usage 
+* 		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc);</pre> 
+* 		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc);</pre> 
+* 		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc, effect);</pre>
+* 		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc, effect, duration);</pre>
+* 		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc, effect, duration, callback);</pre>
+*		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc, effect, duration, easing, callback);</pre>
+* 		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc, effect, adjustmentObj);</pre>
+* 		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc, effect, adjustmentObj, duration);</pre>
+* 		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc, effect, adjustmentObj, duration, callback);</pre>
+*		<pre>var myMaskMoveFX:MaskMoveFX = new MaskMoveFX(mc, mask_mc, effect, adjustmentObj, duration, easing, callback);</pre>
+* 
+* @param mc (MovieClip) movieclip to be masked.
+* @param mask_mc (MovieClip) movieclip to use as a mask. If null or omitted, a Rectangle will be created in the parent timeline of mc.	  
+* @param effect (String) Specifies the mask move FX.
+* @param adjustmentObj (Object) Optional. Object with five properties that overwrite the default properties that define the move effect of the mask. You only need this parameter if you are not contented with the default move effect of the mask or if you use the CUSTOM move effect.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.MaskMoveFX 
+												extends MaskCore 
+												implements ISingleAnimatable  {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to be masked.
+	* @property maskMovieclip (MovieClip) Movieclip to use as a mask.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	private var myMove:Move;
+	
+	public function MaskMoveFX(mc:MovieClip, mask_mc:MovieClip, 
+								effect:String, adjustmentObj:Object, 
+								duration:Object, easing:Object, callback:String) {
+		super(mc, mask_mc);
+		if(arguments.length > 2) {			
+			this.initAnimation.apply(this, arguments.slice(2));
+		}
+	}
+	
+	private function initAnimation(effect:String, adjustmentObj:Object, 
+						duration:Object, easing:Object, callback:String):Void {		
+		
+		this.effect = effect;
+		this.adjustmentObj = adjustmentObj;		
+		var temp;
+		var paramLen:Number = 4;		
+		if(typeof(adjustmentObj) == "number") {
+			temp = adjustmentObj;
+			var temp_ms:Number = temp;                  
+			var temp_easing = duration;
+			temp = easing;
+			easing = temp_easing;
+			callback = temp;			
+			this.animationStyle(temp_ms, easing, callback);
+		} else if (arguments.length > paramLen) {			
+			temp = duration;
+			this.animationStyle(temp, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		this.getBounds();
+		var scaleOffset:Number = this.adjustmentObj.scaleOffset;
+		if(effect == "L" || effect == "R" || effect == "T" || effect == "B" || effect == "CUSTOM") {
+			this.matchSize(scaleOffset);
+		} else if(effect == "TL" || effect == "TR" || effect == "BL" || effect == "BR") {
+			if(scaleOffset == null) {
+				scaleOffset = 160;
+			}
+			this.matchSize(scaleOffset);
+		}
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		
+		var goto:Boolean;
+		var percentage:Number = start;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;
+			end = 100 - end;
+			if(omitEvent) {
+				return;
+			}
+		} else {
+			goto = false;
+		}
+		this.tweening = true;
+		var effect:String = this.effect;
+		
+		var adjustmentObj:Object = this.adjustmentObj;
+		if(adjustmentObj.start != null 
+			&& adjustmentObj.end != null) {
+			
+			start = adjustmentObj.start;
+			end = adjustmentObj.end;
+		}
+		
+		var posStartRel:Number;
+		var posEndRel:Number;
+		var startObj:Object = new Object();
+		var endObj:Object = new Object();
+		var mcPath:String = targetPath(this.mc);
+		var mask_mcPath:String = targetPath(this.mask_mc);
+		var mcPathCont:String  = mcPath.substring(0, mcPath.indexOf(".",8));
+		var mask_mcPathCont:String = mask_mcPath.substring(0, mask_mcPath.indexOf(".",8));
+		this.getBounds();
+		var mcW:Number = this.mcBounds.xMax - this.mcBounds.xMin;
+		var mcH:Number = this.mcBounds.yMax - this.mcBounds.yMin;
+		var mask_mcW:Number = this.mask_mcBounds.xMax - this.mask_mcBounds.xMin;
+		var mask_mcH:Number = this.mask_mcBounds.yMax - this.mask_mcBounds.yMin;
+		/*
+		* Since all shapes of the de.alex_uhlmann.animationpackage.drawing package
+		* are centered by default, meaning that the point at 0,0 is exactly the center of the shape, 
+		* this class treats all movieclips used as a mask, like if they would be centered. 
+		* Masked movieclips can be centered any way.
+		* TODO: Needs refactoring even more badly.
+		*/
+		if(effect == "L") {			
+			posStartRel = (100 - start) / 100 * mcW;
+			posEndRel = (100 - end) / 100 * mcW;	
+			startObj.x = (this.mcBounds.xMin + posEndRel) + (mask_mcW / 2);
+			startObj.y = this.mcBounds.yMin + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);	
+			endObj.x = (this.mcBounds.xMin + posStartRel) + (mask_mcW / 2);
+			endObj.y = this.mcBounds.yMin + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);			
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);
+				this.mc._parent.globalToLocal(endObj);			
+			}	
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;			
+			if(start == 100) {				
+				endObj.x -= (mask_mcW - mcW) / 2 ;			
+			}				
+			
+		} else if(effect == "R") {			
+			posStartRel = (100 - start) / 100 * mcW;
+			posEndRel = (100 - end) / 100 * mcW;					
+			startObj.x = (this.mcBounds.xMin - posEndRel) + (mask_mcW / 2) - (mask_mcW - mcW);
+			startObj.y = this.mcBounds.yMin + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);
+			endObj.x = (this.mcBounds.xMin - posStartRel) + (mask_mcW / 2) - ((mask_mcW - mcW));
+			endObj.y = this.mcBounds.yMin + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);			
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);
+				this.mc._parent.globalToLocal(endObj);			
+			}
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;			
+			if(start == 100) {
+				endObj.x += ((mask_mcW - mcW) / 2);			
+			}			
+			
+		} else if(effect == "T") {
+			posStartRel = (100 - start) / 100 * mcH;
+			posEndRel = (100 - end) / 100 * mcH;		
+			startObj.x = this.mcBounds.xMin + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			startObj.y = (this.mcBounds.yMin + posEndRel) + (mask_mcH / 2);	
+			endObj.x = this.mcBounds.xMin + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			endObj.y = (this.mcBounds.yMin + posStartRel) + (mask_mcH / 2);				
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);
+				this.mc._parent.globalToLocal(endObj);			
+			}
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;	
+			if(start == 100) {
+				endObj.y -= ((mask_mcH - mcH) / 2);			
+			}
+		
+		} else if(effect == "B") {
+			posStartRel = (100 - start) / 100 * mcH;
+			posEndRel = (100 - end) / 100 * mcH;						
+			startObj.x = this.mcBounds.xMin + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			startObj.y = (this.mcBounds.yMin - posEndRel) + (mask_mcH / 2) - (mask_mcH - mcH);
+			endObj.x = this.mcBounds.xMin + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			endObj.y = (this.mcBounds.yMin - posStartRel) + (mask_mcH / 2) - ((mask_mcH - mcH));
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);
+				this.mc._parent.globalToLocal(endObj);			
+			}
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;	
+			if(start == 100) {
+				endObj.y += ((mask_mcH - mcH) / 2);		
+			}
+			
+		} else if(effect == "TL") {
+			posStartRel = (100 - start) / 100 * mcW;
+			posEndRel = (100 - end) / 100 * mcW;	
+			this.mask_mc._rotation = 45;			
+			startObj.x = (this.mcBounds.xMin + posEndRel) + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			startObj.y = (this.mcBounds.yMin + posEndRel) + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);
+			endObj.x = (this.mcBounds.xMin + posStartRel) + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			endObj.y = (this.mcBounds.yMin + posStartRel) + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);			
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);
+				this.mc._parent.globalToLocal(endObj);			
+			}
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;	
+			
+		} else if(effect == "TR") {
+			posStartRel = (100 - start) / 100 * mcW;
+			posEndRel = (100 - end) / 100 * mcW;	
+			this.mask_mc._rotation = 45;			
+			startObj.x = (this.mcBounds.xMin - posEndRel) + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			startObj.y = (this.mcBounds.yMin + posEndRel) + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);
+			endObj.x= (this.mcBounds.xMin - posStartRel) + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			endObj.y = (this.mcBounds.yMin + posStartRel) + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);			
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);
+				this.mc._parent.globalToLocal(endObj);			
+			}
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;	
+		
+		} else if(effect == "BL") {
+			posStartRel = (100 - start) / 100 * mcW;
+			posEndRel = (100 - end) / 100 * mcW;		
+			this.mask_mc._rotation = 45;		
+			startObj.x = (this.mcBounds.xMin + posEndRel) + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			startObj.y = (this.mcBounds.yMin - posEndRel) + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);
+			endObj.x = (this.mcBounds.xMin + posStartRel) + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			endObj.y = (this.mcBounds.yMin - posStartRel) + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);			
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);
+				this.mc._parent.globalToLocal(endObj);			
+			}
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;	
+			
+		} else if(effect == "BR") {
+			posStartRel = (100 - start) / 100 * mcW;
+			posEndRel = (100 - end) / 100 * mcW;
+			this.mask_mc._rotation = 45;			
+			startObj.x = (this.mcBounds.xMin - posEndRel) + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			startObj.y = (this.mcBounds.yMin - posEndRel) + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);
+			endObj.x= (this.mcBounds.xMin - posStartRel) + (mask_mcW / 2) - ((mask_mcW - mcW) / 2);
+			endObj.y = (this.mcBounds.yMin - posStartRel) + (mask_mcH / 2) - ((mask_mcH - mcH) / 2);
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);
+				this.mc._parent.globalToLocal(endObj);			
+			}
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;	
+			
+		} else if(effect == "CUSTOM") {
+			
+		}
+		
+		this.unhideMask();
+		this.setMask();		
+		var endObj2:Object = new Object();
+		startObj.x = adjustmentObj.startX;
+		startObj.y = adjustmentObj.startY;		
+		endObj2.x = adjustmentObj.endX;
+		endObj2.y = adjustmentObj.endY;
+		if(mcPathCont == mask_mcPathCont) {			
+			this.mc._parent.globalToLocal(startObj);
+			this.mc._parent.globalToLocal(endObj2);			
+		}		
+		if(adjustmentObj.startX != null) {			
+			this.mask_mc._x = startObj.x;			
+		}
+		if(adjustmentObj.startY != null) {			
+			this.mask_mc._y = startObj.y;			
+		}
+		if(adjustmentObj.endX != null) {			
+			endObj.x = endObj2.x;			
+		}
+		if(adjustmentObj.endY != null) {
+			endObj.y = endObj2.y;		
+		}
+		this.myMove = new Move(this.mask_mc,endObj.x,endObj.y);
+		this.myMaskAnimation = this.myMove;
+		this.myMove.animationStyle(this.duration, this.easing);
+		this.myMove.addEventListener("onStart", this);
+		this.myMove.addEventListener("onUpdate", this);
+		this.myMove.addEventListener("onEnd", this);		
+		if(goto == false) {
+			this.myMove.animate(0,100);
+		} else {
+			this.myMove.goto(percentage);
+		}
+		this.myAnimator = this.myMove.myAnimator;
+		this.setStartValues(this.myMove.getStartValues());
+		this.setEndValues(this.myMove.getEndValues());
+	}
+	
+	/**
+	* @method run
+	* @description   Animates a mask using move effects from and to a specified amount in a specified time and easing equation. 
+	* 				See class description for details.
+	* @usage   <pre>myMaskMoveFX.run(effect, start, end);</pre>
+	* 		<pre>myMaskMoveFX.run(effect, start, end, duration);</pre>
+	* 		<pre>myMaskMoveFX.run(effect, start, end, duration, callback);</pre>
+	*		<pre>myMaskMoveFX.run(effect, start, end, duration, easing, callback);</pre>
+	* 		<pre>myMaskMoveFX.run(effect, start, end, adjustmentObj);</pre>
+	* 		<pre>myMaskMoveFX.run(effect, start, end, adjustmentObj, duration);</pre>
+	* 		<pre>myMaskMoveFX.run(effect, start, end, adjustmentObj, duration, callback);</pre>
+	*		<pre>myMaskMoveFX.run(effect, start, end, adjustmentObj, duration, easing, callback);</pre>
+	* 	  
+	* @param effect (String) Specifies the mask move FX.
+	* @param start (Number) Amount to animated from. Percentage.
+	* @param end (Number) Targeted amount to animated to. Percentage.
+	* @param adjustmentObj (Object) Optional. Object with five properties that overwrite the default properties that define the move effect of the mask. You only need this parameter if you are not contented with the default move effect of the mask or if you use the CUSTOM move effect.
+	* @param duration (Object) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	public function run():Void {		
+		var start:Number = arguments[1];
+		var end:Number = arguments[2];
+		arguments.splice(1, 2);		
+		this.initAnimation.apply(this, arguments);		
+		this.invokeAnimation(start, end);	
+	}
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myMaskMoveFX.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValues
+	* @description 	returns the original, starting values of the current tween. _x and _y properties.
+	* @usage   <tt>myInstance.getStartValues();</tt>
+	* @return (Array) First value is _x, second is _y.
+	*/
+	
+	/**
+	* @method getEndValues
+	* @description 	returns the targeted values of the current tween. _x and _y properties.
+	* @usage   <tt>myInstance.getEndValues();</tt>
+	* @return (Array) First value is _x, second is _y.
+	*/
+
+	/**
+	* @method getCurrentValues
+	* @description 	returns the current values of the current tween. _x and _y properties.
+	* @usage   <tt>myInstance.getCurrentValues();</tt>
+	* @return (Array) First value is _x, second is _y.
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myMaskMoveFX.addEventListener(event, listener);</pre>
+	* 		    <pre>myMaskMoveFX.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myMaskMoveFX.removeEventListener(event, listener);</pre>
+	* 		    <pre>myMaskMoveFX.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myMaskMoveFX.removeAllEventListeners();</pre>
+	* 		    <pre>myMaskMoveFX.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myMaskMoveFX.eventListenerExists(event, listener);</pre>
+	* 			<pre>myMaskMoveFX.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {		
+		return "MaskMoveFX";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskMoveFX.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskScaleFX.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskScaleFX.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskScaleFX.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,641 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.MaskCore;
+import de.alex_uhlmann.animationpackage.animation.Scale;
+
+/*inspired from Jon Williams, shovemedia.com, ActionScript Timeline Class v2.0 beta*/
+/**
+* @class MaskScaleFX
+* @author Alex Uhlmann, Ben Jackson
+* @description 	Animates a mask using scale effects. 
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			You can also send the animationStyle properties via the run() method or via the constructor. See the following examples.
+* 			The scale effect needs to 
+* 			be specified as a string abbreviation. Available mask scale effects are:
+* 			<blockquote><pre>
+* 			"CENTER" = scales the mask proportional.
+* 			"HORIZ" = horizontal, stretches the mask horizontally. Scales the _xscale property.
+* 			"VERT" = vertical, stretches the mask vertically. Scales the _yscale property.
+* 			"CUSTOM" = scales the mask according to the adjustmentObj parameter.
+* 			</pre></blockquote>
+* 			<p> 
+* 			Example 1: Draw a circle and use it as a mask over movieclip mc.
+* 			<blockquote><pre>
+*			var myEllipse:Ellipse = new Ellipse();
+*			myEllipse.draw();
+*			var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc,myEllipse.movieclip);
+*			myMaskScaleFX.animationStyle(2000,Circ.easeInOut);
+*			myMaskScaleFX.run("CENTER",0,100);
+* 			</pre></blockquote>
+* 			If you don't specify a mask movieclip, 
+* 			a Rectangle will be created in the parent timeline of mc. 
+* 			<p> 
+* 			Example 2: <a href="MaskScaleFX_02.html">(Example .swf)</a> Draw a star and use it as a mask over movieclip mc.
+* 			<blockquote><pre>
+*			var myStar:Star = new Star();
+*			myStar.draw();				
+*			var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc,myStar.movieclip);
+*			myMaskScaleFX.animationStyle(2000,Circ.easeInOut);				
+*			myMaskScaleFX.run("CENTER",500,0); 
+* 			</pre></blockquote>
+* 			<p>
+* 			You can alter a predefined scale effect or you can define a custom scale effect 
+* 			via the adjustmentObj. The adjustmentObj of MaskScaleFX is an Object that contains six optional properties.
+* 			<blockquote><pre>
+* 			startX = Start point to begin animation. Coordinate point x.
+* 			startY = Start point to begin animation. Coordinate point y.
+* 			startXScale = Specifies the starting _xscale property.
+* 			startYScale = Specifies the starting _yscale property.
+*			endXScale = Specifies the ending _xscale property.
+*			endYScale = Specifies the ending _yscale property.
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 3: Modify example 1. Overwrite the center starting points.
+* 			<blockquote><pre>
+* 			var myEllipse:Ellipse = new Ellipse();
+*			myEllipse.draw();
+*			var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc,myEllipse.movieclip);
+*			myMaskScaleFX.animationStyle(2000,Circ.easeInOut);	
+*			myMaskScaleFX.run("CENTER",0,200,{	
+*							startX:mc._x+10,
+*							startY:mc._y+10});
+*			</pre></blockquote>
+* 			<p>
+* 			Example 4: <a href="MaskScaleFX_04.html">(Example .swf)</a> You can define an entire different scale animation, using the CUSTOM effect.
+*  			<blockquote><pre>
+*			var myRect:Rectangle = new Rectangle();
+*			myRect.draw();
+* 			myRect.movieclip._rotation = 45;
+*			var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc,myRect.movieclip);
+*			myMaskScaleFX.animationStyle(2000,Circ.easeInOut);
+*			myMaskScaleFX.run("CUSTOM",0,100,{				  					
+*							startX:340,
+*							startY:350,
+*							startXScale:200,
+*							startYScale:200,
+*							endXScale:450,
+*							endYScale:450});
+*			</pre></blockquote>
+* 			<p>
+* 			Note that the start and end values (0 and 100) in example 4 have no effect when using the CUSTOM scale effect.
+* 			<p>
+* 			Note that all examples above created a mask movieclip above the masked mc. 
+* 			If you want to manipulate physical movieclip properties of the masked movieclip, and at the same time 
+* 			animate the movieclip with a mask effect, the mask effect would be disturbed. Here is a workaround:
+* 			<p>
+* 			Example 5: <a href="MaskScaleFX_05.html">(Example .swf)</a> Using the Parallel class we use a mask effect and manipulate many physical properties of movieclip "mc" at the same time.
+* 			<pre><blockquote>
+* 			var myMoveOnQuadCurve:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,300,300,500,100);
+*			var myScale:Scale = new Scale(mc,50,50);
+*			var myRotation:Rotation = new Rotation(mc,360);
+*			var myColorTransform:ColorTransform = new ColorTransform(mc,0xff0000,50);
+* 			//create the mask movieclip inside the movieclip mc to reflect all manipulations to mc.
+*			var mask_mc:MovieClip = mc.createEmptyMovieClip("mask_mc",1);
+*			var myRect:Rectangle = new Rectangle(mask_mc,50,50,100,50);
+*			myRect.draw();
+* 			//since the mask is inside mc you have to mask a movieclip inside mc.
+* 			var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc.inner_mc,myRect.movieclip,"CENTER");
+*			
+*			var myParallel:Parallel = new Parallel();
+*			myParallel.addChild(myMoveOnQuadCurve);
+*			myParallel.addChild(myScale);
+*			myParallel.addChild(myRotation);
+*			myParallel.addChild(myColorTransform);
+*			myParallel.addChild(myMaskScaleFX);
+*			myParallel.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			myParallel.animate(0,100);
+*			myListener.onCallback = function(source) {	
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</blockquote></pre>
+* 			<p>
+* @usage 
+* 		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc);</pre> 
+* 		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc);</pre> 
+* 		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc, effect);</pre>
+* 		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc, effect, duration);</pre>
+* 		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc, effect, duration, callback);</pre>
+*		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc, effect, duration, easing, callback);</pre>
+* 		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc, effect, adjustmentObj);</pre>
+* 		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc, effect, adjustmentObj, duration);</pre>
+* 		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc, effect, adjustmentObj, duration, callback);</pre>
+*		<pre>var myMaskScaleFX:MaskScaleFX = new MaskScaleFX(mc, mask_mc, effect, adjustmentObj, duration, easing, callback);</pre>
+* 
+* @param mc (MovieClip) movieclip to be masked.
+* @param mask_mc (MovieClip) movieclip to use as a mask. If null or omitted, a Rectangle will be created in the parent timeline of mc.	  
+* @param effect (String) Specifies the mask scale FX.
+* @param start (Number) Amount to animated from. Percentage.
+* @param end (Number) Targeted amount to animated to. Percentage.
+* @param adjustmentObj (Object) Optional. Object with six properties that overwrite the default properties that define the scale effect of the mask. You only need this parameters if you are not contented with the default scale effect of the mask or if you use the CUSTOM scale effect.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.MaskScaleFX 
+											extends MaskCore 
+											implements ISingleAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to be masked.
+	* @property maskMovieclip (MovieClip) Movieclip to use as a mask.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/	
+	private var myScale:Scale;
+	
+	public function MaskScaleFX(mc:MovieClip, mask_mc:MovieClip) {
+		super(mc, mask_mc);
+		if(arguments.length > 2) {			
+			this.initAnimation.apply(this, arguments.slice(2));
+		}
+	}
+
+	private function initAnimation(effect:String, adjustmentObj:Object, duration:Object, easing:Object, callback:String):Void {		
+		this.effect = effect;
+		this.adjustmentObj = adjustmentObj;		
+		var temp;
+		var paramLen:Number = 4;		
+		if(typeof(adjustmentObj) == "number") {
+			temp = adjustmentObj;
+			var temp_ms:Number = temp;                  
+			var temp_easing = duration;
+			temp = easing;
+			easing = temp_easing;
+		        callback = temp;			
+			this.animationStyle(temp_ms, easing, callback);
+		} else if (arguments.length > paramLen) {			
+			temp = duration;
+			this.animationStyle(temp, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		this.getBounds();
+		var scaleOffset:Number = this.adjustmentObj.scaleOffset;
+		if(effect != "CUSTOM") {
+			if(scaleOffset == null) {
+				scaleOffset = 140;
+			}
+			this.matchSize(scaleOffset);
+		} 
+	}
+
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		
+		var goto:Boolean;
+		var percentage:Number = start;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;
+			end = 100 - end;
+			if(omitEvent) {
+				return;
+			}			
+		} else {
+			goto = false;
+		}
+		this.tweening = true;
+		var effect:String = this.effect;
+		var adjustmentObj:Object = this.adjustmentObj;	
+		if(adjustmentObj.start != null 
+			&& adjustmentObj.end != null) {
+			
+			start = adjustmentObj.start;
+			end = adjustmentObj.end;
+		}		
+		
+		var posStartRel:Number;
+		var posEndRel:Number;
+		var startObj:Object = new Object();	
+		var endXScale:Number;
+		var endYScale:Number;
+		var mcPath:String = targetPath(this.mc);
+		var mask_mcPath:String = targetPath(this.mask_mc);
+		var mcPathCont:String  = mcPath.substring(0, mcPath.indexOf(".",8));
+		var mask_mcPathCont:String = mask_mcPath.substring(0, mask_mcPath.indexOf(".",8));
+		this.getBounds();
+		var mcW:Number = this.mcBounds.xMax - this.mcBounds.xMin;
+		var mcH:Number = this.mcBounds.yMax - this.mcBounds.yMin;
+		var mask_mcW:Number = this.mask_mcBounds.xMax - this.mask_mcBounds.xMin;
+		var mask_mcH:Number = this.mask_mcBounds.yMax - this.mask_mcBounds.yMin;
+		/*
+		* Since all shapes of the de.alex_uhlmann.animationpackage.drawing package
+		* are centered, meaning that the point at 0,0 is exactly the center of the shape, 
+		* this class treats all movieclips used as a mask, like if they would be centered. 
+		* Masked movieclips can be centered any way.
+		* TODO: Needs refactoring badly.
+		*/
+		if(effect == "CENTER") {			
+			posStartRel = (100 - start) / 100 * this.resetXscale;
+			posEndRel = (100 - end) / 100 * this.resetYscale;			
+			//posStartRel = this.resetXscale;
+			//posEndRel = this.resetYscale;			
+			
+			startObj.x = this.mcBounds.xMax - (mcW / 2);
+			startObj.y = this.mcBounds.yMax - (mcH / 2);	
+			this.mask_mc._xscale = this.resetXscale - posEndRel;
+			this.mask_mc._yscale = this.resetYscale - posEndRel;
+			endXScale = posStartRel - this.resetXscale;
+			endYScale = posStartRel - this.resetYscale;			
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);						
+			}			
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;		
+			
+		} else if(effect == "HORIZ") {			
+			//posStartRel = (100 - start) / 100 * this.resetXscale;
+			//posEndRel = (100 - end) / 100 * this.resetXscale;			
+			startObj.x = this.mcBounds.xMax - (mcW / 2);
+			startObj.y = this.mcBounds.yMax - (mcH / 2);	
+			this.mask_mc._xscale = this.resetXscale - posEndRel;
+			endXScale = posStartRel - this.resetXscale;			
+			endYScale =  this.resetYscale;		
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);						
+			}			
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;
+			
+		} else if(effect == "VERT") {			
+			posStartRel = (100 - start) / 100 * this.resetYscale;
+			posEndRel = (100 - end) / 100 * this.resetYscale;			
+			startObj.x = this.mcBounds.xMax - (mcW / 2);
+			startObj.y = this.mcBounds.yMax - (mcH / 2);	
+			this.mask_mc._yscale = this.resetYscale - posEndRel;
+			endYScale = posStartRel - this.resetYscale;			
+			endXScale =  this.resetXscale;			
+			if(mcPathCont == mask_mcPathCont) {				
+				this.mc._parent.globalToLocal(startObj);						
+			}			
+			this.mask_mc._x = startObj.x;
+			this.mask_mc._y = startObj.y;
+			
+		} else if(effect == "CUSTOM") {
+			
+		}		
+		this.unhideMask();
+		this.setMask();		
+		startObj.x = adjustmentObj.startX;
+		startObj.y = adjustmentObj.startY;		
+		if(mcPathCont == mask_mcPathCont) {			
+			this.mc._parent.globalToLocal(startObj);		
+		}		
+		if(adjustmentObj.startX != null) {			
+			this.mask_mc._x = startObj.x;			
+		}
+		if(adjustmentObj.startY != null) {			
+			this.mask_mc._y = startObj.y;			
+		}
+		if(adjustmentObj.startXScale != null) {			
+			this.mask_mc._xscale = adjustmentObj.startXScale;		
+		}
+		if(adjustmentObj.startYScale != null) {
+			this.mask_mc._yscale = adjustmentObj.startYScale;		
+		}
+		if(adjustmentObj.endXScale != null) {					
+			endXScale = adjustmentObj.endXScale;			
+		}
+		if(adjustmentObj.endYScale != null) {			
+			endYScale = adjustmentObj.endYScale;
+		}
+		this.myScale = new Scale(this.mask_mc,endXScale,endYScale);		
+		this.myMaskAnimation = this.myScale;
+		this.myScale.animationStyle(this.duration, this.easing);
+		this.myScale.addEventListener("onStart", this);
+		this.myScale.addEventListener("onUpdate", this);
+		this.myScale.addEventListener("onEnd", this);
+		if(goto == false) {			
+			this.myScale.animate(0, 100);
+		} else {
+			this.myScale.goto(percentage);
+		}
+		this.myAnimator = this.myScale.myAnimator;
+		this.setStartValues(this.myScale.getStartValues());
+		this.setEndValues(this.myScale.getEndValues());
+	}
+
+	/**
+	* @method run
+	* @description 	Animates a mask using scale effects from and to a specified amount 
+	* 				in a specified time and easing equation. See class description for details.
+	* in global scope. If you want to use a mask effect on a movieclip which is manipulated during 
+	* @usage   <pre>myMaskScaleFX.run(effect, start, end);</pre>
+	* 		<pre>myMaskScaleFX.run(effect, start, end, duration);</pre>
+	* 		<pre>myMaskScaleFX.run(effect, start, end, duration, callback);</pre>
+	*		<pre>myMaskScaleFX.run(effect, start, end, duration, easing, callback);</pre>
+	* 		<pre>myMaskScaleFX.run(effect, start, end, adjustmentObj);</pre>
+	* 		<pre>myMaskScaleFX.run(effect, start, end, adjustmentObj, duration);</pre>
+	* 		<pre>myMaskScaleFX.run(effect, start, end, adjustmentObj, duration, callback);</pre>
+	*		<pre>myMaskScaleFX.run(effect, start, end, adjustmentObj, duration, easing, callback);</pre>
+	* 	  
+	* @param effect (String) Specifies the mask scale FX.
+	* @param start (Number) Amount to animated from. Percentage.
+	* @param end (Number) Targeted amount to animated to. Percentage.
+	* @param adjustmentObj (Object) Optional. Object with six properties that overwrite the default properties that define the scale effect of the mask. You only need this parameters if you are not contented with the default scale effect of the mask or if you use the CUSTOM scale effect.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/	
+	public function run():Void {		
+		var start:Number = arguments[1];
+		var end:Number = arguments[2];
+		arguments.splice(1, 2);		
+		this.initAnimation.apply(this, arguments);
+		this.invokeAnimation(start, end);
+	}
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myMaskScaleFX.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValues
+	* @description 	returns the original, starting values of the current tween. _xscale and _yscale properties.
+	* @usage   <tt>myInstance.getStartValues();</tt>
+	* @return (Array) First value is _xscale, second is _yscale.
+	*/
+	
+	/**
+	* @method getEndValues
+	* @description 	returns the targeted values of the current tween. _xscale and _yscale properties.
+	* @usage   <tt>myInstance.getEndValues();</tt>
+	* @return (Array) First value is _xscale, second is _yscale.
+	*/
+
+	/**
+	* @method getCurrentValues
+	* @description 	returns the current values of the current tween. _xscale and _yscale properties.
+	* @usage   <tt>myInstance.getCurrentValues();</tt>
+	* @return (Array) First value is _xscale, second is _yscale.
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myMaskScaleFX.addEventListener(event, listener);</pre>
+	* 		    <pre>myMaskScaleFX.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myMaskScaleFX.removeEventListener(event, listener);</pre>
+	* 		    <pre>myMaskScaleFX.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myMaskScaleFX.removeAllEventListeners();</pre>
+	* 		    <pre>myMaskScaleFX.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myMaskScaleFX.eventListenerExists(event, listener);</pre>
+	* 			<pre>myMaskScaleFX.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {		
+		return "MaskScaleFX";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MaskScaleFX.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Move.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Move.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Move.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,553 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Move
+* @author Alex Uhlmann
+* @description Manipulates _x and _y properties of a movieclip or a number of movieclips.<p>
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>			
+*			var myMove:Move = new Move(mc);
+*			myMove.animationStyle(2000,Circ.easeOut,"onCallback");
+*			myMove.run(650,mc._y);
+*			</pre></blockquote>  			
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new Move(mc).run(650,mc._y,2000,Circ.easeOut,"onCallback");
+* 			</pre></blockquote>		
+*  			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 
+* 			<blockquote><pre>
+* 			var myMove:Move = new Move(mc,400,100,2000,Circ.easeOut,"onCallback");
+* 			myMove.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValues or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+* 			<blockquote><pre>
+*			var myMove1:Move = new Move(mc,[400,50,150,50],2000,Circ.easeInOut);
+*			myMove1.addEventListener("onEnd",this);
+*			myMove1.run();
+*			function onEnd() {
+*				var myMove2:Move = new Move(mc,[150,300,150,50],2000,Circ.easeInOut);
+*				myMove2.run();
+*			}
+* 			</pre></blockquote><p>
+*  			Example 5: Move a movieclip to _x 100 and _y 100 in 1 second using linear easing. 		
+* 			<blockquote><pre>
+*			new Move(mc).run(100,100);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 6: Set a movieclip to _x 200 and moves it in two seconds along the y axis 
+* 			using circular easing. After animation move it back to _x 200 using elastic easing.
+* 			<blockquote><pre>			
+*			mc._x = 200;
+*			new Move(mc).run(650,mc._y,2000,Circ.easeOut,"onCallback");	
+*			myListener.onCallback = function() {
+*				new Move(mc).run(200,mc._y,2000,Elastic.easeOut);	
+*			}
+*			</pre></blockquote><p>
+* 			Example 7: To animate many movieclips the same way, this class also accepts 
+* 			an Array of movieclips instead of one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want to animate. Different 
+* 			start values of your movieclip properties are considered when animating multiple movieclips 
+* 			within one animation instance.
+* 			<blockquote><pre>
+* 			var mcs:Array = new Array(mc1,mc2,mc3);
+*			var myMove:Move = new Move(mcs);
+*			myMove.animationStyle(2000,Circ.easeOut,"onCallback");
+*			myMove.run(50,mc._y);
+* 			</pre></blockquote>
+* 
+* @usage 
+* 		<pre>var myMove:Move = new Move(mc);</pre>
+*		<pre>var myMove:Move = new Move(mc, amountx, amounty);</pre>
+* 		<pre>var myMove:Move = new Move(mc, amountx, amounty, duration);</pre>
+*		<pre>var myMove:Move = new Move(mc, amountx, amounty, duration, callback);</pre>
+* 		<pre>var myMove:Move = new Move(mc, amountx, amounty, duration, easing, callback);</pre> 
+*		<pre>var myMove:Move = new Move(mc, values);</pre> 
+* 		<pre>var myMove:Move = new Move(mc, values, duration, callback);</pre> 
+* 		<pre>var myMove:Move = new Move(mc, values, duration, easing, callback);</pre> 
+* 		<pre>var myMove:Move = new Move(mcs);</pre>
+*		<pre>var myMove:Move = new Move(mcs, amountx, amounty);</pre>
+* 		<pre>var myMove:Move = new Move(mcs, amountx, amounty, duration);</pre>
+*		<pre>var myMove:Move = new Move(mcs, amountx, amounty, duration, callback);</pre>
+* 		<pre>var myMove:Move = new Move(mcs, amountx, amounty, duration, easing, callback);</pre> 
+*		<pre>var myMove:Move = new Move(mcs, values);</pre> 
+* 		<pre>var myMove:Move = new Move(mcs, values, duration, callback);</pre> 
+* 		<pre>var myMove:Move = new Move(mcs, values, duration, easing, callback);</pre>
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param amountx (Number) Targeted _x to animate to.
+* @param amounty (Number) Targeted _y to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See APCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Move 
+										extends AnimationCore 
+										implements IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/
+	public var xProperty:String = "_x";
+	public var yProperty:String = "_y";
+	public var rotationProperty:String = "_rotation";
+	private var pathOrientation:Boolean = false;	
+	
+	public function Move() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+
+	private function init():Void {
+		if(arguments[0] instanceof Array) {				
+			var values:Array = arguments[0];
+			var endValues:Array = values.slice(-2);
+			arguments.shift();
+			arguments.splice(0, 0, endValues[0], endValues[1]);
+			this.initAnimation.apply(this, arguments);
+			this.setStartValues([values[0], values[1]]);
+		} else if(arguments.length > 0) {			
+			this.initAnimation.apply(this, arguments);
+		}
+	}
+
+	private function initAnimation(amountx:Number, amounty:Number, 
+						duration:Number, easing:Object, callback:String):Void {
+	
+		if (arguments.length > 2) {
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}	
+		if(this.mc != null) {
+			this.setStartValues([this.mc[this.xProperty], this.mc[this.yProperty]], true);
+		}
+		this.setEndValues([amountx, amounty]);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		this.startInitialized = false;
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = this.endValues;
+		
+		if(this.mc != null) {
+			
+			this.myAnimator.start = this.startValues;
+			this.myAnimator.setter = [[this.mc,this.xProperty], [this.mc,this.yProperty]];
+			
+		} else {
+
+			this.myAnimator.multiStart = [this.xProperty,this.yProperty];										
+			this.myAnimator.multiSetter = [[this.mcs,this.xProperty], 
+									[this.mcs,this.yProperty]];
+		
+		}		
+
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+		
+		if(this.pathOrientation == true) {
+			this.rotate(this.startValues[0], this.startValues[1], 
+						this.endValues[0], this.endValues[1]);			
+		}
+	}
+	
+	private function rotate(startx:Number, starty:Number, endx:Number, endy:Number):Void {		
+		var t:Number, deg:Number;
+		var d:Number;
+		if(starty > this.endValues[1]) {
+			d = Math.abs(endx - startx) / Math.abs(endy - starty);
+			t = Math.atan(d);
+		} else {
+			d = Math.abs(endy - starty) / Math.abs(endx - startx);
+			t = Math.atan(d) + Math.PI / 2;
+		}
+		deg = t * (180 / Math.PI);
+		if(startx > endx) {
+			this.mc[this.rotationProperty] = -deg;
+		} else {
+			this.mc[this.rotationProperty] = deg;
+		}		
+	}
+	
+	/**
+	* @method run
+	* @description  		
+	* @usage   
+	* 
+	* 		<pre>myMove.run();</pre>
+	* 		<pre>myMove.run(amountx, amounty);</pre>
+	* 		<pre>myMove.run(amountx, amounty, duration);</pre>
+	*		<pre>myMove.run(amountx, amounty, duration, callback);</pre>
+	* 		<pre>myMove.run(amountx, amounty, duration, easing, callback);</pre>
+	* 		<pre>myMove.run(values, duration);</pre>
+	* 		<pre>myMove.run(values, duration, callback);</pre>
+	*		<pre>myMove.run(values, duration, easing, callback);</pre>
+	* 
+	* @param amountx (Number) Targeted _x to animate to.
+	* @param amounty (Number) Targeted _y to animate to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myMove.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method orientToPath
+	* @description 	offers the opportunity to rotate the object towards the line while animating.
+	* 				Default is false. If true the object orientates on the line.
+	*                  		If false the object's rotation will not be altered.
+	* 			Example 1:
+	* 			<blockquote><pre>
+	*			var myMove:Move = new Move(mc,[100,50,400,300]);
+	*			myMove.orientToPath(true);
+	*			myMove.animate(0,100);
+	*			</pre></blockquote>
+	* @usage   <pre>myInstance.orientToPath(pathOrientation);</pre> 	  
+	* @param pathOrientation (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/
+	public function orientToPath(bool:Boolean):Void {
+		this.pathOrientation = bool;
+	}	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValues
+	* @description 	returns the original, starting values of the current tween. _x and _y properties.
+	* @usage   <tt>myInstance.getStartValues();</tt>
+	* @return (Array) First value is _x, second is _y.
+	*/
+	
+	/**
+	* @method setStartValues
+	* @description 	sets the original, starting values of the current tween. _x and _y properties.
+	* @usage   <tt>myInstance.setStartValues(startValues);</tt>
+	* @param startValues (Array) First value is _x, second is _y.
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValues
+	* @description 	returns the targeted values of the current tween. _x and _y properties.
+	* @usage   <tt>myInstance.getEndValues();</tt>
+	* @return (Array) First value is _x, second is _y.
+	*/
+	
+	/**
+	* @method setEndValues
+	* @description 	sets the targeted value of the current tween. _x and _y properties.
+	* @usage   <tt>myInstance.setEndValues(endValues);</tt>
+	* @param endValues (Array) First value is _x, second is _y.
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValues
+	* @description 	returns the current values of the current tween. _x and _y properties.
+	* @usage   <tt>myInstance.getCurrentValues();</tt>
+	* @return (Array) First value is _x, second is _y.
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Array) values to animate.<p>
+	* 		
+	* @usage   <pre>myMove.addEventListener(event, listener);</pre>
+	* 		    <pre>myMove.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myMove.removeEventListener(event, listener);</pre>
+	* 		    <pre>myMove.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myMove.removeAllEventListeners();</pre>
+	* 		    <pre>myMove.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myMove.eventListenerExists(event, listener);</pre>
+	* 			<pre>myMove.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Move";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Move.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCubicCurve.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCubicCurve.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCubicCurve.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,682 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.BezierToolkit;
+
+/**
+* @class MoveOnCubicCurve
+* @author Alex Uhlmann, Steve Schwarz
+* @description  Moves a movieclip along a specified cubic bezier curve in a specified time and easing equation.
+* 			The curve is specified with four points. Start point, two points on the curve or control points, end point.
+* 			With the useControlPoints method you can specify control points instead of points on the curve, 
+* 			which is the default. The MovieClip.curveTo method uses control points i.e.
+* 			<p>
+* 			Example 1: <a href="MoveOnCubicCurve_run_01.html">(Example .swf)</a> 
+* 			Declare 8 variables to store the four points that define the curve 
+* 			for easy access. To visualize the points and the curve draw it with 
+* 			the classes of the de.alex_uhlmann.animationpackage.drawing package. Then, 
+*  			move the movieclip along the specified curve in three seconds using Bounce easing.
+* 			Draw circles on the current positions of the movieclip.
+*  			<pre><blockquote>
+*			var x1:Number = 100;
+*			var y1:Number = 100;
+*			var x2:Number = 300;
+*			var y2:Number = 300;
+*			var x3:Number = 500;
+*			var y3:Number = 100;
+*			var x4:Number = 500;
+*			var y4:Number = 400;
+*			
+*			new Ellipse(x1,y1,10,10).draw();						
+*			new Ellipse(x2,y2,10,10).draw();
+*			new Ellipse(x3,y3,10,10).draw();
+*			new Ellipse(x4,y4,10,10).draw();
+*			
+*			var myEllipse:Ellipse = new Ellipse(x1,y1,15,15)
+*			myEllipse.lineStyle(1,0xff0000);
+*			myEllipse.fillStyle(0xff0000);
+*			myEllipse.draw();
+*			
+*			var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(myEllipse.movieclip);
+*			myMOC.animationStyle(3000,Bounce.easeOut);
+*			//draw a circle in every function update.
+*			var myObject:Object = new Object();
+*			myMOC.addEventListener("onUpdate",myObject);
+*			myObject.onUpdate = function(eventObject:Object) {
+*				var mc:MovieClip = eventObject.target.movieclip;
+* 				new Ellipse(mc._x,mc._y,3,3).draw();
+*			}
+*			
+*			myMOC.run(x1,y1,x2,y2,x3,y3,x4,y4);
+*			</pre></blockquote>
+* 			Example 2: Move a movieclip along the curve in 4 seconds using circular easing. 		
+* 			<blockquote><pre>
+*			new MoveOnQuadCurve(mc).run(100,100,300,300,500,100,500,400,4000,Circ.easeInOut);			
+* 			</pre></blockquote>
+* 			<p>		
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 3:
+* 			<blockquote><pre>			
+*			var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc);
+*			myMOC.animationStyle(4000,Circ.easeInOut);
+*			myMOC.run(100,100,300,300,500,100,500,400);
+*			</pre></blockquote>  			
+* 			Example 4: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new MoveOnCubicCurve(mc).run(100,100,300,300,500,100,500,400,4000,Circ.easeInOut);
+* 			</pre></blockquote>		
+*  			Example 5: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 
+* 			<blockquote><pre>
+* 			var myMoveOnCubicCurve:MoveOnCubicCurve = new MoveOnCubicCurve(mc,100,100,300,300,500,100,500,400,4000,Circ.easeInOut);
+* 			myMoveOnCubicCurve.animate(0,100);
+* 			</pre></blockquote>
+* @usage <pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc);</pre> 
+* 		<pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4);</pre>
+*		<pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4, duration);</pre>
+* 		<pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4, duration, callback);</pre>
+* 		<pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4, duration, easing, callback);</pre>
+* 		<pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints);</pre>
+*		<pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints, duration);</pre>
+* 		<pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints, duration, callback);</pre>
+* 		<pre>var myMOC:MoveOnCubicCurve = new MoveOnCubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints, duration, easing, callback);</pre>
+* @param mc (MovieClip) Movieclip to animate.
+* @param x1 (Number) start point to define curve. Coordinate point x
+* @param y1 (Number) start point to define curve. Coordinate point y
+* @param x2 (Number) point on the curve or control point to define curve. Coordinate point x
+* @param y2 (Number) point on the curve or control point to define curve. Coordinate point y
+* @param x3 (Number) point on the curve or control point to define curve. Coordinate point x
+* @param y3 (Number) point on the curveor control point to define curve. Coordinate point y
+* @param x4 (Number) end point to define curve. Coordinate point x
+* @param y4 (Number) end point to define curve. Coordinate point y 
+* @param withControlpoints (Boolean) specify control points between the start and end points of the curve instead of points on the curve. Default is false.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See APCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.MoveOnCubicCurve 
+											extends AnimationCore 
+											implements ISingleAnimatable {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/	
+	private var mc:MovieClip;
+	private var x1:Number;
+	private var y1:Number;
+	private var x2:Number;
+	private var y2:Number;
+	private var x3:Number;
+	private var y3:Number;
+	private var x4:Number;
+	private var y4:Number;
+	private var myBezierToolkit:BezierToolkit;
+	private var p1:Object;
+	private var p2:Object;
+	private var p3:Object;
+	private var p4:Object;
+	private var withControlpoints:Boolean = false;
+	private var x2ControlPoint:Number;
+	private var y2ControlPoint:Number;
+	private var x3ControlPoint:Number;
+	private var y3ControlPoint:Number;
+	private var rotateTo:Boolean = false;
+	private var rotateOn:Boolean = false;
+	private var overriddenRounded:Boolean = false;
+	
+	/*
+	* cache for last point calculated by getPointsOnCurve. 
+	* Used to calculate slope/rotation
+	*/
+	private var lastPoint:Object;
+	
+	public function MoveOnCubicCurve() {				
+		super();
+		this.mc = arguments[0];
+		if(arguments.length > 1) {			
+			this.initAnimation.apply(this, arguments.slice(1));
+		}
+	}
+	
+	private function initAnimation(x1:Number, y1:Number, x2:Number, 
+							y2:Number, x3:Number, y3:Number, x4:Number, y4:Number, withControlpoints:Object, 
+							duration:Object, easing:Object, callback:String):Void {		
+		
+		var paramLen:Number = 8;
+		
+		var temp;
+		if(typeof(withControlpoints) == "number") {
+			temp = withControlpoints;
+			var temp_ms:Number = temp;                  
+			var temp_easing = duration;
+			temp = easing;
+			easing = temp_easing;
+		        callback = temp;			
+			this.animationStyle(temp_ms, easing, callback);
+		} else if (arguments.length > paramLen) {
+			temp = duration;
+			this.animationStyle(temp, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		this.myBezierToolkit = new BezierToolkit();
+		if(typeof(withControlpoints) == "boolean") {
+			temp = withControlpoints;
+			this.withControlpoints = temp;
+		}
+		if(this.withControlpoints == false) {
+			
+			this.x2ControlPoint = x2;
+			this.y2ControlPoint = y2;
+			this.x3ControlPoint = x3;
+			this.y3ControlPoint = y3;
+			var controlPoint:Object = this.myBezierToolkit.getCubicControlPoints(x1, y1, x2, y2, x3, y3, x4, y4);
+			x2 = controlPoint.x1;
+			y2 = controlPoint.y1;
+			x3 = controlPoint.x2;
+			y3 = controlPoint.y2;
+		}
+		this.init(x1, y1, x2, y2, x3, y3, x4, y4);
+		this.setStartValue(0);
+		this.setEndValue(100);		
+	}
+	
+	private function init():Void {
+				
+		this.x1 = arguments[0];
+		this.y1 = arguments[1];
+		this.x2 = arguments[2];
+		this.y2 = arguments[3];
+		this.x3 = arguments[4];
+		this.y3 = arguments[5];
+		this.x4 = arguments[6];
+		this.y4 = arguments[7];
+		this.p1 = {x:this.x1, y:this.y1};
+		this.p2 = {x:this.x2, y:this.y2};
+		this.p3 = {x:this.x3, y:this.y3};
+		this.p4 = {x:this.x4, y:this.y4};		
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [0];
+		this.myAnimator.end = [100];
+		if(this.rotateTo == true) {
+			this.myAnimator.setter = [[this,"moveAndRotateTo"]];
+		} else if(this.rotateOn == true) {
+			this.myAnimator.setter = [[this,"moveAndRotateOn"]];
+		} else {
+			this.myAnimator.setter = [[this,"move"]];				
+		}
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	/**
+	* @method run
+	* @description 
+	* @usage  
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, x4, y4);</pre>
+	*		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, x4, y4, duration);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, x4, y4, duration, callback);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, x4, y4, duration, easing, callback);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints);</pre>
+	*		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints, duration);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints, duration, callback);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints, duration, easing, callback);</pre>
+	* 	  
+	* @param x1 (Number) start point to define curve. Coordinate point x
+	* @param y1 (Number) start point to define curve. Coordinate point y
+	* @param x2 (Number) point on the curve or control point to define curve. Coordinate point x
+	* @param y2 (Number) point on the curve or control point to define curve. Coordinate point y
+	* @param x3 (Number) point on the curve or control point to define curve. Coordinate point x
+	* @param y3 (Number) point on the curveor control point to define curve. Coordinate point y
+	* @param x4 (Number) end point to define curve. Coordinate point x
+	* @param y4 (Number) end point to define curve. Coordinate point y 
+	* @param withControlpoints (Boolean) specify control points between the start and end points of the curve instead of points on the curve. Default is false.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/	
+	public function run():Void {							
+		
+		this.initAnimation.apply(this, arguments);
+		this.invokeAnimation(0, 100);
+	}
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myMOC.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	private function move(targ:Number):Void {
+		var p:Object = this.myBezierToolkit.getPointsOnCubicCurve(targ, this.p1, this.p2, this.p3, this.p4);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);			
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;			
+		}
+	}
+	
+	private function moveAndRotateTo(targ:Number):Void {
+		var p:Object = this.myBezierToolkit.getPointsOnCubicCurve(targ, 
+												this.p1, 
+												this.p2, 
+												this.p3, 
+												this.p4);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);
+			this.mc._rotation = Math.round(this.computeRotation(targ, p) - 90);
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;
+			this.mc._rotation = this.computeRotation(targ, p) - 90;
+		}		
+	}
+	
+	private function moveAndRotateOn(targ:Number):Void {
+		var p:Object = this.myBezierToolkit.getPointsOnCubicCurve(targ, 
+												this.p1, 
+												this.p2, 
+												this.p3, 
+												this.p4);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);
+			this.mc._rotation = Math.round(this.computeRotation(targ, p));
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;
+			this.mc._rotation = this.computeRotation(targ, p);
+		}
+	}
+	
+	private function computeRotation(targ:Number, p:Object):Number {
+		if (this.lastPoint.x == undefined) {
+			//just calculated the first point. Store it.
+			this.lastPoint = p;
+			//go 1% forward to get next point
+			p = this.myBezierToolkit.getPointsOnCubicCurve(
+									targ + 1, 
+									this.p1, 
+									this.p2, 
+									this.p3, 
+									this.p4);
+		}
+		var degrees:Number = Math.atan2(this.lastPoint.y-p.y, this.lastPoint.x-p.x)/(Math.PI/180);
+		//update cache
+		this.lastPoint = p;
+		return degrees;
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+
+	/**
+	* @method orientToPath
+	* @description 	offers the opportunity to rotate the object towards the curve while animating.
+	* 				Default is false. If true the object orientates towards the curve.
+	*                  		If false the object's rotation will not be altered. See class documentation.
+	* @usage   <pre>myInstance.orientToPath(rotateTo);</pre> 	  
+	* @param rotateTo (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/	
+	public function orientToPath(bool:Boolean):Void {
+		if(bool) {
+			this.rotateOn = false;
+		}
+		this.rotateTo = bool;
+	}
+	
+	/**
+	* @method orientOnPath
+	* @description 	offers the opportunity to rotate the object on the curve while animating.
+	* 				Default is false. If true the object orientates on the curve.
+	*                  		If false the object's rotation will not be altered. See class documentation.
+	* @usage   <pre>myInstance.orientToPath(rotateOn);</pre> 	  
+	* @param rotateOn (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/	
+	public function orientOnPath(bool:Boolean):Void {
+		if(bool) {
+			this.rotateTo = false;
+		}
+		this.rotateOn = bool;
+	}
+	
+	/**
+	* @method useControlPoints
+	* @description 	offers the opportunity to specify control points between the start and end points 
+	* 				of the curve instead of points on the curve. Default is false.
+	* 				If true points between start and end points are control points.
+	*                  		If false points between start and end points are points on the curve.
+	* @usage   <pre>myInstance.useControlPoints(withControlpoints);</pre> 	  
+	* @param withControlpoints (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/
+	public function useControlPoints(withControlpoints:Boolean):Void {
+		if(withControlpoints) {
+			this.x2 = this.x2ControlPoint;
+			this.y2 = this.y2ControlPoint;
+			this.x3 = this.x3ControlPoint;
+			this.y3 = this.y3ControlPoint;
+			this.p2 = {x:this.x2, y:this.y2};
+			this.p3 = {x:this.x3, y:this.y3};
+		}
+		this.withControlpoints = withControlpoints;		
+	}
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(event, listener);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy.
+	*                  				<code>false</code> animates with floating point numbers.
+	*/
+	public function checkIfRounded(Void):Boolean {
+		return this.overriddenRounded;
+	}
+	
+	public function roundResult(overriddenRounded:Boolean):Void {
+		this.overriddenRounded = overriddenRounded;
+	}
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myMOC.addEventListener(event, listener);</pre>
+	* 		    <pre>myMOC.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myMOC.removeEventListener(event, listener);</pre>
+	* 		    <pre>myMOC.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myMOC.removeAllEventListeners();</pre>
+	* 		    <pre>myMOC.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myMOC.eventListenerExists(event, listener);</pre>
+	* 			<pre>myMOC.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "MoveOnCubicCurve";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCubicCurve.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCurve.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCurve.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCurve.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,670 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class MoveOnCurve
+* @author Alex Uhlmann, Steve Schwarz
+* @description   Moves a movieclip on along a bezier curve with n controlpoints. With MoveOnCurve 
+* 			you can create bezier curves with an arbitrary length. The start and end points are the points 
+* 			on the curve. In contrary to i.e. MoveOnQuadCurve the MoveOnCurve class by default 
+* 			uses control points instead of points on the curve between the start and end points (anchor points).<p>		
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1: <a href="MoveOnCurve_01.html">(Example .swf)</a> Draw a bezier curve with 11 
+* 			control points. Loop a movieclip on it and draw the curve for visualisation. Attach a trail with 
+* 			infinite length and make it interruptible.
+* 			<blockquote><pre>			
+*			var x1:Number = 350;
+*			var y1:Number = 50;
+*			var x2:Number = 50;
+*			var y2:Number = 50;
+*			var x3:Number = 50;
+*			var y3:Number = 200;
+*			var x4:Number = 850;
+*			var y4:Number = 200;
+*			var x5:Number = 350;
+*			var y5:Number = 350;
+*			var x6:Number = 50;
+*			var y6:Number = 350;
+*			var x7:Number = -550;
+*			var y7:Number = 500;
+*			var x8:Number = 600;
+*			var y8:Number = 600;
+*			var x9:Number = 650;
+*			var y9:Number = 500;
+*			var x10:Number = 650;
+*			var y10:Number = 50;
+*			var x11:Number = 350;
+*			var y11:Number = 50;
+*			
+*			var myStar:Star = new Star(275,200,20,10,6)
+*			myStar.lineStyle();
+*			myStar.fillStyle(0x9C3031);
+*			myStar.draw();
+*			
+*			var points:Array = new Array();
+*			points.push({x:x1, y:y1});
+*			points.push({x:x2, y:y2});
+*			points.push({x:x3, y:y3});
+*			points.push({x:x4, y:y4});
+*			points.push({x:x5, y:y5});
+*			points.push({x:x6, y:y6});
+*			points.push({x:x7, y:y7});
+*			points.push({x:x8, y:y8});
+*			points.push({x:x9, y:y9});
+*			points.push({x:x10, y:y10});
+*			points.push({x:x11, y:y11});
+*			
+*			var myMOC:MoveOnCurve = new MoveOnCurve(myStar.movieclip,points);
+*			myMOC.animationStyle(4000);
+*			myMOC.addEventListener("onEnd",this);
+*			function onEnd() {
+*				myMOC.animate(0,100);
+*			}
+*			myMOC.animate(0,100);
+*			
+*			var myCurve = new Curve(points);
+*			myCurve.lineStyle(6,0x8CA6BD);
+*			myCurve.animationStyle(4000);
+*			myCurve.animate(0,100);
+*			
+*			var myTrail:Trail = new Trail(myStar.movieclip);
+*			myTrail.attach(250,40,null);
+*			
+*			var myText:Text = new Text();
+*			myText.setText("Press the mouse to pause/resume the animation.");
+*			
+*			function onMouseDown() {
+*				if(myMOC.isTweening() == true) {
+*					myMOC.pause();
+*					myCurve.pause();
+*					myTrail.pause();
+*				} else {
+*					myMOC.resume();
+*					myCurve.resume();
+*					myTrail.resume();
+*				}
+*			}
+*			</pre></blockquote> 
+* 			Example 2: <a href="MoveOnCurve_02.html">(Example .swf)</a> Do  
+* 			the same like above just move and orientate 
+* 			the AP logo along the curve.
+* 			<blockquote><pre>
+* 			...			
+*			var myMOC:MoveOnCurve = new MoveOnCurve(mc,points);
+*			myMOC.orientOnPath(true);
+*			myMOC.animationStyle(8000);
+*			myMOC.addEventListener("onEnd",this);
+*			function onEnd() {
+*				myMOC.animate(0,100);
+*			}
+*			myMOC.animate(0,100);
+*			
+*			var myTrail:Trail = new Trail(mc);
+*			myTrail.attach(250,40,null);
+* 			...
+*			</pre></blockquote>  
+* 			Example 3: Draw a quadratic bezier curve (3 control points).
+* 			<blockquote><pre>			
+*			var points:Array = new Array();
+*			points.push({x:0, y:0});
+*			points.push({x:275, y:200});
+*			points.push({x:550, y:0});
+*			
+*			var myMOC:MoveOnCurve = new MoveOnCurve(mc);
+*			myMOC.animationStyle(4000,Circ.easeInOut);
+*			myMOC.run(points);
+*			</pre></blockquote>
+* 			Example 4: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new MoveOnCurve(mc).run([{x:0,y:0},{x:275,y:200},{x:550,y:0}],4000,Circ.easeInOut);
+* 			</pre></blockquote>		
+*  			Example 5: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end paremeters might also be useful. 
+* 			<blockquote><pre>
+*			var points:Array = new Array();
+*			points.push({x:0, y:0});
+*			points.push({x:275, y:200});
+*			points.push({x:550, y:0});
+* 
+* 			var myMOC:MoveOnCurve = new MoveOnCurve(mc,points,4000,Circ.easeInOut);
+* 			myMOC.animate(0,100);
+* 			</pre></blockquote>
+* @usage <pre>var myMOC:MoveOnCurve = new MoveOnCurve(mc);</pre> 
+* 		<pre>var myMOC:MoveOnCurve = new MoveOnCurve(mc, points);</pre>
+*		<pre>var myMOC:MoveOnCurve = new MoveOnCurve(mc, points, duration);</pre>
+* 		<pre>var myMOC:MoveOnCurve = new MoveOnCurve(mc, xpoints, duration, callback);</pre>
+* 		<pre>var myMOC:MoveOnCurve = new MoveOnCurve(mc, points, duration, easing, callback);</pre>
+* @param mc (MovieClip) Movieclip to animate.
+* @param points (Array) Array of objects with x and y properties that define the curve.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See APCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.MoveOnCurve 
+												extends AnimationCore 
+												implements ISingleAnimatable {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/	
+	private var mc:MovieClip;
+	private var points:Array;
+	private var n:Number;
+	private var rotateTo:Boolean = false;
+	private var rotateOn:Boolean = false;
+	private var overriddenRounded:Boolean = false;
+	
+	/*
+	* cache for last point calculated by getPointsOnCurve. 
+	* Used to calculate slope/rotation
+	*/
+	private var lastPoint:Object;	
+	
+	public function MoveOnCurve() {				
+		super();
+		this.mc = arguments[0];
+		if(arguments.length > 1) {			
+			this.initAnimation.apply(this, arguments.slice(1));
+		}
+	}
+	
+	private function initAnimation(points:Array, duration:Number, easing:Object, callback:String):Void {		
+		
+		var paramLen:Number = 1;
+		if (arguments.length > paramLen) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}		
+		this.points = points;
+		this.n = this.points.length-1;
+		this.setStartValue(0);
+		this.setEndValue(100);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [0];
+		this.myAnimator.end = [100];
+		if(this.rotateTo == true) {
+			this.myAnimator.setter = [[this,"moveAndRotateTo"]];
+		} else if(this.rotateOn == true) {
+			this.myAnimator.setter = [[this,"moveAndRotateOn"]];
+		} else {
+			this.myAnimator.setter = [[this,"move"]];				
+		}
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	private function move(targ:Number):Void {
+		var p:Object = this.getPointsOnCurve(targ);		
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);			
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;			
+		}
+	}
+	
+	private function moveAndRotateTo(targ:Number):Void {
+		var p:Object = this.getPointsOnCurve(targ);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);
+			this.mc._rotation = Math.round(this.computeRotation(targ, p) - 90);
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;
+			this.mc._rotation = this.computeRotation(targ, p) - 90;
+		}
+	}
+	
+	private function moveAndRotateOn(targ:Number):Void {		
+		var p:Object = this.getPointsOnCurve(targ);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);
+			this.mc._rotation = Math.round(this.computeRotation(targ, p));
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;
+			this.mc._rotation = this.computeRotation(targ, p);
+		}		
+	}
+	
+	private function computeRotation(targ:Number, p:Object):Number {
+		if (this.lastPoint.x == undefined) {
+			//just calculated the first point. Store it.
+			this.lastPoint = p;
+			//go 1% forward to get next point
+			p = this.getPointsOnCurve(targ + 1);
+		}
+		var degrees:Number = Math.atan2(this.lastPoint.y-p.y, this.lastPoint.x-p.x)/(Math.PI/180);
+		//update cache
+		this.lastPoint = p;	
+		return degrees;
+	}
+	
+	/*
+	* de.alex_uhlmann.animationpackage.drawing.CubicCurve needs to access this method.
+	* Adapted from Paul Bourke.
+	*/
+	public function getPointsOnCurve(targ:Number):Object {
+		var v:Number = targ / 100;
+		var k:Number, kn:Number, nn:Number, nkn:Number, blend:Number, muk:Number, munk:Number;
+		var n:Number = this.n;
+		var p:Array = this.points;
+		var b:Object = {x:0, y:0};
+		if(v != 1) {
+			//calculate for all control points 
+			//but the last point on the path
+			muk = 1;		
+			munk = Math.pow(1 - v, n);		
+			for (k = 0; k <= n; k++) {			
+				nn = n;
+				kn = k;
+				nkn = n - k;			
+				blend = muk * munk;			
+				muk *= v;
+				munk /= (1 - v);			
+				while (nn >= 1) {
+					blend *= nn;				
+					nn--;
+					if (kn > 1) {
+						blend /= kn;
+						kn--;
+					}
+					if (nkn > 1) {
+						blend /= nkn;
+						nkn--;
+					}
+				}
+				b.x += p[k].x * blend;
+				b.y += p[k].y * blend;		
+			}
+			return b;
+		} else {
+		//Calculate the last point 
+		//- it is NOT a control point
+			var l:Number = p.length - 1;
+			b.x = p[l].x;
+			b.y = p[l].y;
+			return b;
+		}
+	}
+
+	/**
+	* @method run
+	* @description
+	* @usage   
+	* 		<pre>myInstance.run();</pre>
+	* 		<pre>myInstance.run(points);</pre>
+	* 		<pre>myInstance.run(points, duration);</pre>
+	*		<pre>myInstance.run(points, duration, callback);</pre>
+	* 		<pre>myInstance.run(points, duration, easing, callback);</pre>
+	* 	  
+	* @param points (Array) Array of objects with x and y properties that define the curve.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	public function run():Void {							
+		
+		this.initAnimation.apply(this, arguments);
+		this.invokeAnimation(0, 100);
+	}
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myMOC.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method orientToPath
+	* @description 	offers the opportunity to rotate the object towards the curve while animating.
+	* 				Default is false. If true the object orientates towards the curve.
+	*                  		If false the object's rotation will not be altered. See class documentation.
+	* @usage   <pre>myInstance.orientToPath(rotateTo);</pre> 	  
+	* @param rotateTo (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/
+	public function orientToPath(bool:Boolean):Void {
+		if(bool) {
+			this.rotateOn = false;
+		}
+		this.rotateTo = bool;
+	}
+	
+	/**
+	* @method orientOnPath
+	* @description 	offers the opportunity to rotate the object on the curve while animating.
+	* 				Default is false. If true the object orientates on the curve.
+	*                  		If false the object's rotation will not be altered. See class documentation.
+	* @usage   <pre>myInstance.orientToPath(rotateOn);</pre> 	  
+	* @param rotateOn (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/	
+	public function orientOnPath(bool:Boolean):Void {
+		if(bool) {
+			this.rotateTo = false;
+		}
+		this.rotateOn = bool;
+	}
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(event, listener);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy.
+	*                  				<code>false</code> animates with floating point numbers.
+	*/
+	public function checkIfRounded(Void):Boolean {
+		return this.overriddenRounded;
+	}
+	
+	public function roundResult(overriddenRounded:Boolean):Void {
+		this.overriddenRounded = overriddenRounded;
+	}
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myMOC.addEventListener(event, listener);</pre>
+	* 		    <pre>myMOC.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myMOC.removeEventListener(event, listener);</pre>
+	* 		    <pre>myMOC.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myMOC.removeAllEventListeners();</pre>
+	* 		    <pre>myMOC.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myMOC.eventListenerExists(event, listener);</pre>
+	* 			<pre>myMOC.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "MoveOnCurve";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnCurve.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnPath.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnPath.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnPath.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,585 @@
+import de.alex_uhlmann.animationpackage.animation.IAnimatable;
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.IVisitor;
+import de.alex_uhlmann.animationpackage.utility.IVisitorElement;
+import de.alex_uhlmann.animationpackage.utility.IComposite;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import org.dembicki.Path;
+
+/**
+* @class MoveOnPath
+* @author Alex Uhlmann
+* @description   Moves a movieclip on along a path using Ivan Dembicki's com.sharedfonts.Path. This allows to 
+* 			animate an object very evenly along a path. 
+* 			<p>
+* 			Example 1: <a href="MoveOnPath_01.html">(Example .swf)</a>
+* 			<blockquote><pre>
+*			//draw the path for visualisation.
+*			new QuadCurve(400,100,100,0,100,100,true).draw();
+*			new QuadCurve(100,100,100,200,450,380,true).draw();
+*			new QuadCurve(450,380,0,100,400,100,true).draw();
+*		
+*			var myMoveOnQuadCurve1:MoveOnQuadCurve = new MoveOnQuadCurve(mc,400,100,100,0,100,100);
+*			var myMoveOnQuadCurve2:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,100,200,450,380);
+*			var myMoveOnQuadCurve3:MoveOnQuadCurve = new MoveOnQuadCurve(mc,450,380,0,100,400,100);
+*			
+*			var myMOP:MoveOnPath = new MoveOnPath(mc);
+*			myMOP.addChild(myMoveOnQuadCurve1);
+*			myMOP.addChild(myMoveOnQuadCurve2);
+*			myMOP.addChild(myMoveOnQuadCurve3);
+*			myMOP.animationStyle(4000,Linear.easeNone);
+*			myMOP.animate(0,100);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 2: <a href="MoveOnPath_02.html">(Example .swf)</a> Orient the object towards the path while 
+* 			animating with Sine easing.
+* 			<blockquote><pre>
+* 			//draw the path for visualisation.
+* 			new QuadCurve(400,100,100,0,100,100,true).draw();
+* 			new QuadCurve(100,100,100,200,450,380,true).draw();
+* 			new QuadCurve(450,380,0,100,400,100,true).draw();
+* 		
+* 			var myMoveOnQuadCurve1:MoveOnQuadCurve = new MoveOnQuadCurve(mc,400,100,100,0,100,100);
+*			var myMoveOnQuadCurve2:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,100,200,450,380);
+* 			var myMoveOnQuadCurve3:MoveOnQuadCurve = new MoveOnQuadCurve(mc,450,380,0,100,400,100);
+* 			
+* 			var myMOP:MoveOnPath = new MoveOnPath(mc);
+* 			myMOP.addChild(myMoveOnQuadCurve1);
+* 			myMOP.addChild(myMoveOnQuadCurve2);
+* 			myMOP.addChild(myMoveOnQuadCurve3);
+* 			myMOP.orientToPath(true);
+* 			myMOP.animationStyle(8000,Sine.easeInOut);
+* 			myMOP.animate(0,100);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 3: <a href="MoveOnPath_03.html">(Example .swf)</a> Same like above except 
+* 			that the object will orientate itself on the path instead towards the path. 
+* 			This is like the rotation on a path works in the Flash IDE.
+* 			<blockquote><pre>
+* 			//draw the path for visualisation.
+* 			new QuadCurve(400,100,100,0,100,100,true).draw();
+* 			new QuadCurve(100,100,100,200,450,380,true).draw();
+* 			new QuadCurve(450,380,0,100,400,100,true).draw();
+* 		
+* 			var myMoveOnQuadCurve1:MoveOnQuadCurve = new MoveOnQuadCurve(mc,400,100,100,0,100,100);
+*			var myMoveOnQuadCurve2:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,100,200,450,380);
+* 			var myMoveOnQuadCurve3:MoveOnQuadCurve = new MoveOnQuadCurve(mc,450,380,0,100,400,100);
+* 			
+* 			var myMOP:MoveOnPath = new MoveOnPath(mc);
+* 			myMOP.addChild(myMoveOnQuadCurve1);
+* 			myMOP.addChild(myMoveOnQuadCurve2);
+* 			myMOP.addChild(myMoveOnQuadCurve3);
+* 			myMOP.orientOnPath(true);
+* 			myMOP.animationStyle(8000,Sine.easeInOut);
+* 			myMOP.animate(0,100);
+*			</pre></blockquote>
+* @usage <pre>var myMOP:MoveOnPath = new MoveOnPath(mc);</pre> 
+*		<pre>var myMOP:MoveOnPath = new MoveOnPath(mc, duration);</pre>
+* 		<pre>var myMOP:MoveOnPath = new MoveOnPath(mc, duration, callback);</pre>
+* 		<pre>var myMOP:MoveOnPath = new MoveOnPath(mc, duration, easing, callback);</pre>
+* @param mc (MovieClip) Movieclip to animate.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See APCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.MoveOnPath 
+										extends AnimationCore 
+										implements ISingleAnimatable, 
+												IVisitorElement, 
+												IComposite {	
+	
+	private var start:Number;
+	private var end:Number;
+	private var childsArr:Array;
+	private var myPath:Path;
+	private var pathArr:Array;
+	private var rotateTo:Boolean = false;
+	private var rotateOn:Boolean = false;
+	private var overriddenRounded:Boolean = false;
+	
+	public function MoveOnPath() {				
+		super();
+		this.mc = arguments[0];
+		this.childsArr = new Array();
+		if(arguments.length > 1) {			
+			this.initAnimation.apply(this, arguments.slice(1));
+		}
+	}
+	
+	private function initAnimation(duration:Number, easing:Object, callback:String):Void {		
+		
+		var paramLen:Number = 0;
+		if (arguments.length > paramLen) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+	}
+
+	private function invokeAnimation(start:Number, end:Number):Void {
+		this.startInitialized = false;
+		
+		this.pathArr = new Array();
+		
+		var i:Number, len:Number = this.childsArr.length;
+		var child:Object = this.childsArr[0];			
+		child.useControlPoints(true);
+		this.pathArr.push(child.x1);
+		this.pathArr.push(child.y1);		
+		for(i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];			
+			child.useControlPoints(true);		
+			this.pathArr.push(child.x2);
+			this.pathArr.push(child.y2);
+			this.pathArr.push(child.x3);
+			this.pathArr.push(child.y3);
+		}
+		this.myPath = new Path(this.pathArr);
+		this.setStartValue(0);
+		this.setEndValue(this.myPath.path_length-1);
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [0];
+		this.myAnimator.end = [this.myPath.path_length-1];
+		if(this.rotateTo == true) {
+			this.myAnimator.setter = [[this,"moveAndRotateTo"]];
+		} else if(this.rotateOn == true) {
+			this.myAnimator.setter = [[this,"moveAndRotateOn"]];
+		} else {
+			this.myAnimator.setter = [[this,"move"]];
+		}
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	private function move(targ:Number):Void {		
+		var p:Object = this.myPath.getPoint(targ, true);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p._x);
+			this.mc._y = Math.round(p._y);			
+		}
+		else {
+			this.mc._x = p._x;
+			this.mc._y = p._y;			
+		}
+	}
+	
+	private function moveAndRotateTo(targ:Number):Void {
+		var p:Object = this.myPath.getPoint(targ, false);		
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p._x);
+			this.mc._y = Math.round(p._y);
+			this.mc._rotation = Math.round(p._rotation-90);
+		}
+		else {
+			this.mc._x = p._x;
+			this.mc._y = p._y;
+			this.mc._rotation = p._rotation-90;
+		}
+	}
+	
+	private function moveAndRotateOn(targ:Number):Void {
+		var p:Object = this.myPath.getPoint(targ, false);		
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p._x);
+			this.mc._y = Math.round(p._y);
+			this.mc._rotation = Math.round(p._rotation);
+		}
+		else {
+			this.mc._x = p._x;
+			this.mc._y = p._y;
+			this.mc._rotation = p._rotation;
+		}
+	}
+	
+	/**
+	* @method animate
+	* @description 	animates the contents of the composite.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/	
+	
+	/**
+	* @method orientToPath
+	* @description 	offers the opportunity to rotate the object towards the curve while animating.
+	* 				Default is false. If true the object orientates towards the curve.
+	*                  		If false the object's rotation will not be altered. See class documentation.
+	* @usage   <pre>myInstance.orientToPath(rotateTo);</pre> 	  
+	* @param rotateTo (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/	
+	public function orientToPath(bool:Boolean):Void {
+		if(bool) {
+			this.rotateOn = false;
+		}
+		this.rotateTo = bool;
+	}
+	
+	/**
+	* @method orientOnPath
+	* @description 	offers the opportunity to rotate the object on the curve while animating.
+	* 				Default is false. If true the object orientates on the curve.
+	*                  		If false the object's rotation will not be altered. See class documentation.
+	* @usage   <pre>myInstance.orientToPath(rotateOn);</pre> 	  
+	* @param rotateOn (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/	
+	public function orientOnPath(bool:Boolean):Void {
+		if(bool) {
+			this.rotateTo = false;
+		}
+		this.rotateOn = bool;
+	}	
+	
+	/**
+	* @method addChild
+	* @description 	adds a primitive or composite to the composite instance of Parallel 
+	* See class description.
+	* @usage  <pre>myInstance.addChild(component);</pre>
+	* @param component (IAnimatable) Must be compatible to IAnimatable.
+	* @return IAnimatable class that was added.
+	*/
+	public function addChild(component:IAnimatable):IAnimatable {		
+		if(component instanceof Object) {
+			this.childsArr.push(component);
+			return component;
+		}
+	}	
+	
+	/**
+	* @method removeChild
+	* @description 	removes a primitive or composite from the composite instance of Parallel 
+	* See class description.
+	* @usage  <pre>myInstance.removeChild(component);</pre>
+	* @param component (IAnimatable) Must be compatible to IAnimatable.	
+	*/	
+	public function removeChild(component:IAnimatable):Void {		
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			if(this.childsArr[i] == component) {
+				this.childsArr.splice(i, 1);
+			}
+		}
+	}
+	
+	/**
+	* @method accept
+	* @description 	Allow a visitor to visit its elements. See Visitor design pattern [GoF].
+	* @usage  <pre>myInstance.accept(visitor);</pre>
+	* @param visitor (IVisitor) Must be compatible to de.alex_uhlmann.animationpackage.utility.IVisitor.	
+	*/
+	public function accept(visitor:IVisitor):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			visitor.visit(this.childsArr[i]);			
+		}
+	}
+	
+	/**
+	* @method getChildren
+	* @description 	returns an Array of all children of the sequence. 
+	* 				Could contain other Sequences.
+	* @usage   <tt>myInstance.getChildren();</tt>
+	* @return Array
+	*/	
+	public function getChildren(Void):Array {
+		return this.childsArr;
+	}	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	* @param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	public function checkIfRounded(Void):Boolean {
+		return this.overriddenRounded;
+	}
+	
+	public function roundResult(overriddenRounded:Boolean):Void {
+		this.overriddenRounded = overriddenRounded;
+	}
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	* @param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myMOC.addEventListener(event, listener);</pre>
+	* 		    <pre>myMOC.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myMOC.removeEventListener(event, listener);</pre>
+	* 		    <pre>myMOC.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myMOC.removeAllEventListeners();</pre>
+	* 		    <pre>myMOC.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myMOC.eventListenerExists(event, listener);</pre>
+	* 			<pre>myMOC.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "MoveOnPath";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnPath.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnQuadCurve.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnQuadCurve.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnQuadCurve.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,655 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.BezierToolkit;
+
+/**
+* @class MoveOnQuadCurve
+* @author Alex Uhlmann
+* @description Moves a movieclip along a specified quadratic bezier curve in a specified time and easing equation.
+* 			The curve is specified with three points. Start point, mid point or control point, end point.
+* 			Note: The mid point is the point the curve passes through. With the useControlPoints 
+* 			method you can specify the control point instead of the mid point. 
+* 			The MovieClip.curveTo method uses control points i.e.
+* 			<p>
+* 			Example 1: <a href="MoveOnQuadCurve_run_01.html">(Example .swf)</a> Declare 6 variables to store the three points that define the curve 
+* 			for easy access. To visualize the points and the curve draw it with 
+* 			the classes of the de.alex_uhlmann.animationpackage.drawing package. Then, 
+*  			move the movieclip along the specified curve in 4 seconds using Bounce easing.		
+* 			<pre><blockquote>
+*			var x1:Number = 100;
+*			var y1:Number = 100;
+*			var x2:Number = 400;
+*			var y2:Number = 200;
+*			var x3:Number = 500;
+*			var y3:Number = 400;
+*			
+*			var myQuadCurve:QuadCurve = new QuadCurve(x1,y1,x2,y2,x3,y3);
+*			myQuadCurve.lineStyle(6,0x8CA6BD);
+*			myQuadCurve.draw();
+*			
+*			Shape.lineRGB_def = 0x9C3031;
+*			Shape.fillRGB_def = 0x9C3031;
+*			
+*			new Ellipse(x1,y1,5,5).draw();						
+*			new Ellipse(x2,y2,5,5).draw();
+*			new Ellipse(x3,y3,5,5).draw();			
+*			
+*			var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc);
+*			myMOC.animationStyle(4000,Bounce.easeOut);
+*			myMOC.run(x1,y1,x2,y2,x3,y3);
+*			</pre></blockquote>
+* 			Example 2: Move a movieclip along the curve in 4 seconds using circular easing. 		
+* 			<blockquote><pre>
+*			new MoveOnQuadCurve(mc).run(100,100,300,300,500,100,4000,Circ.easeInOut);			
+* 			</pre></blockquote>
+* 			<p>		
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 3:
+* 			<blockquote><pre>			
+*			var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc);
+*			myMOC.animationStyle(4000,Circ.easeInOut);
+*			myMOC.run(100,100,300,300,500,100);
+*			</pre></blockquote>  			
+* 			Example 4: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new MoveOnQuadCurve(mc).run(100,100,300,300,500,100,4000,Circ.easeInOut);
+* 			</pre></blockquote>		
+*  			Example 5: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end parameters might also be useful. 
+* 			<blockquote><pre>
+* 			var myMoveOnQuadCurve:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,300,300,500,100,4000,Circ.easeInOut);
+* 			myMoveOnQuadCurve.animate(0,100);
+* 			</pre></blockquote>
+* @usage <pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc);</pre> 
+* 		<pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc, x1, y1, x2, y2, x3, y3);</pre>
+*		<pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc, x1, y1, x2, y2, x3, y3, duration);</pre>
+* 		<pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc, x1, y1, x2, y2, x3, y3, duration, callback);</pre>
+* 		<pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc, x1, y1, x2, y2, x3, y3, duration, easing, callback);</pre>
+* 		<pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc, x1, y1, x2, y2, x3, y3, withControlpoints);</pre>
+*		<pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc, x1, y1, x2, y2, x3, y3, withControlpoints, duration);</pre>
+* 		<pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc, x1, y1, x2, y2, x3, y3, withControlpoints, duration, callback);</pre>
+* 		<pre>var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc, x1, y1, x2, y2, x3, y3, withControlpoints, duration, easing, callback);</pre>
+* @param mc (MovieClip) Movieclip to animate.
+* @param x1 (Number) start point to define curve. Coordinate point x
+* @param y1 (Number) start point to define curve. Coordinate point y
+* @param x2 (Number) mid point or control point to define curve. Coordinate point x
+* @param y2 (Number) mid point or control point to define curve. Coordinate point y
+* @param x3 (Number) end point to define curve. Coordinate point x
+* @param y3 (Number) end point to define curve. Coordinate point y
+* @param withControlpoints (Boolean) specify control points between the start and end points of the curve instead of points on the curve. Default is false.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See APCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.MoveOnQuadCurve 
+											extends AnimationCore 
+											implements ISingleAnimatable {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/	
+	private var mc:MovieClip;
+	private var x1:Number;
+	private var y1:Number;
+	private var x2:Number;
+	private var y2:Number;
+	private var x3:Number;
+	private var y3:Number;
+	private var myBezierToolkit:BezierToolkit;
+	private var p1:Object;
+	private var p2:Object;
+	private var p3:Object;
+	private var withControlpoints:Boolean = false;
+	private var x2ControlPoint:Number;
+	private var y2ControlPoint:Number;
+	private var rotateTo:Boolean = false;
+	private var rotateOn:Boolean = false;
+	private var overriddenRounded:Boolean = false;
+	
+	/*
+	* cache for last point calculated by getPointsOnCurve. 
+	* Used to calculate slope/rotation
+	*/
+	private var lastPoint:Object;
+	
+	public function MoveOnQuadCurve() {				
+		super();
+		this.mc = arguments[0];
+		if(arguments.length > 1) {			
+			this.initAnimation.apply(this, arguments.slice(1));
+		}
+	}
+	
+	private function initAnimation(x1:Number, y1:Number, x2:Number, 
+							y2:Number, x3:Number, y3:Number, withControlpoints:Object, 
+							duration:Object, easing:Object, callback:String):Void {		
+		
+		var paramLen:Number = 6;
+		var temp;
+		if(typeof(withControlpoints) == "number") {
+			temp = withControlpoints;
+			var temp_ms:Number = temp;                  
+			var temp_easing = duration;
+			temp = easing;
+			easing = temp_easing;
+			callback = temp;			
+			this.animationStyle(temp_ms, easing, callback);
+		} else if (arguments.length > paramLen) {
+			temp = duration;
+			this.animationStyle(temp, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		this.myBezierToolkit = new BezierToolkit();
+		if(typeof(withControlpoints) == "boolean") {
+			temp = withControlpoints;
+			this.withControlpoints = temp;
+		}
+		if(this.withControlpoints == false) {
+			this.x2ControlPoint = x2;
+			this.y2ControlPoint = y2;
+			var controlPoint:Object = this.myBezierToolkit.getQuadControlPoints(x1, y1, x2, y2, x3, y3);
+			x2 = controlPoint.x;
+			y2 = controlPoint.y;
+		}
+		this.init(x1, y1, x2, y2, x3, y3);
+		this.setStartValue(0);
+		this.setEndValue(100);
+	}
+	
+	private function init():Void {
+				
+		this.x1 = arguments[0];
+		this.y1 = arguments[1];
+		this.x2 = arguments[2];
+		this.y2 = arguments[3];
+		this.x3 = arguments[4];
+		this.y3 = arguments[5];
+		this.p1 = {x:this.x1, y:this.y1};
+		this.p2 = {x:this.x2, y:this.y2};
+		this.p3 = {x:this.x3, y:this.y3};
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		this.startInitialized = false;
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [0];
+		this.myAnimator.end = [100];
+		if(this.rotateTo == true) {
+			this.myAnimator.setter = [[this,"moveAndRotateTo"]];
+		} else if(this.rotateOn == true) {
+			this.myAnimator.setter = [[this,"moveAndRotateOn"]];
+		} else {
+			this.myAnimator.setter = [[this,"move"]];				
+		}
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	private function move(targ:Number):Void {		
+		var p:Object = this.myBezierToolkit.getPointsOnQuadCurve(targ, this.p1, this.p2, this.p3);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);			
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;			
+		}
+	}
+
+	private function moveAndRotateTo(targ:Number):Void {
+		var p:Object = this.myBezierToolkit.getPointsOnQuadCurve(targ, 
+												this.p1, 
+												this.p2, 
+												this.p3);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);
+			this.mc._rotation = Math.round(this.computeRotation(targ, p) - 90);
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;
+			this.mc._rotation = this.computeRotation(targ, p) - 90;
+		}
+	}
+	
+	private function moveAndRotateOn(targ:Number):Void {
+		var p:Object = this.myBezierToolkit.getPointsOnQuadCurve(targ, 
+												this.p1, 
+												this.p2, 
+												this.p3);
+		if(overriddenRounded) {
+			this.mc._x = Math.round(p.x);
+			this.mc._y = Math.round(p.y);
+			this.mc._rotation = Math.round(this.computeRotation(targ, p));
+		}
+		else {
+			this.mc._x = p.x;
+			this.mc._y = p.y;
+			this.mc._rotation = this.computeRotation(targ, p);
+		}
+	}
+	
+	private function computeRotation(targ:Number, p:Object):Number {
+		if (this.lastPoint.x == undefined) {
+			//just calculated the first point. Store it.
+			this.lastPoint = p;
+			//go 1% forward to get next point
+			p = this.myBezierToolkit.getPointsOnQuadCurve(
+									targ + 1, 
+									this.p1, 
+									this.p2, 
+									this.p3);
+		}
+		var degrees:Number = Math.atan2(this.lastPoint.y-p.y, this.lastPoint.x-p.x)/(Math.PI/180);
+		//update cache
+		this.lastPoint = p;	
+		return degrees;
+	}
+	
+	/**
+	* @method run
+	* @description
+	* @usage  
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3);</pre>
+	*		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, duration);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, duration, callback);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, duration, easing, callback);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, withControlpoints);</pre>
+	*		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, withControlpoints, duration);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, withControlpoints, duration, callback);</pre>
+	* 		<pre>myMOC.run(x1, y1, x2, y2, x3, y3, withControlpoints, duration, easing, callback);</pre>
+	* 	  
+	* @param x1 (Number) start point to define curve. Coordinate point x
+	* @param y1 (Number) start point to define curve. Coordinate point y
+	* @param x2 (Number) mid point or control point to define curve. Coordinate point x
+	* @param y2 (Number) mid point or control point to define curve. Coordinate point y
+	* @param x3 (Number) end point to define curve. Coordinate point x
+	* @param y3 (Number) end point to define curve. Coordinate point y
+	* @param withControlpoints (Boolean) specify control points between the start and end points of the curve instead of points on the curve. Default is false.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	public function run():Void {
+		this.initAnimation.apply(this, arguments);
+		this.invokeAnimation(0, 100);
+	}
+
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myMOC.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/	
+	
+	/**
+	* @method useControlPoints
+	* @description 	offers the opportunity to specify control points between the start and end points 
+	* 				of the curve instead of points on the curve. Default is false.
+	* 				If true points between start and end points are control points.
+	*                  		If false points between start and end points are points on the curve.
+	* @usage   <pre>myInstance.useControlPoints(withControlpoints);</pre> 	  
+	* @param withControlpoints (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/
+	public function useControlPoints(withControlpoints:Boolean):Void {
+		if(withControlpoints) {
+			this.x2 = this.x2ControlPoint;
+			this.y2 = this.y2ControlPoint;
+			this.p2 = {x:this.x2, y:this.y2};
+		}
+		this.withControlpoints = withControlpoints;		
+	}
+
+	/**
+	* @method orientToPath
+	* @description 	offers the opportunity to rotate the object towards the curve while animating.
+	* 				Default is false. If true the object orientates on the curve.
+	*                  		If false the object's rotation will not be altered.
+	* 			Example 1: <a href="MoveOnQuadCurve_orientToPath_01.html">(Example .swf)</a>
+	* 			<pre><blockquote>
+	*			var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc);
+	*			myMOC.animationStyle(2000,Sine.easeInOut);
+	*			myMOC.orientToPath(true);
+	*			myMOC.run(100,100,300,300,500,100);
+	*			</pre></blockquote>
+	* @usage   <pre>myInstance.orientToPath(pathOrientation);</pre> 	  
+	* @param pathOrientation (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/
+	public function orientToPath(bool:Boolean):Void {
+		if(bool) {
+			this.rotateOn = false;
+		}
+		this.rotateTo = bool;
+	}
+	
+	/**
+	* @method orientOnPath
+	* @description 	offers the opportunity to rotate the object on the curve while animating.
+	* 				Default is false. If true the object orientates on the curve.
+	*                  		If false the object's rotation will not be altered. See class documentation.
+	* @usage   <pre>myInstance.orientToPath(rotateOn);</pre> 	  
+	* @param rotateOn (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/	
+	public function orientOnPath(bool:Boolean):Void {
+		if(bool) {
+			this.rotateTo = false;
+		}
+		this.rotateOn = bool;
+	}	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(event, listener);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy.
+	*                  				<code>false</code> animates with floating point numbers.
+	*/
+	public function checkIfRounded(Void):Boolean {
+		return this.overriddenRounded;
+	}
+	
+	public function roundResult(overriddenRounded:Boolean):Void {
+		this.overriddenRounded = overriddenRounded;
+	}
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myMOC.addEventListener(event, listener);</pre>
+	* 		    <pre>myMOC.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myMOC.removeEventListener(event, listener);</pre>
+	* 		    <pre>myMOC.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myMOC.removeAllEventListeners();</pre>
+	* 		    <pre>myMOC.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myMOC.eventListenerExists(event, listener);</pre>
+	* 			<pre>myMOC.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "MoveOnQuadCurve";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/MoveOnQuadCurve.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Parallel.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Parallel.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Parallel.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,563 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.IAnimatable;
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.IVisitor;
+import de.alex_uhlmann.animationpackage.utility.IVisitorElement;
+import de.alex_uhlmann.animationpackage.utility.IComposite;
+
+/**
+* @class Parallel
+* @author Alex Uhlmann
+* @description  Parallel allows you to animate the classes of 
+* 			de.alex_uhlmann.animationpackage.animation synchronously in a uniform manner.
+* 			Parallel uses the composite design pattern. [GoF]
+* 			<p>
+* 			Example 1: <a href="Parallel_01.html">(Example .swf)</a> Animate different animations at the same time back and forth.
+* 			<pre><blockquote> 
+* 			var myMoveOnQuadCurve:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,300,300,500,100);
+*			var myScale:Scale = new Scale(mc,50,50);
+*			var myRotation:Rotation = new Rotation(mc,360);
+*			var myColorTransform:ColorTransform = new ColorTransform(mc,0xff0000,50);
+* 
+*			var myParallel:Parallel = new Parallel();
+*			myParallel.addChild(myMoveOnQuadCurve);
+*			myParallel.addChild(myScale);
+*			myParallel.addChild(myRotation);
+*			myParallel.addChild(myColorTransform);
+*			myParallel.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			myParallel.animate(0,100);
+*			myListener.onCallback = function(source) {	
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</pre></blockquote>
+* 			<p>			
+* @usage <tt>var myParallel:Parallel = new Parallel();</tt> 
+*/
+class de.alex_uhlmann.animationpackage.animation.Parallel 
+											extends AnimationCore 
+											implements ISingleAnimatable, 
+													IVisitorElement, 
+													IComposite {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+
+	private var childsArr:Array;
+	private var oneChild:Object;
+	
+	public function Parallel() {		
+		super();
+		this.childsArr = new Array();
+	}
+	
+	private function invokeAnimation(start:Number, end:Number) {
+		var goto:Boolean;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;
+		} else {
+			goto = false;
+			this.setStartValue(start);	
+			this.setEndValue(end);
+		}
+		var i:Number, len:Number = this.childsArr.length;
+		var child:Object;
+		for (i = 0; i < len; i++) {
+			child = this.childsArr[i];
+			if(goto == false) {
+				child.animate(start, end);
+			} else {
+				child.goto(end);
+			}
+			if(child.duration == this.duration) {
+				this.oneChild = child;
+			}
+		}
+		this.oneChild.addEventListener("onUpdate",this);
+		this.oneChild.addEventListener("onEnd", this);
+		this.myAnimator = this.oneChild.myAnimator;
+		this.tweening = true;	
+		this.dispatchEvent.apply(this, [ {type:"onStart", value:this.getStartValue()} ]);
+	}	
+	
+	/**
+	* @method animate
+	* @description 	animates the contents of the composite.
+	* @usage   <pre>myParallel.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/	
+	public function animate(start:Number, end:Number):Void {
+		this.invokeAnimation(start, end);
+	}
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 
+	* @usage   <pre>myParallel.animationStyle(duration);</pre>
+	* 		<pre>myParallel.animationStyle(duration, callback);</pre>
+	* 		<pre>myParallel.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation(s) in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation(s). See APCore class.
+	*/
+	public function animationStyle(duration:Number, easing:Object, callback:String):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {					
+			this.childsArr[i].animationStyle(duration, easing);			
+		}
+		this.duration = duration;
+		this.callback = callback;
+	}	
+	
+	public function onStart(eventObject:Object):Void {		
+		this.dispatchEvent({type:eventObject.type, value:this.getStartValue()});
+	}
+	
+	public function onUpdate(eventObject:Object):Void {		
+		this.dispatchEvent({type:eventObject.type, value:this.getCurrentValue()});
+	}
+	
+	public function onEnd(eventObj:Object):Void {			
+		
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {	
+			var child:Object = this.childsArr[i];
+			if(child.isTweening()) {
+				child.addEventListener("onEnd",this);
+				return;
+			}	
+		}
+		this.tweening = false;
+		eventObj.target.removeEventListener("onEnd", this);
+		APCore.broadcastMessage(this.callback, this);		
+		this.dispatchEvent.apply(this, [ {type:"onEnd", value:this.getEndValue()} ]);
+	}
+	
+	/**
+	* @method addChild
+	* @description 	adds a primitive or composite to the composite instance of Parallel 
+	* See class description.
+	* @usage  <pre>myParallel.addChild(component);</pre>
+	* @param component (IAnimatable) Must be compatible to IAnimatable.
+	* @return IAnimatable class that was added.
+	*/	
+	public function addChild(component:IAnimatable):IAnimatable {		
+		if(component instanceof Object) {
+			this.childsArr.push(component);
+			return component;
+		}
+	}
+
+	/**
+	* @method removeChild
+	* @description 	removes a primitive or composite from the composite instance of Parallel 
+	* See class description.
+	* @usage  <pre>myParallel.removeChild(component);</pre>
+	* @param component (IAnimatable) Must be compatiblee to IAnimatable.	
+	*/
+	public function removeChild(component:IAnimatable):Void {		
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			if(this.childsArr[i] == component) {
+				this.childsArr.splice(i, 1);
+			}
+		}
+	}
+	
+	/**
+	* @method accept
+	* @description 	Allow a visitor to visit its elements. See Visitor design pattern [GoF].
+	* @usage  <pre>myInstance.accept(visitor);</pre>
+	* @param visitor (IVisitor) Must be compatible to de.alex_uhlmann.animationpackage.utility.IVisitor.	
+	*/
+	public function accept(visitor:IVisitor):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			visitor.visit(this.childsArr[i]);			
+		}
+	}
+	
+	/**
+	* @method getChildren
+	* @description 	returns an Array of all children of the sequence. 
+	* 				Could contain other Sequences.
+	* @usage   <tt>myInstance.getChildren();</tt>
+	* @return Array
+	*/	
+	public function getChildren(Void):Array {
+		return this.childsArr;
+	}	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	public function roundResult(rounded:Boolean):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].roundResult(rounded);		
+		}
+	}	
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	public function forceEnd(forceEndVal:Boolean):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].forceEnd(forceEndVal);		
+		}
+	}
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	public function setOptimizationMode(optimize:Boolean):Void {
+		this.equivalentsRemoved = optimize;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].setOptimizationMode(optimize);		
+		}
+	}	
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode(tweenMode);</tt> 	
+	* @param tweenMode (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	public function setTweenMode(tweenMode:String):Boolean {
+		this.tweenMode = tweenMode;
+		var isSet:Boolean;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			isSet = this.childsArr[i].setTweenMode(tweenMode);		
+		}
+		return isSet;
+	}
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode(durationMode);</tt> 	
+	* @param durationMode (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/	
+	public function setDurationMode(durationMode:String):Boolean {
+		this.durationMode = durationMode;
+		var isSet:Boolean;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			isSet = this.childsArr[i].setDurationMode(durationMode);		
+		}
+		return isSet;
+	}
+
+	/*inherited from AnimationCore*/
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/
+	public function stop(Void):Boolean {
+		if(super.stop() == true) {			
+			var i:Number, len:Number = this.childsArr.length;
+			for (i = 0; i < len; i++) {				
+				this.childsArr[i].stop();
+			}
+			return true;
+		} else {
+			return false;
+		}
+	}	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/
+	public function pause(duration:Number):Boolean {		
+		if(super.pause(duration) == true) {
+			var i:Number, len:Number = this.childsArr.length;
+			for (i = 0; i < len; i++) {				
+				this.childsArr[i].pause();
+			}
+			return true;
+		} else {
+			return false;
+		}
+	}	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	public function resume(Void):Boolean {		
+		if(super.resume() == true) {
+			var i:Number, len:Number = this.childsArr.length;
+			for (i = 0; i < len; i++) {				
+				this.childsArr[i].resume();
+			}			
+			return true;
+		} else {
+			return false;
+		}
+	}	
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	public function getStartValue(Void):Number {		
+		var startValue:Number = super.getStartValue();
+		if(startValue == null) {
+			startValue = 0;
+		}
+		return startValue;
+	}	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	public function getEndValue(Void):Number {		
+		var endValue:Number = super.getEndValue();
+		if(endValue == null) {
+			endValue = 100;
+		}
+		return endValue;
+	}	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	public function getCurrentValue(Void):Number {
+		return (this.currentValue = this.oneChild.getCurrentPercentage());
+	}	
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/
+	public function getCurrentPercentage(Void):Number {
+		return this.oneChild.getCurrentPercentage();
+	}	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myParallel.addEventListener(event, listener);</pre>
+	* 		    <pre>myParallel.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myParallel.removeEventListener(event, listener);</pre>
+	* 		    <pre>myParallel.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myParallel.removeAllEventListeners();</pre>
+	* 		    <pre>myParallel.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myParallel.eventListenerExists(event, listener);</pre>
+	* 			<pre>myParallel.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Parallel";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Parallel.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Rotation.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Rotation.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Rotation.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,582 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Rotation
+* @author Alex Uhlmann
+* @description  Manipulates _rotation property of a movieclip or a number of movieclips.
+* 			<p>	
+* 			There are many ways to use this class. One way is to specify 
+* 			the duration, easing equation and callback properties outside 
+* 			the current method, either with setting the properies directly 
+* 			or with the animationStyle() method like it is used in 
+* 			de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>			
+*			var myRotation:Rotation = new Rotation(mc);
+*			myRotation.animationStyle(2000,Quad.easeIn,"onCallback");
+*			myRotation.run(360);
+*			</pre></blockquote>  			
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new Rotation(mc).run(360,2000,Quad.easeIn,"onCallback");
+* 			</pre></blockquote>
+* 			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 			
+* 			<blockquote><pre>
+* 			var myRotation:Rotation = new Rotation(mc,45,1000,Elastic.easeInOut);
+* 			myRotation.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValue or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+* 			<blockquote><pre>
+*			var myRotation:Rotation = new Rotation(mc,[90,270],2000,Quad.easeIn);
+*			myRotation.run();
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 5: rotate a movieclip 180 degrees clockwise in 1 second using linear easing. 		
+* 			<blockquote><pre>
+*			new Rotation(mc).run(180,1000);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 6: <a href="Rotation_run_02.html">(Example .swf)</a> rotate a movieclip 360 degrees clockwise and back using Quad easing.
+* 			<blockquote><pre>
+*			new Rotation(mc).run(360,2000,Quad.easeIn,"onCallback");
+*			myListener.onCallback = function() {
+*				new Rotation(mc).run(-360,2000,Quad.easeOut);	
+*			}
+*			</pre></blockquote>
+* 			Example 7: To animate many movieclips the same way, this class also accepts 
+* 			an Array of movieclips instead of one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want to animate. Different 
+* 			start values of your movieclip properties are considered when animating multiple movieclips 
+* 			within one animation instance.
+* 			<blockquote><pre>
+* 			var mcs:Array = new Array(mc1,mc2,mc3);
+* 			mc2._rotation = 240;
+*			var myRotation:Rotation = new Rotation(mc);
+*			myRotation.animationStyle(2000,Quad.easeIn,"onCallback");
+*			myRotation.run(360);
+* 			</pre></blockquote>
+* @usage      
+* 			<pre>var myRotation:Rotation = new Rotation(mc);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mc, degree, duration, callback);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mc, degree, duration, easing, callback);</pre>
+*			<pre>var myRotation:Rotation = new Rotation(mc, values);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mc, values, duration, callback);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mc, values, duration, easing, callback);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mcs);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mcs, degree, duration, callback);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mcs, degree, duration, easing, callback);</pre>
+*			<pre>var myRotation:Rotation = new Rotation(mcs, values);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mcs, values, duration, callback);</pre> 
+* 			<pre>var myRotation:Rotation = new Rotation(mcs, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param degree (Number) Targeted amount to animate to in degrees.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Rotation 
+											extends AnimationCore 
+											implements ISingleAnimatable,
+													IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public var xProperty:String = "_x";
+	public var yProperty:String = "_y";
+	public var rotationProperty:String = "_rotation";
+	private var modifiedRegistrationPoint:Boolean = false;
+	public var x:Number = 0;
+	public var y:Number = 0;	
+	private var myInstances:Array;
+	
+	public function Rotation() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function initAnimation(degree:Number, duration:Number, easing:Object, callback:String):Void {		
+		if (arguments.length > 1) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		if(this.mc != null) {
+			this.setStartValue(this.mc[this.rotationProperty], true);		
+		}
+		this.setEndValue(degree);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = [this.endValue];
+		if(this.mc != null) {
+			
+			this.myAnimator.start = [this.startValue];
+			if(!this.modifiedRegistrationPoint) {				
+				this.myAnimator.setter = [[this.mc,this.rotationProperty]];						
+			} else {
+				this.myAnimator.setter = [[this,"setXY"]];
+			}
+		
+		} else {
+
+			if(!this.modifiedRegistrationPoint) {
+				
+				this.myAnimator.multiStart = [this.rotationProperty];										
+				this.myAnimator.multiSetter = [[this.mcs,this.rotationProperty]];			
+			
+			} else {
+				
+				var myInstances:Array = [];			
+				var len:Number = this.mcs.length;
+				var mcs:Array = this.mcs;
+				var i:Number = len;
+				while(--i>-1) {
+					myInstances[i] = new Rotation(mcs[i]);
+					myInstances[i].setStartValue(this.getStartValue());					
+					myInstances[i].x = this.x;
+					myInstances[i].y = this.x;
+				}
+				this.myInstances = myInstances;
+				this.myAnimator.multiStart = ["getMultiStartXYValue"];	
+				this.myAnimator.multiSetter = [[this.myInstances,"setXY"]];
+			}
+		}
+
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	private function getMultiStartXYValue(Void):Number {
+		var startValue:Number = this.getStartValue();
+		if(startValue == null) {
+			return this.mc[this.rotationProperty];
+		} else {
+			return startValue;
+		}
+	}
+	
+	/*Adapted from solutions of Robert Penner, Darron Schall and Ben Jackson*/
+	public function setXY(value:Number):Void {
+		
+		var bounds:Object = this.mc.getBounds(this.mc);
+		var xorigin:Number = bounds.xMin + this.x;
+		var yorigin:Number = bounds.yMin + this.y;
+		
+		var a:Object = {x:xorigin, y:yorigin};
+		this.mc.localToGlobal(a);
+		this.mc._parent.globalToLocal(a);
+		
+		this.mc[this.rotationProperty] = value;
+
+		var b:Object = {x:xorigin, y:yorigin};
+		this.mc.localToGlobal(b);
+		this.mc._parent.globalToLocal(b);
+		this.mc[this.xProperty] -= b.x - a.x;
+		this.mc[this.yProperty] -= b.y - a.y;
+	}
+	
+	/**
+	* @method run
+	* @description 	Rotates a movieclip from its the current _rotation property value 
+	* 			to a specified amount in a specified time and easing equation.
+	* 		
+	* @usage   
+	* 		<pre>myRotation.run();</pre>
+	* 		<pre>myRotation.run(degree);</pre>
+	* 		<pre>myRotation.run(degree, duration);</pre>
+	*		<pre>myRotation.run(degree, duration, callback);</pre>
+	* 		<pre>myRotation.run(degree, duration, easing, callback);</pre>
+	* 		<pre>myRotation.run(values, duration);</pre>
+	* 		<pre>myRotation.run(values, duration, callback);</pre>
+	*		<pre>myRotation.run(values, duration, easing, callback);</pre>
+	* 	  
+	* @param degree (Number) Targeted degree to animate to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myRotation.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Movieclips rotate according to their registration point. If the registration 
+	* 				point is in the center of the shape, the movieclip will rotate around 
+	* 				its center. setRegistrationPoint in Rotation emulates modifying the 
+	* 				registration point of the animation. Top left is 0,0. 
+	* 				The parameter object accepts either x and y properties with coordinates as values 
+	* 				of the registration point or a position property with 
+	* 				String flags. Currently there are the following options 
+	* 				for the position property available:<p>
+	* 				CENTER = central registration point of movieclip.
+	* 			<p>
+	* 			Example 1: Assume that the movieclip mc has a registration point 
+	* 			of 0,0 (i.e. like Flash and Flex components). Rotate mc 
+	* 			around a central registration point.
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(5000,Sine.easeInOut);				
+	*			myRotation.setRegistrationPoint({position:"CENTER"});
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			<p>
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/	
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		this.modifiedRegistrationPoint = true;		
+		if(registrationObj.position == "CENTER") {
+			this.x = this.mc._width / 2;
+			this.y = this.mc._height / 2;
+		} else {
+			if(registrationObj.x != null ) {
+				this.x = registrationObj.x;
+			}
+			if(registrationObj.y != null ) {
+				this.y = registrationObj.y;
+			}
+		}
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myRotation.addEventListener(event, listener);</pre>
+	* 		    <pre>myRotation.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myRotation.removeEventListener(event, listener);</pre>
+	* 		    <pre>myRotation.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myRotation.removeAllEventListeners();</pre>
+	* 		    <pre>myRotation.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myRotation.eventListenerExists(event, listener);</pre>
+	* 			<pre>myRotation.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Rotation";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Rotation.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Scale.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Scale.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Scale.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,744 @@
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Scale
+* @author Alex Uhlmann, Ben Jackson
+* @description  Manipulates either the _xscale and _yscale or _width and _height properties 
+* 			of a movieclip or a number of movieclips.<p>	
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>			
+*			var myScale:Scale = new Scale(mc);
+*			myScale.animationStyle(2000,Sine.easeOut,"onCallback");
+*			myScale.run(1500,1500);
+*			</pre></blockquote>  			
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new Scale(mc).run(1500,1500,2000,Sine.easeOut,"onCallback");
+* 			</pre></blockquote>		
+*  			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 
+* 			<blockquote><pre>
+* 			var myScale:Scale = new Scale(mc,500,500,2000,Circ.easeOut,"onCallback");
+* 			myScale.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValues or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+* 			<blockquote><pre>
+* 			var myScale:Scale = new Scale(mc,[10,300],3000,Quad.easeOut);
+* 			myScales.run();
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 5: Scretch a movieclip to _xscale 400 in 2 second using elastic easing. 		
+* 			<blockquote><pre>
+*			new Scale(mc).run(400,100,2000,Elastic.easeOut);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 6: <a href="Scale_run_02.html">(Example.swf)</a> Scale a movieclip 1500% proportionally in two seconds  
+* 			using circular easing. After animation scale it back to 100%.
+* 			<blockquote><pre>			
+*			new Scale(mc).run(1500,1500,2000,Sine.easeOut,"onCallback");
+*			myListener.onCallback = function() {
+*				new Scale(mc).run(100,100,2000,Sine.easeIn);
+*			}
+*			</pre></blockquote>
+* 			Example 7: <a href="Scale_run_03.html">(Example.swf)</a> <a href="Scale_run_04.html">(Example.swf)</a>
+* 			To animate many movieclips the same way, this class also accepts 
+* 			an Array of movieclips instead of one movieclip. This way yields to a better performance than 
+* 			creating a new class instance for each movieclip you want to animate. Different 
+* 			start values of your movieclip properties are considered when animating multiple movieclips 
+* 			within one animation instance.
+* 			<p>
+* 			The following example is meant to shows that different start values are considered. 
+* 			50 rectangles will be drawn with the drawing package and scaled with Scale using multiple 
+* 			animations within one animation instance. See .swf example above.			
+* 			<blockquote><pre>
+*			var target:Line = new Line(500,0,500,98.5);
+*			target.draw();
+*			
+*			var squares:Array = new Array();
+*			for (var i:Number = 0; i<50; i++) {
+*				var x:Number = Math.random() * 300;
+*				var w:Number = Math.random() * 300;
+*				
+*				var myRectangle:Rectangle = new Rectangle(0, i*2, 100, 1);	
+*				myRectangle.setRegistrationPoint({x:0, y:0});
+*				myRectangle.lineStyle();
+*				myRectangle.draw();	
+*				myRectangle.movieclip._xscale = w;
+*				squares[i] = myRectangle.movieclip;
+*			}
+*			
+*			var myScale:Scale = new Scale(squares);
+*			myScale.setOptimizationMode(true);
+*			myScale.animationStyle(6000,Bounce.easeOut);
+*			myScale.run(500,squares[0]._yscale);
+* 			</pre></blockquote>
+* 			<p>
+* 			The example below moves, scales and rotates a number of movieclips with different start values.
+* 			See .swf example above.
+* 			<blockquote><pre>
+*			var mcs:Array = new Array();
+*			for (var i = 0; i<20; i++) {
+*				var x:Number = Math.random() * 640;
+*				var y:Number = Math.random() * 400;	
+*				var r:Number = Math.random() * 360;
+*				mcs[i] = this.attachMovie("mc", "mc"+i, i, {_x:x, _y:y, _xscale:0, _yscale:0, _rotation:r});
+*			}
+*			
+*			var myMove:Move = new Move(mcs);
+*			myMove.animationStyle(8000,Sine.easeInOut);
+*			myMove.run(320,200);
+*			
+*			var myScale:Scale = new Scale(mcs);
+*			myScale.animationStyle(8000,Sine.easeInOut);
+*			myScale.run(100,100);
+*			
+*			var myRotation:Rotation = new Rotation(mcs);
+*			myRotation.animationStyle(8000,Sine.easeInOut);
+*			myRotation.run(360);
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 8: <a href="Scale_single.html">(Example.swf)</a> A similar experiment 
+* 			like the above shows the speed difference compared to the way 
+* 			that animates each movieclip in a single instance. This is the slow way:
+* 			<blockquote><pre>
+*			var squares:Array = new Array();
+*			for (var i:Number = 0; i<200; i++) {
+*				squares[i] = _root.attachMovie("square_mc", "s"+i, i, {_y:i*2});
+*				var myScale:Scale = new Scale(squares[i]);
+*				myScale.scaleWithPixels(true);
+*				myScale.setOptimizationMode(true);
+*				myScale.animationStyle(10000,Bounce.easeOut);
+*				myScale.run(550,squares[0]._height);
+*			}
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 9: <a href="Scale_multi.html">(Example.swf)</a> 
+* 			...and this is the fast way:
+* 			<blockquote><pre>
+*			var squares:Array = new Array();
+*			for (var i:Number = 0; i<200; i++) {
+*				squares[i] = _root.attachMovie("square_mc", "s"+i, i, {_x:0, _y:i*2});
+*			}
+*			var myScale:Scale = new Scale(squares);
+*			myScale.scaleWithPixels(true);
+*			myScale.setOptimizationMode(true);
+*			myScale.animationStyle(10000,Bounce.easeOut);
+*			myScale.run(550,squares[0]._height);
+* 			</pre></blockquote>
+* 			<p>
+* 
+* @usage 
+* 		<pre>var myScale:Scale = new Scale(mc);</pre> 
+*		<pre>var myScale:Scale = new Scale(mc, amountx, amounty);</pre>
+* 		<pre>var myScale:Scale = new Scale(mc, amountx, amounty, duration);</pre>
+*		<pre>var myScale:Scale = new Scale(mc, amountx, amounty, duration, callback);</pre>
+* 		<pre>var myScale:Scale = new Scale(mc, amountx, amounty, duration, easing, callback);</pre>
+*		<pre>var myScale:Scale = new Scale(mc, values);</pre> 
+* 		<pre>var myScale:Scale = new Scale(mc, values, duration, callback);</pre> 
+* 		<pre>var myScale:Scale = new Scale(mc, values, duration, easing, callback);</pre>
+* 		<pre>var myScale:Scale = new Scale(mcs);</pre> 
+*		<pre>var myScale:Scale = new Scale(mcs, amountx, amounty);</pre>
+* 		<pre>var myScale:Scale = new Scale(mcs, amountx, amounty, duration);</pre>
+*		<pre>var myScale:Scale = new Scale(mcs, amountx, amounty, duration, callback);</pre>
+* 		<pre>var myScale:Scale = new Scale(mcs, amountx, amounty, duration, easing, callback);</pre>
+*		<pre>var myScale:Scale = new Scale(mcs, values);</pre> 
+* 		<pre>var myScale:Scale = new Scale(mcs, values, duration, callback);</pre> 
+* 		<pre>var myScale:Scale = new Scale(mcs, values, duration, easing, callback);</pre>  
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param amountx (Number) Targeted _xscale or _width to animate to.
+* @param amounty (Number) Targeted _yscale or _height to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation.
+*/
+class de.alex_uhlmann.animationpackage.animation.Scale 
+											extends AnimationCore 
+											implements IMultiAnimatable {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public var scaleXProperty:String = "_xscale";
+	public var scaleYProperty:String = "_yscale";
+	public var xProperty:String = "_x";
+	public var yProperty:String = "_y";	
+	private var pixelscale:Boolean = false;
+	private var pixelscaleConstructValue:Boolean;
+	private var areStartValuesSet:Boolean = false;	
+	private var modifiedRegistrationPoint:Boolean = false;
+	public var x:Number = 0;
+	public var y:Number = 0;
+	private var myInstances:Array;
+
+	public function Scale() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+		}
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function init():Void {
+		if(arguments[0] instanceof Array) {				
+			var values:Array = arguments[0];
+			var endValues:Array = values.slice(-2);
+			arguments.shift();
+			arguments.splice(0, 0, endValues[0], endValues[1]);
+			this.initAnimation.apply(this, arguments);
+			this.setStartValues([values[0], values[1]]);
+		} else if(arguments.length > 0) {			
+			this.initAnimation.apply(this, arguments);
+		}
+	}
+	
+	private function initAnimation(amountx:Number, amounty:Number, 
+						duration:Number, easing:Object, callback:String):Void {		
+		
+		if (arguments.length > 2) {	
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		
+		if(this.mc != null) {
+			this.pixelscaleConstructValue = this.pixelscale;
+			this.setStartValues([this.mc[this.scaleXProperty], this.mc[this.scaleYProperty]], true);
+		}
+		this.setEndValues([amountx, amounty]);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		this.startInitialized = false;		
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = this.endValues;
+
+		if(this.mc != null) {
+
+			//in case the pixelscale has been changed to true after the start values have been set via 
+			//constructor, we need to calculate the start values again, but only if start values 
+			//havn't been set and have to be calculated from current values.
+			var hasPixelScaleChanged:Boolean = (this.pixelscaleConstructValue != this.pixelscale && this.pixelscale == true)
+			if(hasPixelScaleChanged && !this.areStartValuesSet) {
+				this.setStartValues([this.mc[this.scaleXProperty], this.mc[this.scaleYProperty]]);
+			}
+			
+			this.myAnimator.start = this.startValues;
+			
+			if(!this.modifiedRegistrationPoint) {
+				this.myAnimator.setter = [[this.mc, this.scaleXProperty], 
+										[this.mc, this.scaleYProperty]];					
+			} else {
+				this.myAnimator.setter = [[this,"setX"], [this,"setY"]];
+			}
+
+		} else {
+			
+			if(!this.modifiedRegistrationPoint) {
+				this.myAnimator.multiStart = [this.scaleXProperty, this.scaleYProperty];	
+				this.myAnimator.multiSetter = [[this.mcs, this.scaleXProperty], 
+									[this.mcs, this.scaleYProperty]];				
+			} else {
+				var myInstances:Array = [];			
+				var len:Number = this.mcs.length;
+				var mcs:Array = this.mcs;
+				var i:Number = len;
+				while(--i>-1) {
+					myInstances[i] = new Scale(mcs[i]);
+					myInstances[i].setStartValues(this.getStartValues());
+					myInstances[i].scaleXProperty = this.scaleXProperty;
+					myInstances[i].scaleYProperty = this.scaleYProperty;
+					myInstances[i].x = this.x;
+					myInstances[i].y = this.y;
+				}
+				this.myInstances = myInstances;
+				this.myAnimator.multiStart = ["getMultiStartXValue","getMultiStartYValue"];	
+				this.myAnimator.multiSetter = [[this.myInstances,"setX"], 
+									[this.myInstances,"setY"]];
+			}
+		}
+		
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+
+	private function getMultiStartXValue(Void):Number {
+		var startValue:Number = this.getStartValues()[0];
+		if(startValue == null) {
+			return this.mc[this.scaleXProperty];
+		} else {
+			return startValue;
+		}
+	}
+	
+	private function getMultiStartYValue(Void):Number {
+		var startValue:Number = this.getStartValues()[1];
+		if(startValue == null) {
+			return this.mc[this.scaleYProperty];
+		} else {
+			return startValue;
+		}
+	}
+	
+	/*Adapted from solutions of Robert Penner, Darron Schall and Ben Jackson*/
+	public function setX(value:Number):Void {
+		
+		var bounds:Object = this.mc.getBounds(this.mc);
+		var xorigin:Number = bounds.xMin + this.x;
+
+		var a:Object = {x:xorigin, y:0};
+		this.mc.localToGlobal(a);
+		this.mc._parent.globalToLocal(a);
+		
+		this.mc[this.scaleXProperty] = value;
+
+		var b:Object = {x:xorigin, y:0};
+		this.mc.localToGlobal(b);
+		this.mc._parent.globalToLocal(b);
+		this.mc[this.xProperty] -= b.x - a.x;
+	}
+
+	/*Adapted from solutions of Robert Penner, Darron Schall and Ben Jackson*/
+	public function setY(value:Number):Void {
+		
+		var bounds:Object = this.mc.getBounds(this.mc);
+		var yorigin:Number = bounds.yMin + this.y;
+		
+		var a:Object = {x:0, y:yorigin};
+		this.mc.localToGlobal(a);
+		this.mc._parent.globalToLocal(a);
+		
+		this.mc[this.scaleYProperty] = value;
+
+		var b:Object = {x:0, y:yorigin};
+		this.mc.localToGlobal(b);
+		this.mc._parent.globalToLocal(b);
+		this.mc[this.yProperty] -= b.y - a.y;
+	}
+	
+	/**
+	* @method run
+	* @description 	Scales a movieclip from its the current _xscale and _yscale or _width and _height
+	* 			property values to specified amounts in a specified time and easing equation.
+	* 		
+	* @usage   
+	* 		<pre>myScale.run();</pre>		
+	* 		<pre>myScale.run(amountx, amounty);</pre>
+	* 		<pre>myScale.run(amountx, amounty, duration);</pre>
+	*		<pre>myScale.run(amountx, amounty, duration, callback);</pre>
+	* 		<pre>myScale.run(amountx, amounty, duration, easing, callback);</pre>
+	* 		<pre>myScale.run(values, duration);</pre>
+	* 		<pre>myScale.run(values, duration, callback);</pre>
+	*		<pre>myScale.run(values, duration, easing, callback);</pre>
+	* 	  
+	* @param amountx (Number) Targeted _xscale or _width to animate to.
+	* @param amounty (Number) Targeted _yscale or _height to animate to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation
+	* @return void
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myScale.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/	
+	
+	/**
+	* @method scaleWithPixels
+	* @description 	changes the scaling mode. Default is false.
+	* 				If true it scales the movieclip with _width and _height properties.
+	*                  		If false it scales the movieclip with _xscale and _yscale properties.
+	* @usage   <pre>myScale.scaleWithPixels(pixelscale);</pre> 	  
+	* @param pixelscale (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/
+	public function scaleWithPixels(pixelscale:Boolean) {
+		if(pixelscale) {
+			this.scaleXProperty = "_width";
+			this.scaleYProperty = "_height";
+		} else {
+			this.scaleXProperty = "_xscale";
+			this.scaleYProperty = "_yscale";			
+		}
+		this.pixelscale = pixelscale;		
+	}
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Movieclips scale according to their registration point. If the registration 
+	* 				point is in the center of the shape, the movieclip will scale evenly on all 
+	* 				sides. setRegistrationPoint in Scale emulates modifying the 
+	* 				registration point of the animation. Top left is 0,0. 
+	* 				The parameter object accepts either x and y properties with coordinates as values 
+	* 				of the registration point or a position property with 
+	* 				String flags. Currently there are the following options 
+	* 				for the position property available:<p>
+	* 				CENTER = central registration point of movieclip.
+	* 			<p>
+	* 			Example 1: Set the registration point of an mc to the upper left corner (0,0). 
+	* 			So even if mc's registration point is in the center, it will scale like as if 
+	* 			the registration point would be on the upper left corner.
+	* 			<blockquote><pre>
+	*			var myScale:Scale = new Scale(mc);
+	*			myScale.setRegistrationPoint( {x:0,y:0} );
+	*			myScale.run(200, 200);
+	*			</pre></blockquote>
+	* 			<p>
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/	
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		this.modifiedRegistrationPoint = true;		
+		if(registrationObj.position == "CENTER") {
+			this.x = this.mc._width / 2;
+			this.y = this.mc._height / 2;
+		} else {
+			if(registrationObj.x != null ) {
+				this.x = registrationObj.x;
+			}
+			if(registrationObj.y != null ) {
+				this.y = registrationObj.y;
+			}
+		}
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValues
+	* @description 	returns the original, starting values of the current tween. _xscale and _yscale or _width and _height properties.
+	* @usage   <tt>myInstance.getStartValues();</tt>
+	* @return (Array) First value is _xscale or _width, second is _yscale or _height.
+	*/
+	
+	/**
+	* @method setStartValues
+	* @description 	sets the original, starting values of the current tween. _xscale and _yscale or _width and _height properties.
+	* @usage   <tt>myInstance.setStartValues(startValues);</tt>
+	* @param startValues (Array) First value is _xscale or _width, second is _yscale or _height.
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	public function setStartValues(startValues:Array, optional:Boolean):Boolean {
+		if(optional == null) {	
+			this.areStartValuesSet = true;
+		}
+		return super.setStartValues(startValues, optional);
+	}
+	
+	/**
+	* @method getEndValues
+	* @description 	returns the targeted values of the current tween. _xscale and _yscale or _width and _height properties.
+	* @usage   <tt>myInstance.getEndValues();</tt>
+	* @return (Array) First value is _xscale or _width, second is _yscale or _height.
+	*/
+	
+	/**
+	* @method setEndValues
+	* @description 	sets the targeted value of the current tween. _xscale and _yscale or _width and _height properties.
+	* @usage   <tt>myInstance.setEndValues(endValues);</tt>
+	* @param endValues (Array) First value is _xscale or _width, second is _yscale or _height.
+	* @return Boolean, indicates if the assignment was performed.
+	*/		
+
+	/**
+	* @method getCurrentValues
+	* @description 	returns the current values of the current tween. _xscale and _yscale or _width and _height properties.
+	* @usage   <tt>myInstance.getCurrentValues();</tt>
+	* @return (Array) First value is _xscale or _width, second is _yscale or _height.
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Array) values to animate.<p>
+	* 		
+	* @usage   <pre>myScale.addEventListener(event, listener);</pre>
+	* 		    <pre>myScale.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myScale.removeEventListener(event, listener);</pre>
+	* 		    <pre>myScale.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myScale.removeAllEventListeners();</pre>
+	* 		    <pre>myScale.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myScale.eventListenerExists(event, listener);</pre>
+	* 			<pre>myScale.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Scale";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Scale.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Sequence.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Sequence.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Sequence.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,1177 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.IAnimatable;
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.IVisitor;
+import de.alex_uhlmann.animationpackage.utility.IVisitorElement;
+import de.alex_uhlmann.animationpackage.utility.IComposite;
+
+/**
+* @class Sequence
+* @author Alex Uhlmann
+* @description  Sequence allows you to animate the classes of 
+* 			de.alex_uhlmann.animationpackage.animation one after the other in a uniform manner.
+* 			Sequence uses the composite design pattern. [GoF]
+* 			<p>
+* 			Example 1: <a href="Sequence_01.html">(Example .swf)</a> Animate a sequence of animations back and forth.	
+* 			<pre><blockquote> 
+*			var myMoveOnQuadCurve:MoveOnQuadCurve = new MoveOnQuadCurve(mc,100,100,300,300,500,100);
+*			var myScale:Scale = new Scale(mc,50,50);
+*			var myRotation:Rotation = new Rotation(mc,360);
+*			var myColorTransform:ColorTransform = new ColorTransform(mc,0xff0000,50);
+*			
+*			var mySequence:Sequence = new Sequence();
+*			mySequence.setAnimateMode("EACH");
+* 			mySequence.addChild(myMoveOnQuadCurve);
+*			mySequence.addChild(myScale);
+*			mySequence.addChild(myRotation);
+*			mySequence.addChild(myColorTransform);
+*			mySequence.animationStyle(4000,Circ.easeInOut,"onCallback");
+*			mySequence.animate(0,100);
+*			myListener.onCallback = function(source) {
+*				trace("end of "+source);	
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				trace("end of "+source);	
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</pre></blockquote>
+* 			<p> 
+* 			Example 2: <a href="Sequence_02.html">(Example .swf)</a> 
+* 			Animate a sequence of Move animations like a path animation back and forth.
+* 			Notice that every Move will be animated separately like in the example above. The problem is with 
+* 			the backward animation.
+* 			<pre><blockquote> 
+* 			var myMove1:Move = new Move(mc,[400,300,400,50]);
+*			var myMove2:Move = new Move(mc,[400,50,150,50]);
+*			var myMove3:Move = new Move(mc,[150,50,150,300]);
+* 		
+*			var mySequence:Sequence = new Sequence();
+* 			mySequence.setAnimateMode("EACH");
+*			mySequence.addChild(myMove1);
+*			mySequence.addChild(myMove2);
+*			mySequence.addChild(myMove3);
+*			mySequence.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			mySequence.animate(0,100);
+*
+*			myListener.onCallback = function(source) {
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</pre></blockquote>
+* 			<p> 
+*			The order of Move animations doesn't seem correct for our path.<p>
+* 			Example 3: <a href="Sequence_03.html">(Example .swf)</a> 
+* 			Let's fix the problem with setting the animate mode to JOIN instead of 
+* 			Each. Since Sequence comes by default with animate mode set to JOIN 
+* 			all we have to do is simply to delete the setAnimateMode line.
+* 			<pre><blockquote> 
+*			var myMove1:Move = new Move(mc,[400,300,400,50]);
+*			var myMove2:Move = new Move(mc,[400,50,150,50]);
+*			var myMove3:Move = new Move(mc,[150,50,150,300]);
+*			
+* 			var mySequence:Sequence = new Sequence();	
+*			mySequence.addChild(myMove1);
+*			mySequence.addChild(myMove2);
+*			mySequence.addChild(myMove3);
+*			mySequence.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			mySequence.animate(0,100);
+*			
+*			myListener.onCallback = function(source) {
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</pre></blockquote>
+* 			Example 4: <a href="Sequence_04.html">(Example .swf)</a> 
+* 			Notice that in the example above our easing equation is applied to every child each. 
+* 			To let the Move animations behave more like a path animation we need to set the easing mode 
+* 			to JOIN.
+* 			<pre><blockquote> 
+*			var myMove1:Move = new Move(mc,[400,300,400,50]);
+*			var myMove2:Move = new Move(mc,[400,50,150,50]);
+*			var myMove3:Move = new Move(mc,[150,50,150,300]);
+*			
+*			var mySequence:Sequence = new Sequence();
+*			mySequence.addChild(myMove1);
+*			mySequence.addChild(myMove2);
+*			mySequence.addChild(myMove3);
+* 			mySequence.setEasingMode("JOIN");	
+*			mySequence.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			mySequence.animate(0,100);
+*			
+*			myListener.onCallback = function(source) {
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</pre></blockquote> 			
+* 			Reader exercise: create a smoother path animation with MoveOnQuadCurve, MoveOnCubicCurve 
+* 			and/or MoveOnCurve. And, take a look into MoveOnPath for another approach to 
+* 			create path animations using Ivan Dembicki's com.sharedfonts.Path class.
+* 			<p>
+*			Example 5: <a href="Sequence_05.html">(Example .swf)</a> Animate a sequence back and 
+* 			forth and attaches a Trail animation on a certain part of the sequence. The Text class helps to 
+* 			log all the updates of the sequence. Notice the usage of Sequence.getCurrentValue and the 
+* 			specific properties of the eventObject returned by EventDispatcher. There are getter methods 
+* 			of the Sequence class that also offer the information returned by the eventObject.
+* 			<pre><blockquote>
+*			var myStar:Star = new Star(275,200,60,15,6);
+*			myStar.lineStyle();
+*			myStar.fillStyle(0x9C3031);
+*			myStar.draw()
+*			var mc:MovieClip = myStar.movieclip;
+*			
+*			var myMoveOnQuadCurve:MoveOnQuadCurve = new MoveOnQuadCurve(mc,300,100,400,300,580,100);
+*			var myScale:Scale = new Scale(mc,50,50);
+*			var myRotation:Rotation = new Rotation(mc,360);
+*			var myColorTransform:ColorTransform = new ColorTransform(mc,0x8CA6BD,0);
+*			
+*			var myText:Text = new Text();
+*			
+*			function onStart(eventObject:Object) {
+*				this.setText(eventObject);
+*			}
+*			
+*			function onUpdate(eventObject:Object) {
+*				this.setText(eventObject);
+*				//if the next child of the Sequence is an instance of Rotation, attach the Trail 
+*				//for the duration of the Rotation instance.
+*				if(eventObject.nextChild instanceof Rotation) {
+*					var myTrail:Trail = new Trail(mc);
+*					myTrail.attach(250,40,eventObject.childDuration);
+*				}
+*			}
+*			
+*			function setText(eventObject:Object) {
+*				var myTextfield:TextField = myText.getText();
+*				if(myTextfield == null) {
+*					myText.setText(eventObject.nextChild+" is at no. "
+* 						+mySequence.getCurrentValue()+" in your "+mySequence);
+*				} else {
+*					if(myTextfield.textHeight < Stage.height-10) {
+*						myText.addText("\n"+eventObject.nextChild+" is at no. "
+*									+mySequence.getCurrentValue()+" in your "+mySequence);
+*					} else {			
+*						myText.movieclip.removeMovieClip();
+*					}		
+*				}
+*			}
+*			
+*			//Note that myText and mySequence will be visible inside the onUpdate, onStart 
+*			//and setText functions (closure).
+*			var mySequence:Sequence = new Sequence();
+*			mySequence.addEventListener("onStart",this);
+*			mySequence.addEventListener("onUpdate",this);
+*			mySequence.addChild(myMoveOnQuadCurve);
+*			mySequence.addChild(myScale);
+*			mySequence.addChild(myRotation);
+*			mySequence.addChild(myColorTransform);
+*			mySequence.animationStyle(6000,Circ.easeInOut,"onCallback");
+*			mySequence.animate(0,100);
+*			
+*			myListener.onCallback = function(source) {
+*				source.callback = "onCallback2";
+*				source.animate(100,0);
+*			}
+*			myListener.onCallback2 = function(source) {
+*				source.callback = "onCallback";
+*				source.animate(0,100);
+*			}
+* 			</pre></blockquote>
+* 			<p> 
+* 			
+* @usage <tt>var mySequence:Sequence = new Sequence();</tt>
+*/
+class de.alex_uhlmann.animationpackage.animation.Sequence 
+											extends AnimationCore 
+											implements ISingleAnimatable, 
+														IVisitorElement, 
+														IComposite {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	public static var JOIN:String = "JOIN";
+	public static var EACH:String = "EACH";
+	private var childsArr:Array;
+	private var start:Number;
+	private var end:Number;
+	private var currentChild:Object;
+	private var childDuration:Number;
+	private var position:Number = 1;
+	private var animateMode:String = "JOIN";
+	private var easingMode:String = "EACH";
+	private var easingClass:String;
+	private var firstEasingMeth:String;
+	private var lastEasingMeth:String;
+	private var roundedPosStart:Number;
+	private var roundedPosEnd:Number;
+	private var percentages:Array;
+	private var backwards:Boolean = false;
+	private var elapsedDuration:Number = 0;
+	private var sequenceArr:Array;
+	
+	public function Sequence() {		
+		super();
+		this.childsArr = new Array();
+		this.sequenceArr = new Array();
+	}
+	
+	/**
+	* @method animate
+	* @description 	animates the contents of the composite.
+	* @usage   <pre>mySequence.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	public function animate(start:Number, end:Number):Void {		
+		this.invokeAnimation(start, end);
+	}
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	private function invokeAnimation(start:Number, end:Number) {
+		var goto:Boolean;
+		var percentage:Number;
+		if(end == null) {
+			goto = true;
+			percentage = end = start;
+			start = 0;			
+		} else {
+			goto = false;
+			this.start = start;
+			this.end = end;
+			this.tweening = true;
+		}
+		
+		var i:Number, len:Number = this.childsArr.length;		
+		var fChild:Object;
+		
+		var posStart:Number = start / 100 * len;
+		var posEnd:Number = end / 100 * len;
+			
+		this.setStartValue(posStart);
+		this.setEndValue(posEnd);
+		
+		
+		if(this.animateMode == "JOIN") {			
+
+			if(!goto) {
+			
+				var details:Object = this.getAnimateDetails(start, end, this.childsArr, this);
+				this.backwards = details.backwards;
+				this.position = details.position;			
+				var roundedPosStart:Number = details.roundedPosStart;
+				var roundedPosEnd:Number = details.roundedPosEnd;
+				this.percentages = details.percentages;			
+				
+				if(this.easingMode == "JOIN") {				
+					
+					var dividedDuration:Number = this.childDuration = this.duration / len;
+					if(this.childsArr[roundedPosStart] instanceof Sequence) {
+						this.childsArr[roundedPosStart].animationStyle(dividedDuration, _global.com.robertpenner.easing[this.easingClass][this.firstEasingMeth]);
+					} else {
+						this.childsArr[roundedPosStart].easing = _global.com.robertpenner.easing[this.easingClass][this.firstEasingMeth];
+					}
+					if(this.childsArr[roundedPosEnd] instanceof Sequence) {
+						this.childsArr[roundedPosEnd].animationStyle(dividedDuration, _global.com.robertpenner.easing[this.easingClass][this.lastEasingMeth]);
+					} else {
+						this.childsArr[roundedPosEnd].easing = _global.com.robertpenner.easing[this.easingClass][this.lastEasingMeth];
+					}
+				}
+			
+				fChild = this.currentChild = this.childsArr[roundedPosStart];
+				fChild.animate(this.percentages[this.position-1].start, 
+								this.percentages[this.position-1].end);	
+									
+			} else {
+				
+				if(percentage < 0) {
+					this.invokeAnimation(0);
+					return;
+				} else if(percentage > 100) {
+					this.invokeAnimation(100);
+					return;
+				}
+				var posPerc:Number = percentage / 100 * (len);
+				var roundedPosPerc:Number = Math.floor(posPerc);
+				var perc_loc:Number = (posPerc - roundedPosPerc) * 100;
+				this.position = roundedPosPerc + 1;
+				this.currentChild = this.childsArr[roundedPosPerc];
+				
+				for (i = 0; i < len; i++) {
+					var child:Object = this.childsArr[i];
+					if(i < roundedPosPerc) {
+						child.goto(100);
+					} else {
+						child.goto(0);
+					}
+				}
+				
+				this.childsArr[roundedPosPerc].goto(perc_loc);
+				
+				if(percentage == 0) {
+					this.dispatchEvent({type:"onStart", 
+									value:this.getStartValue(),
+									childDuration:this.childDuration});
+				} else if(percentage == 100) {
+					this.dispatchEvent({type:"onEnd", 
+									value:this.getEndValue(), 
+									childDuration:this.childDuration});
+				} else {
+					this.dispatchEvent({type:"onUpdate", 
+									value:this.getCurrentValue(), 
+									childDuration:this.childDuration});		
+				}
+			}
+			
+		} else {			
+			
+			this.percentages = new Array();
+			this.position = 1;
+			for (i = 0; i < len; i++) {
+				var child:Object = this.childsArr[i];
+				this.sequenceArr.push(this.childsArr[i+1]);
+				child.addEventListener("onUpdate", this);
+				child.addEventListener("onEnd", this);
+				this.percentages[i] = {start:start, end:end};
+			}		
+			fChild = this.currentChild = this.childsArr[0];			
+			if(goto == false) {
+				if(start > end) {
+					this.backwards = true;				
+				} else {
+					this.backwards = false;
+				}				
+				fChild.animate(start, end);
+			} else {			
+				fChild.goto(percentage);
+			}
+		}
+		if(!goto) {
+			this.childDuration = fChild.duration;
+			this.elapsedDuration = 0;
+			this.dispatchEvent.apply(this, [ {type:"onStart",
+											value:this.getStartValue(),
+											nextChild:fChild, 
+											lastChild:null, 
+											childDuration:this.childDuration} ]);
+		}
+	}
+
+	private function getAnimateDetails(start:Number, 
+									end:Number, 
+									childsArr:Array, 
+									ref:Object):Object {
+		
+		var backwards:Boolean;
+		if(start > end) {
+			backwards = true;				
+		} else {
+			backwards = false;
+		}
+		/*			
+		* To compute start and end values for all childs combined, 
+		* I first compute the childs where the tween will start and end. (rule of three)
+		* The integer part of the number posStart and posEnd represents that.
+		* The fractional part of those numbers represent the percentage to be animated in integer child.
+		*/
+		var i:Number, len:Number = this.childsArr.length;
+		var posStart:Number = start / 100 * (len);
+		var posEnd:Number = end / 100 * (len);
+		
+		var roundedPosStart:Number = Math.floor(posStart);
+		var roundedPosEnd:Number = Math.floor(posEnd);			
+		var start_loc:Number;
+		if(posStart > roundedPosStart) {				
+			start_loc = (posStart - roundedPosStart) * 100;					
+		} else {
+			if(backwards) {
+				roundedPosStart--;
+				start_loc = 100;
+			} else {					
+				start_loc = 0;
+			}
+		}			
+		var end_loc:Number;
+		if(posEnd > roundedPosEnd) {				
+			end_loc = (posEnd - roundedPosEnd) * 100;					
+		} else {				
+			if(backwards) {
+				end_loc = 0;
+			} else {
+				roundedPosEnd--;
+				end_loc = 100;
+			}
+		}
+		
+		this.position = roundedPosStart+1;
+		
+
+		//apply animate state to all children.			
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];			
+			child.omitEvent = true;
+			if(backwards) {
+				if(i > roundedPosStart) {
+					child.goto(0);
+				} else {
+					child.goto(100);
+				}
+			}
+			child.omitEvent = false;
+		}		
+		for (i = len-1; i > -1; i--) {
+			var child:Object = this.childsArr[i];
+			child.omitEvent = true;
+			if(!backwards) {
+				if(i < roundedPosStart) {
+					child.goto(100);
+				} else {
+					child.goto(0);
+				}
+			}
+			child.omitEvent = false;
+			child.addEventListener("onUpdate", this);
+		}
+
+		
+		//reset succossors.
+		this.sequenceArr = new Array();
+		
+		var percentages:Array = new Array();
+		var child:Object;
+		//for forward tweening
+		for (i = roundedPosStart; i < roundedPosEnd; i++) {
+			child = childsArr[i];
+			this.sequenceArr.push(this.childsArr[i+1]);
+			child.addEventListener("onEnd", ref);
+			if(i == roundedPosStart) {
+				percentages[i] = {start:start_loc, end:100};
+			} else {
+				percentages[i] = {start:0, end:100};
+			}
+		}
+		//for backward tweening
+		for (i = roundedPosStart; i > roundedPosEnd; i--) {
+			child = childsArr[i];
+			this.sequenceArr.push(this.childsArr[i-1]);
+			child.addEventListener("onEnd", ref);
+			if(i == roundedPosStart) {
+				percentages[i] = {start:start_loc, end:0};
+			} else {
+				percentages[i] = {start:100, end:0};
+			}
+		}
+		child = childsArr[roundedPosEnd];
+		child.addEventListener("onEnd", ref);
+		if(backwards) {
+			percentages[roundedPosEnd] = {start:100, end:end_loc};
+		} else {
+			percentages[roundedPosEnd] = {start:0, end:end_loc};
+		}
+		
+		var details = new Object();
+		details.backwards = backwards;
+		details.position = roundedPosStart+1;
+		details.roundedPosStart = roundedPosStart;
+		details.roundedPosEnd = roundedPosEnd;		
+		details.percentages = percentages;		
+		return details;
+	}
+	
+	public function onStart(eventObject:Object):Void {		
+		this.dispatchEvent({type:"onStart", 
+							value:this.getStartValue(),
+							childDuration:this.childDuration});
+	}	
+	
+	public function onUpdate(eventObject:Object):Void {	
+		this.dispatchEvent({type:"onUpdate", 
+							value:this.getCurrentValue(), 
+							childDuration:this.childDuration});
+	}
+	
+	public function onEnd(eventObj:Object):Void {
+		
+		eventObj.target.removeEventListener("onEnd", this);
+		var successor:Object = this.sequenceArr.shift();
+		this.childDuration = successor.duration;
+		if(successor == null) {
+			this.tweening = false;
+			APCore.broadcastMessage(this.callback, this);			
+			this.dispatchEvent.apply(this, [ {type:"onEnd",
+											value:this.getEndValue(),
+											nextChild:null, 
+											lastChild:eventObj.target, 
+											childDuration:null} ]);
+
+		} else {
+			/*backwards will only be true in Sequence mode JOIN*/
+			if(this.animateMode == Sequence.JOIN && this.backwards) {
+				this.position--;
+			} else {
+				this.position++;
+			}
+			this.elapsedDuration += eventObj.target.getDurationElapsed();
+			this.currentChild = successor;			
+			this.dispatchEvent.apply(this, [ {type:"onUpdatePosition",
+											value:this.getCurrentValue(),
+											nextChild:successor, 
+											lastChild:eventObj.target, 
+											childDuration:this.childDuration} ]);			
+
+			successor["animate"].apply(successor, [this.percentages[this.position-1].start, 
+												this.percentages[this.position-1].end]);
+		}		
+	}
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation. Overwrites animationStyle settings from childs.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* @usage   <pre>mySequence.animationStyle(duration);</pre>
+	* 		<pre>mySequence.animationStyle(duration, callback);</pre>
+	* 		<pre>mySequence.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation(s) in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation(s). See APCore class.
+	*/
+	public function animationStyle(duration:Number, easing:Object, callback:String):Void {
+		super.animationStyle(duration, easing, callback);
+		var i, len:Number = this.childsArr.length;
+		var dividedDuration:Number = this.childDuration = duration / len;
+		if(this.animateMode == "JOIN") {
+			var fChild:Object = this.childsArr[0];		
+			fChild.animationStyle(dividedDuration, easing);		
+			var firstEasing:String;
+			var lastEasing:String;
+			var oneClass:Function;
+			var meth:String;
+			var func:Function;
+			var classes = eval("com.robertpenner.easing");
+			var c:String;
+			var myC:String, myMeth:String;
+			for(c in classes) {				
+				oneClass = _global.com.robertpenner.easing[c]; 
+				for(meth in oneClass) {					
+					func = oneClass[meth];
+					if(func == fChild.easing) {						
+						myC = c;
+						myMeth = meth;					
+						if(meth == "easeIn") {
+							firstEasing = "easeIn";
+							lastEasing = "easeNone"; 
+						} else if(meth == "easeOut") {
+							firstEasing = "easeNone";
+							lastEasing = "easeOut"; 						
+						} else if(meth == "easeInOut") {
+							firstEasing = "easeIn";
+							lastEasing = "easeOut"; 					
+						} else if(meth == "easeNone") {
+							firstEasing = "easeNone";
+							lastEasing = "easeNone"; 						
+						}
+						break;
+					}
+				}
+			}		
+			if(this.easingMode == "JOIN") {
+				for (i = 0; i < len; i++) {
+					this.childsArr[i].animationStyle(dividedDuration, 
+							_global.com.robertpenner.easing.Linear.easeNone);
+				}
+			} else {
+				for (i = 0; i < len; i++) {
+					this.childsArr[i].animationStyle(dividedDuration, easing);					
+				}
+			}
+			this.firstEasingMeth = firstEasing;
+			this.lastEasingMeth = lastEasing;
+			this.easingClass = myC;		
+			
+		} else {
+			for (i = 0; i < len; i++) {
+				this.childsArr[i].animationStyle(dividedDuration, easing);
+			}
+		}
+		this.callback = callback;
+	}
+
+	/**
+	* @method setAnimateMode
+	* @description 	sets the animate mode. If JOIN, the start and end percentage 
+	* 				parameters influences the composite animation as a whole. Defaults to JOIN. 
+	* 				See class documentation.
+	* @usage   <tt>myInstance.setAnimateMode();</tt>
+	* @param animateMode (String) Either EACH or JOIN.
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	public function setAnimateMode(animateMode:String):Boolean {
+		if(animateMode == "EACH" || animateMode == "JOIN") {	
+			this.animateMode = animateMode;
+		} else {
+			return false;
+		}
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];
+			if(child instanceof Sequence) {
+				child.setAnimateMode(animateMode);
+			}
+		}
+		return true;	
+	}
+	
+	/**
+	* @method getAnimateMode
+	* @description 	returns the current animate mode.
+	* @usage   <tt>myInstance.getAnimateMode();</tt>
+	* @return String
+	*/
+	public function getAnimateMode(Void):String {
+		return this.animateMode;
+	}
+	
+	/**
+	* @method setEasingMode
+	* @description 	sets the easing mode. If EACH, each child will be animated separately.
+	* 				If JOIN the childs seem to share one easing equation. Defaults to EACH.
+	* @usage   <tt>myInstance.setEasingMode();</tt>
+	* @param easingMode (String) Either EACH or JOIN.
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	public function setEasingMode(easingMode:String):Boolean {
+		if(easingMode == "EACH" || easingMode == "JOIN") {	
+			this.easingMode = easingMode;
+		} else {
+			return false;
+		}
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];			
+			if(child instanceof Sequence) {
+				child.setEasingMode(easingMode);
+			}
+		}
+		return true;
+	}
+	
+	/**
+	* @method getEasingMode
+	* @description 	returns the current easing mode.
+	* @usage   <tt>myInstance.getEasingMode();</tt>
+	* @return String
+	*/
+	public function getEasingMode(Void):String {
+		return this.easingMode;
+	}
+	
+	/**
+	* @method getChild
+	* @description 	returns the current child of the sequence.
+	* @usage   <tt>myInstance.getChild();</tt>
+	* @return IAnimatable
+	*/	
+	public function getChild(Void):IAnimatable {		
+		return IAnimatable(this.currentChild);
+	}
+	
+	/**
+	* @method getChildren
+	* @description 	returns an Array of all children of the sequence. 
+	* 				Could contain other Sequences.
+	* @usage   <tt>myInstance.getChildren();</tt>
+	* @return Array
+	*/	
+	public function getChildren(Void):Array {
+		return this.childsArr;
+	}
+	
+	/**
+	* @method getNextChild
+	* @description 	returns the next child of the sequence.
+	* @usage   <tt>myInstance.getNextChild();</tt>
+	* @return IAnimatable
+	*/	
+	public function getNextChild(Void):IAnimatable {
+		if(this.animateMode == "JOIN" && this.backwards) {
+			return IAnimatable(this.childsArr[this.position-2]);
+		} else {
+			return IAnimatable(this.childsArr[this.position]);
+		}
+	}
+	
+	/**
+	* @method getPreviousChild
+	* @description 	returns the previous child of the sequence.
+	* @usage   <tt>myInstance.getPreviousChild();</tt>
+	* @return IAnimatable
+	*/	
+	public function getPreviousChild(Void):IAnimatable {		
+		if(this.animateMode == "JOIN" && this.backwards) {
+			if(this.position-1 == this.childsArr.length) {
+				return IAnimatable(this.childsArr[this.position-1]);
+			} else {
+				return IAnimatable(this.childsArr[this.position]);
+			}			
+		} else {
+			return IAnimatable(this.childsArr[this.position-2]);
+		}
+	}
+	
+	/**
+	* @method getChildDuration
+	* @description 	returns the duration of the currently animated child in constrast to the duration property, 
+	* 				which is the duration of the whole Sequence.  
+	* @usage   <tt>myInstance.getChildDuration();</tt>
+	* @return Number
+	*/
+	public function getChildDuration(Void):Object {		
+		return this.childDuration;
+	}
+
+	/**
+	* @method addChild
+	* @description 	adds a primitive or composite to the composite instance of Sequence 
+	* See class description.
+	* @usage  <pre>mySequence.addChild(component);</pre>
+	* @param component (IAnimatable) Must be compatible to IAnimatable.
+	* @return IAnimatable class that was added.
+	*/
+	public function addChild(component:IAnimatable):IAnimatable {		
+		if(component instanceof Object) {
+			this.childsArr.push(component);
+			return component;
+		}
+	}
+
+	/**
+	* @method removeChild
+	* @description 	removes a primitive or composite from the composite instance of Sequence 
+	* See class description.
+	* @usage  <pre>mySequence.removeChild(component);</pre>
+	* @param component (IAnimatable) Must be compatible to IAnimatable.	
+	*/
+	public function removeChild(component:IAnimatable):Void {		
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			if(this.childsArr[i] == component) {
+				this.childsArr.splice(i, 1);
+			}
+		}
+	}
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	* @param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	public function roundResult(rounded:Boolean):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].roundResult(rounded);		
+		}
+	}
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	public function forceEnd(forceEndVal:Boolean):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].forceEnd(forceEndVal);		
+		}
+	}
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	public function setOptimizationMode(optimize:Boolean):Void {
+		this.equivalentsRemoved = optimize;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].setOptimizationMode(optimize);		
+		}
+	}	
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode(tweenMode);</tt> 	
+	* @param tweenMode (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	public function setTweenMode(tweenMode:String):Boolean {
+		this.tweenMode = tweenMode;
+		var isSet:Boolean;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			isSet = this.childsArr[i].setTweenMode(tweenMode);		
+		}
+		return isSet;
+	}
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode(durationMode);</tt> 	
+	* @param durationMode (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/	
+	public function setDurationMode(durationMode:String):Boolean {
+		this.durationMode = durationMode;
+		var isSet:Boolean;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			isSet = this.childsArr[i].setDurationMode(durationMode);		
+		}
+		return isSet;
+	}
+	
+	/**
+	* @method accept
+	* @description 	Allow a visitor to visit its elements. See Visitor design pattern [GoF].
+	* @usage  <pre>myInstance.accept(visitor);</pre>
+	* @param visitor (IVisitor) Must be compatible to de.alex_uhlmann.animationpackage.utility.IVisitor.	
+	*/
+	public function accept(visitor:IVisitor):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			visitor.visit(this.childsArr[i]);			
+		}
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/
+	public function stop(Void):Boolean {		
+		var success:Boolean = this.getChild().stop();
+		if(success) {
+			this.tweening = false;
+			this.paused = false;
+			this.dispatchEvent.apply(this, [ {type:"onEnd", 
+										nextChild:null, 
+										lastChild:this.getChild(), 
+										childDuration:null} ]);
+		}
+		return success;
+	}	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause(duration);</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/
+	public function pause(duration:Number):Boolean {		
+		var success:Boolean = this.getChild().pause(duration);
+		if(success) {
+			this.tweening = false;
+			this.paused = true;
+		}
+		return success;		
+	}	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	public function resume(Void):Boolean {	
+		var success:Boolean = this.getChild().resume();
+		if(success) {
+			this.tweening = true;
+			this.paused = false;
+		}
+		return success;
+	}	
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. First position of sequence. Always zero.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	public function getStartValue(Void):Number {		
+		var startValue:Number = super.getStartValue();
+		if(startValue == null) {
+			startValue = 0;
+		}		
+		return startValue;
+	}
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. first position of sequence. 
+	* 				Last position of sequence. Number of childs added to the sequence.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	public function getEndValue(Void):Number {		
+		var endValue:Number = super.getEndValue();
+		if(endValue == null) {
+			endValue = 100;
+		}
+		return endValue;
+	}
+	
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Current position of sequence.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	public function getCurrentValue(Void):Number {
+		return this.position;
+	}
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/
+	public function getCurrentPercentage(Void):Number {
+		var pos:Number = this.getCurrentValue()-1;
+		var perc:Number = this.currentChild.getCurrentPercentage();
+		if(typeof(perc) != "number" || isNaN(perc)) {
+			perc = 0;			
+		}
+		if(this.animateMode == Sequence.EACH && this.backwards == true) {
+			pos = this.getEndValue() - (pos - (this.getStartValue() - 1));
+		}
+		var currentValue:Number = pos + perc / 100;
+		var currentPerc:Number = currentValue / (this.childsArr.length) * 100;		
+		return currentPerc;			
+	}
+	
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	public function getDurationElapsed(Void):Number {
+		return this.elapsedDuration + this.currentChild.getDurationElapsed();
+	}
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	public function getDurationRemaining(Void):Number {
+		return this.duration - this.getDurationElapsed();
+	}
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when sequence starts.<br>
+	* 			<b>onUpdate</b>, broadcasted when a Sequence's child updates.<br>
+	*			<b>onUpdatePosition</b>, broadcasted when sequence animates a new child.<br>
+	* 			<b>onEnd</b>, broadcasted when sequence ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Sequence) event source.<br>
+	*			<b>value</b> (Sequence) current position of Sequence. First child is 1.<br> 
+	* 			<b>nextChild</b> (IAnimatable) next child in sequence to be animated.<br>
+	* 			<b>lastChild</b> (IAnimatable) last child in sequence that has been animated.<br>
+	* 			<b>childDuration</b> (Number) duration of every single child.<br>
+	* 		
+	* @usage   <pre>mySequence.addEventListener(event, listener);</pre>
+	* 		    <pre>mySequence.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>mySequence.removeEventListener(event, listener);</pre>
+	* 		    <pre>mySequence.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>mySequence.removeAllEventListeners();</pre>
+	* 		    <pre>mySequence.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>mySequence.eventListenerExists(event, listener);</pre>
+	* 			<pre>mySequence.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "Sequence";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Sequence.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Shake.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Shake.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Shake.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,346 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Pause;
+/**
+* @class Shake
+* @description Shakes a movieclip with a specified power, optional specified rotation 
+* 			in a specified time.
+* 			<p>
+* 			Example 1: shakes a movieclip 1 second with little power and without rotation. 		
+* 			<blockquote><pre>
+*			new Shake(mc).run(.1,2000);
+*			</pre></blockquote>
+* 			<p>
+* 			Example 2: <a href="Shake_run_02.html">(Example .swf)</a> shakes a movieclip with a little more power and a little rotation
+* 			2 seconds long. Then, shake it harder but without rotation. Both shake animations have a Trail effect attached.
+* 			<blockquote><pre>			
+* 			new Trail(mc).attach(250,40,4000);
+*			new Shake(mc).run(.2,2000,2,"onCallback");	
+*			myListener.onCallback = function() {	
+*				new Shake(mc).run(.8,2000);
+*			}
+*			</pre></blockquote>		
+* @usage <tt>var myShake:Shake = new Shake(mc);</tt> 
+* @param mc (MovieClip) Movieclip to animate.
+*/
+class de.alex_uhlmann.animationpackage.animation.Shake 
+											extends AnimationCore {	
+	
+	/*property inherited from AnimationCore*/
+	/**
+	* @property movieclip (MovieClip) Movieclip to animate.
+	*/
+	private var interval_ID:Number;
+	private var interval_ID2:Number;
+	private var rot:Number;
+	private var loc_callback:String;
+	private var milliseconds:Number;
+	private var millisecondsOrig:Number;
+	private var elapsedDuration:Number = 0;
+	private var paused:Boolean = false;
+	private var stopped:Boolean = false;
+	private var finished:Boolean = false;
+	private var startPause:Number;
+	private var durationPaused:Number = 0;
+	private var startTime:Number;
+	private var power:Number;
+	private var origin_x:Number;
+	private var origin_y:Number;	
+	private var origin_rot:Number;
+	
+	public function Shake(mc:MovieClip) {
+		super();
+		this.mc = mc;
+	}
+	
+	/**
+	* @method run
+	* @description 	Shakes a movieclip with a specified power, optional specified rotation 
+	* 			in a specified time.
+	* 		
+	* @usage   <pre>myShake.run(power, milliseconds, rot[, callback]);</pre>
+	* 		<pre>myShake.run(power, milliseconds[, callback]);</pre>
+	* 	  
+	* @param power (Number) Power to shake mc. (0.1 for small shaking and maybe 1 for real shaking).
+	* @param milliseconds (Number) Duration of shaking in milliseconds.
+	* @param rot (Number) lets mc rotate while shaking. Optional.
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	public function run():Void {
+		
+		var power:Number = arguments[0];
+		var milliseconds:Number = arguments[1];
+		var rot:Object = arguments[2];
+		var callback:String = arguments[3];
+		var temp;
+		if (typeof(rot) == "string") {
+			temp = rot;
+			callback = temp;			
+		} else if (typeof(rot) == "number") {
+			temp = rot;
+			this.rot = temp;
+		}		
+		this.loc_callback = callback;
+		this.millisecondsOrig = this.milliseconds = milliseconds;		
+		this.power = power;
+		
+		this.origin_x = this.mc._x;
+		this.origin_y = this.mc._y;
+		this.origin_rot = this.mc._rotation;
+		this.dispatchEvent.apply(this, [ {type:"onStart"} ]);
+		this.startTime = getTimer();
+		this.initShakeInterval();
+		this.initEndInterval();
+	}
+	
+	private function initShakeInterval(Void):Void {		
+		var parent:Object = this;
+		var r1:Number, r2:Number;
+		/*copy instance variables to local variables for the sake of performance.*/
+		var mc_loc:MovieClip = this.mc;
+		var power_loc:Number = this.power;
+		var rot_loc:Number = this.rot;
+		var origin_x_loc:Number = this.origin_x;
+		var origin_y_loc:Number = this.origin_y;
+		var origin_rot_loc:Number = this.origin_rot;
+		this.tweening = true;
+		this.finished = false;
+		//shake it fast
+		this.interval_ID = setInterval(function () {			
+			//adapted from crazyl0rd @ EFnet
+			r1 = (Math.round(Math.random()*10) < 5) ? -r1 : r1;
+			r2 = (Math.round(Math.random()*10) < 5) ? -r2 : r2;		
+			mc_loc._x = origin_x_loc+power_loc*r1;
+			mc_loc._y = origin_y_loc+power_loc*r2;
+		
+			if (rot_loc != 0) 
+				mc_loc._rotation = mc_loc._rotation-Math.random()*rot_loc+Math.random()*rot_loc;			
+			updateAfterEvent();
+		}, 10);
+	}
+	
+	private function initEndInterval(Void):Void {
+		var parent:Object = this;
+		//enough shaking. Reset.
+		this.interval_ID2 = setInterval(function () { 
+			parent.tweening = false;
+			parent.finished = true;
+			parent.mc._x = parent.origin_x;
+			parent.mc._y = parent.origin_y;
+			parent.mc._rotation = parent.origin_rot;			
+			clearInterval(parent.interval_ID);
+			clearInterval(parent.interval_ID2);
+			APCore.broadcastMessage(parent.loc_callback, parent);
+			parent.dispatchEvent.apply(parent, [ {type:"onEnd", target:parent} ]);
+		}, this.milliseconds);
+	}
+	
+	public function stop(Void):Boolean {		
+		if(super.stop() == true) {
+			this.tweening = false;
+			this.stopped = true;
+			this.elapsedDuration = this.computeElapsedDuration();
+			clearInterval(this.interval_ID);
+			clearInterval(this.interval_ID2);	
+			return true;
+		} else {
+			return false;
+		}
+	}
+		
+	public function pause(duration:Number):Boolean {		
+		if(this.locked == true || this.tweening == false) {
+			return false;
+		} else {			
+			this.tweening = false;
+			this.paused = true;
+			this.elapsedDuration = this.computeElapsedDuration();
+			this.startPause = getTimer();
+			if(duration != null) {
+				var myPause:Pause = new Pause();				
+				myPause.waitMS(duration, this, "resume");
+			}
+			clearInterval(this.interval_ID);
+			clearInterval(this.interval_ID2);			
+			return true;		
+		}
+	}
+	
+	public function resume(Void):Boolean {		
+		if(this.locked == true || this.paused == false) {
+			return false;
+		} else {
+			this.tweening = true;
+			this.paused = false;
+			this.milliseconds -= this.elapsedDuration;
+			this.durationPaused += getTimer() - this.startPause;
+			this.initShakeInterval();
+			this.initEndInterval();
+			return true;
+		}
+	}
+
+	public function getDurationElapsed(Void):Number {		
+		if(this.paused == true || this.stopped == true) {
+			return this.elapsedDuration;
+		} else {
+			return this.computeElapsedDuration();
+		}
+	}
+	
+	public function getDurationRemaining(Void):Number {
+		var r:Number;
+		if(this.stopped == false) {
+			r = this.millisecondsOrig - this.getDurationElapsed();
+			if(r < 0) {
+				r = 0;
+			}
+		} else {
+			r = 0;
+		}
+		return r;
+	}
+	
+	private function computeElapsedDuration(Void):Number {
+		if(this.finished == true) {
+			return this.millisecondsOrig;
+		} else {		
+			return getTimer() - this.startTime - this.durationPaused;			
+		}
+	}	
+	
+	/*inherited from AnimationCore*/	
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked.
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param milliseconds (Number) optional property. Number of milliseconds to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time in milliseconds since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time in milliseconds since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myShake.addEventListener(event, listener);</pre>
+	* 		    <pre>myShake.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myShake.removeEventListener(event, listener);</pre>
+	* 		    <pre>myShake.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myShake.removeAllEventListeners();</pre>
+	* 		    <pre>myShake.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myShake.eventListenerExists(event, listener);</pre>
+	* 			<pre>myShake.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Shake";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Shake.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Skew.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Skew.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Skew.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,605 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Skew
+* @author Alex Uhlmann
+* @description  Skews a movieclip like in the Flash IDE's transform panel.<p>	
+* 			You can specify the duration, easing equation and callback properties 
+* 			either with setting the properies directly or with the animationStyle() method 
+* 			like it is used in de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 1:
+* 			<blockquote><pre>			
+*			var mySkew:Skew = new Skew(mc.inner_mc);
+*			mySkew.animationStyle(1000,Sine.easeInOut,"onCallback");
+*			mySkew.skewHorizontal(30);
+*			</pre></blockquote>  			
+* 			Example 2: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new Skew(mc.inner_mc).skewHorizontal(30,1000,Sine.easeInOut,"onCallback");
+* 			</pre></blockquote>		
+*  			Example 3: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 
+* 			<blockquote><pre>
+* 			var mySkew:Skew = new Skew(mc.inner_mc,"HORIZ",30,1000,Sine.easeInOut,"onCallback");
+* 			mySkew.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 4: By default, the start value of your animation is the current value. You can explicitly 
+* 			define the start values either via the setStartValue or run method or via the constructor. Here is one 
+* 			example for the constructor solution. This also might come in handy using composite classes, like 
+* 			Sequence.
+*			<blockquote><pre>
+*			var mySkew:Skew = new Skew(mc.inner_mc,"HORIZ",[-30,30],2000,Sine.easeInOut);
+*			mySkew.skewHorizontal();
+* 			</pre></blockquote>	
+* @usage <pre>var mySkew:Skew = new Skew(inner_mc);</pre>
+* 		<pre>var mySkew:Skew = new Skew(inner_mc, type, degree);</pre>
+* 		<pre>var mySkew:Skew = new Skew(inner_mc, type, degree, duration);</pre>
+*		<pre>var mySkew:Skew = new Skew(inner_mc, type, degree, duration, callback);</pre>
+* 		<pre>var mySkew:Skew = new Skew(inner_mc, type, degree, duration, easing, callback);</pre>
+*		<pre>var mySkew:Skew = new Skew(inner_mc,type, values);</pre> 
+* 		<pre>var mySkew:Skew = new Skew(inner_mc,type, values, duration, callback);</pre> 
+* 		<pre>var mySkew:Skew = new Skew(inner_mc,type, values, duration, easing, callback);</pre> 
+*  
+* @param inner_mc (MovieClip) Movieclip to animate. Movieclip must have a parent clip.
+* @param type (String) Type of skew. Choose between  HORIZ for horizontal skew or VERT for vertical skew.
+* @param degree (Number) Targeted degree to skew to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Skew 
+										extends AnimationCore 
+										implements ISingleAnimatable {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property Skew.HORIZ (String)(static) Property that can be used to set the skew mode.
+	* @property Skew.VERT (String)(static) Property that can be used to set the skew mode.
+	* @property movieclip (MovieClip) Movieclip to animate. Movieclip must have a parent clip.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/
+	public static var HORIZ:String = "HORIZ";
+	public static var VERT:String = "VERT";	
+	private var outer_mc:MovieClip;
+	private var type:String;
+	private var skew:Number;
+	
+	public function Skew() {
+		super();
+		this.mc = arguments[0];
+		this.outer_mc = this.mc._parent;
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function init():Void {		
+		if(arguments[1] instanceof Array) {				
+			var values:Array = arguments[1];
+			var endValue:Number = values.slice(-1)[0];				
+			arguments.splice(1, 1, endValue);
+			this.initAnimation.apply(this, arguments);				
+			this.setStartValue(values[0]);				
+		} else if(arguments.length > 1) {				
+			this.initAnimation.apply(this, arguments);
+		}
+	}
+	
+	private function initAnimation(type:String, skew:Number, duration:Number, easing:Object, callback:String):Void {		
+		if (arguments.length > 2) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		this.type = type;
+		var skewKind:String = getFunctionStr(type);
+		if (this.mc._rotation == 0) {
+			this["set"+skewKind](0);
+		}
+		this.setStartValue(this["get"+skewKind](), true);		
+		this.setEndValue(skew);
+		this.skew = skew;
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		//determine kind of skew
+		var skewKind:String = getFunctionStr(this.type);
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [this.startValue];
+		this.myAnimator.end = [this.endValue];
+		this.myAnimator.setter = [[this,"set"+skewKind]];	
+		if(end != null) {			
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	private function getFunctionStr(type:String):String {
+		var skewKind:String;
+		if(type == Skew.HORIZ) {			
+			skewKind = "HorizontalSkew";
+		} else if (type == Skew.VERT) {
+			skewKind = "VerticalSkew";  
+		}
+		return skewKind;
+	}	
+	
+	/**
+	* @method skewHorizontal	 
+	* @description 	Skews a movieclip horizontally from its current slope 
+	* 			to a specified slope in a specified time and easing equation.
+	* 			Note: only movieclips that are contained by another movieclip 
+	* 			can be skewed.
+	* 			<p>
+	* 			Example 1: skew a movieclip 360 degrees horizontally in 1 second 
+	* 			using linear easing. 		
+	* 			<blockquote><pre>
+	*			new Skew(mc.inner_mc).skewHorizontal(360,1000);
+	*			</pre></blockquote>
+	* 			<p>
+	* 			Example 2: <a href="Skew_skewHorizontal_02.html">(Example .swf)</a> skews a movieclip 30 degrees horizontally first clockwise, 
+	* 			then counterclockwise, and then back to normal. Each animation takes 1 
+	* 			second using Sine easing.
+	* 			<blockquote><pre>
+	*			var mySkew:Skew = new Skew(mc.inner_mc);
+	*			mySkew.skewHorizontal(30,1000,Sine.easeInOut,"onCallback");	
+	*			myListener.onCallback = function() {		
+	*				mySkew.skewHorizontal(-30,1000,Sine.easeInOut,"onCallback2");
+	*			}
+	*			myListener.onCallback2 = function() {		
+	*				mySkew.skewHorizontal(0,1000,Sine.easeInOut);
+	*			}
+	*			</pre></blockquote>
+	* 		
+	* @usage   
+	* 		<pre>mySkew.skewHorizontal();</pre>
+	* 		<pre>mySkew.skewHorizontal(degree);</pre>
+	* 		<pre>mySkew.skewHorizontal(degree, duration);</pre>
+	*		<pre>mySkew.skewHorizontal(degree, duration, callback);</pre>
+	* 		<pre>mySkew.skewHorizontal(degree, duration, easing, callback);</pre>
+	* 		<pre>mySkew.skewHorizontal(values, duration);</pre>
+	* 		<pre>mySkew.skewHorizontal(values, duration, callback);</pre>
+	*		<pre>mySkew.skewHorizontal(values, duration, easing, callback);</pre>
+	*  	  
+	* @param degree (Number) Targeted degree to skew to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	public function skewHorizontal(Void):Void {		
+		this.type = Skew.HORIZ;
+		arguments.unshift(this.type);		
+		this.run.apply(this,arguments);
+	}
+		
+	/**
+	* @method skewVertical	 
+	* @description 	Skews a movieclip vertically from its the current slope 
+	* 			to a specified slope in a specified time and easing equation.
+	* 			Note: only movieclips that are contained by another movieclip 
+	* 			can be skewed.
+	* 			<p>
+	* 			Example 1: skew a movieclip 360 degrees vertically in 1 second 
+	* 			using linear easing. 		
+	* 			<blockquote><pre>
+	*			new Skew(mc.inner_mc).skewVertical(360,1000);
+	*			</pre></blockquote>
+	* 			<p>
+	* 			Example 2: <a href="Skew_skewVertical_02.html">(Example .swf)</a> skews a movieclip 30 degrees vertically first clockwise, 
+	* 			then counterclockwise, and then back to normal. Each animation takes 1 
+	* 			second using Sine easing.
+	* 			<blockquote><pre>
+	*			new Skew(mc.inner_mc).skewVertical(30,1000,Sine.easeInOut,"onCallback");	
+	*			myListener.onCallback = function() {		
+	*				new Skew(mc.inner_mc).skewVertical(-30,1000,Sine.easeInOut,"onCallback2");
+	*			}
+	*			myListener.onCallback2 = function() {		
+	*				new Skew(mc.inner_mc).skewVertical(0,1000,Sine.easeInOut);
+	*			}
+	*			</pre></blockquote>
+	* 		
+	* @usage   
+	* 		<pre>mySkew.skewVertical();</pre>
+	* 		<pre>mySkew.skewVertical(degree);</pre>
+	* 		<pre>mySkew.skewVertical(degree, duration);</pre>
+	*		<pre>mySkew.skewVertical(degree, duration, callback);</pre>
+	* 		<pre>mySkew.skewVertical(degree, duration, easing, callback);</pre>
+	* 		<pre>mySkew.skewVertical(values, duration);</pre>
+	* 		<pre>mySkew.skewVertical(values, duration, callback);</pre>
+	*		<pre>mySkew.skewVertical(values, duration, easing, callback);</pre>
+	*  	  
+	* @param degree (Number) Targeted degree to skew to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	public function skewVertical(Void):Void {		
+		this.type = "VERT";
+		arguments.unshift(this.type);
+		this.run.apply(this,arguments);
+	}	
+	
+	/**
+	* @method animate
+	* @description 	similar to the skewHorizontal() and skewVertical() methods. Offers start and end parameters.
+	* @usage   <pre>mySkew.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	private function getHorizontalSkew(Void):Number {
+		return this.getSkew();
+	}	
+	
+	private function setHorizontalSkew(amount:Number):Void {		
+		this.setSkew(amount, Skew.HORIZ);
+	}	
+	
+	private function getVerticalSkew(Void):Number {
+		return this.getSkew();
+	}	
+	
+	private function setVerticalSkew(amount:Number):Void {
+		this.setSkew(amount, Skew.VERT);
+	}		
+	
+	private function getSkew(Void):Number {
+		//CLUNKY
+		var skew:Number;
+		var mc:MovieClip = this.outer_mc;
+		if(mc._rotation >= 0){
+			skew = 2*(mc._rotation-45);
+		}
+		else{
+			//skew = 2*(180+mc._rotation+180-45);
+			skew = 2*(315+mc._rotation);		
+		}
+		return skew;
+	}
+	
+	private function setSkew(amount:Number, type:String):Void {
+		var h_skew:Number;
+		var v_skew:Number;
+		if(type == Skew.HORIZ) {
+			h_skew = amount;
+			v_skew = 0;	
+		}
+		else if (type == Skew.VERT) {
+			h_skew = 0;
+			v_skew = amount;			
+		}
+		var mc:MovieClip = this.outer_mc;
+		var inner_mc:MovieClip = this.mc;
+		var x0:Number = mc._x;
+		var y0:Number = mc._y;
+		var x_offset:Number = 0;
+		var y_offset:Number = 0;				
+		//nacho at yestoall.com (http://flashAPI.yestoall.com) and Andres Sebastian Yañez Duran (lifaros at yahoo.com)
+		inner_mc._x = 0.5*Math.SQRT2*(-x_offset-y_offset);
+		inner_mc._y = 0.5*Math.SQRT2*(x_offset-y_offset);
+		inner_mc._rotation = -45;
+		mc._rotation = 45+(h_skew+v_skew)/2;	
+		mc._yscale = Math.sin((90+h_skew-v_skew)*0.5*(Math.PI/180))*Math.SQRT2*100;
+		mc._xscale = Math.cos((90+h_skew-v_skew)*0.5*(Math.PI/180))*Math.SQRT2*100;
+		mc._x = x0 + x_offset;
+		mc._y = y0 + y_offset;
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>mySkew.addEventListener(event, listener);</pre>
+	* 		    <pre>mySkew.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>mySkew.removeEventListener(event, listener);</pre>
+	* 		    <pre>mySkew.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>mySkew.removeAllEventListeners();</pre>
+	* 		    <pre>mySkew.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>mySkew.eventListenerExists(event, listener);</pre>
+	* 			<pre>mySkew.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Skew";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Skew.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Timeline.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Timeline.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Timeline.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,868 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.andre_michelle.events.ImpulsDispatcher;
+
+/**
+* @class Timeline
+* @author Ralf Bokelberg, Alex Uhlmann
+* @description  There are two different ways to use Timeline for. One way is to animate 
+* 				existing movieclip timeline(s) with AnimationPackage's tween engine. This way you can 
+* 				apply easing equations to a movieclip timeline. If choosing the default time-based tweening, 
+* 				the animation is independend from the current frame rate of your movieclip timeline(s). 
+* 				See example number 1 and 2 for more information.<p>
+* 				The other way is to control existing movieclip timelines with the API of AnimationPackage. 
+* 				See example number 3 for more information about this opportunity.<p>
+* 			Example 1: 	<a href="Timeline_01.html">(Example .swf)</a>
+* 						<a href="Timeline_01.fla">(Example .fla)</a>
+* 			Animate a single movieclip timeline via AnimationPackage's tween engine. 
+* 			Animation of a movieclip that contains 50 frames of a shape tween. It starts with a rectangle 
+* 			and ends with a polygon drawn with the Flash MX 2004 IDE. It is a usual linear tween 
+* 			with a stop() action in the first frame. With Timeline we apply a Bounce easing equation to the linear 
+* 			shape tween animation inside movieclip mc.
+* 			<blockquote><pre>
+*			var myTimeline:Timeline = new Timeline(mc,0,50);
+*			myTimeline.animationStyle(2000,Bounce.easeOut);
+*			myTimeline.animate(0,100);
+*			</pre></blockquote>
+* 			You could have used <code>AnimationCore.setTweenModes(AnimationCore.FRAMES);</code> and 
+* 			a duration property of 50 to emulate a movieclip timeline animation with the same speed. 
+* 			<p>
+* 			Example 2: 	<a href="Timeline_02.html">(Example .swf)</a>
+* 						<a href="Timeline_02.fla">(Example .fla)</a>
+* 			Animate multiple movieclip timelines via AnimationPackage's tween engine.
+* 			All Movieclips have the same structure than in the example above with 50 frames and a stop() action 
+* 			in the first frame. Just the shape tween animation itself is different in some movieclips.
+* 			<blockquote><pre>
+*			var mcs:Array = new Array(top1_mc,top2_mc,top3_mc,bottom1_mc,bottom2_mc,bottom3_mc);
+*			
+*			//Two movieclips start at frame 30. This shall demonstrate 
+* 			//Timeline's consideration of different start values
+*			top1_mc.gotoAndStop(30);
+*			bottom1_mc.gotoAndStop(30);
+*			
+*			var myTimeline:Timeline = new Timeline(mcs,50);
+*			myTimeline.animationStyle(2500,Bounce.easeOut);
+*			myTimeline.addEventListener("onEnd",this);
+*			myTimeline.animate(0,100);
+*			function onEnd(e:Object) {
+*				trace("source: "+e.target+" event: "+e.type+" frame: "+e.value);
+*				new Text().setText("source: "+e.target+" event: "+e.type+" frame: "+e.value);
+*			}
+* 
+*			//pause and resume the animation in turns with each mouse click.
+*			function onMouseDown() {
+*				if(myTimeline.isTweening()){
+*					myTimeline.pause();
+*				} else {
+*					myTimeline.resume();
+*				}
+*			}
+*			</pre></blockquote>
+*			<p>
+* 			Example 3: 	<a href="Timeline_03.html">(Example .swf)</a>
+* 						<a href="Timeline_03.fla">(Example .fla)</a>
+* 			Another use of Timeline is to control movieclip timelines.
+* 			Same movieclips like in example 2. Notice that we don't use the animationStyle method here, 
+* 			because we don't want to apply an easing equation to the movieclip timelines specified in the Array mcs.
+* 			We play every movieclip timeline by its own and get all informations, including events, about them via 
+* 			the known API of AnimationPackage. The .swf plays at 31 fps.
+* 			<blockquote><pre>
+* 			//some textfields for logging event informations.
+*			var myStartText:Text = new Text();
+*			myStartText.setText("",0,0);
+*			var myUpdateText:Text = new Text();
+*			myUpdateText.setText("",0,15);
+*			var myEndText:Text = new Text();
+*			myEndText.setText("",0,30);
+*			
+*			var mcs:Array = new Array(top1_mc,top2_mc,top3_mc,bottom1_mc,bottom2_mc,bottom3_mc);
+*			
+* 			var myTimeline:Timeline = new Timeline(mcs);
+*			myTimeline.addEventListener("onStart",this);
+*			myTimeline.addEventListener("onUpdate",this);
+*			myTimeline.addEventListener("onEnd",this);
+* 
+*			//internally, this method invokes the play() method on each movieclip instance.
+* 			//you could i.e. also use stop(), gotoAndStop(), gotoAndPlay(), nextFrame(), 
+* 			//and prevFrame() via Timeline.
+*			myTimeline.play();
+*			
+*			function onStart(e:Object) {
+*				myStartText.updateText("source: "+e.target+" event: "+e.type+" frame: "+e.value+"\n");	
+*			}
+*			function onUpdate(e:Object) {
+*				myUpdateText.updateText("source: "+e.target+" event: "+e.type+" frame: "+e.value+"\n");
+*			}
+*			function onEnd(e:Object) {
+*				myEndText.updateText("source: "+e.target+" event: "+e.type+" frame: "+e.value+"\n");
+*				myTimeline.stop();
+*			}
+*			
+* 			//even if not animated via AnimationPackage's own tween engine, you're still able to stop and pause 
+* 			//the movieclip timeline(s) as you would expect with every IAnimatable instance.
+*			function onMouseDown() {
+*				if(myTimeline.isTweening()){
+*					myTimeline.pause();
+*				} else {
+*					myTimeline.resume();
+*				}
+*			}
+*			</pre></blockquote>
+* 			Notice, that if you use Timeline for controling movieclip timelines, omitting the second parameter 
+* 			like we have done in the Timeline constructor of example 3, reads the _totalframe property 
+* 			of the movieclip you want to control as end value of the animation. 
+* 			Nevertheless you could also have set a second property (amount parameter, see usage) 
+* 			as a end value or you could also have set a start and end value (value parameter, see usage) 
+* 			If no start and end values are specified, the movieclip's _currentframe and _totalframe properties 
+* 			are used as start and end values.
+*			<p>
+* 
+* 			There are many ways to use this class. One way is to specify 
+* 			the duration, easing equation and callback properties outside 
+* 			the current method, either with setting the properies directly 
+* 			or with the animationStyle() method like it is used in 
+* 			de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 4: 
+* 			<blockquote><pre>			
+*			var myTimeline:Timeline = new Timeline(mc);
+*			myTimeline.animationStyle(2000,Circ.easeIn,"onCallback");
+*			myTimeline.run(50);
+*			</pre></blockquote>  			
+* 			Example 5: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new Timeline(mc).run(50,2000,Circ.easeInOut,"onCallback");
+* 			</pre></blockquote>
+* 			Example 6: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 			
+* 			<blockquote><pre>
+* 			var myTimeline:Timeline = new Timeline(mc,0,2000,Circ.easeInOut);
+* 			myTimeline.animate(50,100);
+* 			</pre></blockquote>
+* 			Example 7: By default, the start value of your animation is the current value of your sound instance 
+* 			retrieved from getTimeline(). You can explicitly define the start values either via the setStartValue 
+* 			or run method or via the constructor. Here is one example for the constructor solution. 
+* 			This also might come in handy using composite classes, like Sequence.
+* 			<blockquote><pre>
+*			var myTimeline:Timeline = new Timeline(mc,[50,0],2000,Circ.easeIn);
+*			myTimeline.run();
+* 			</pre></blockquote>	
+* @usage 
+* 			<pre>var myTimeline:Timeline = new Timeline(mcs);</pre> 
+* 			<pre>var myTimeline:Timeline = new Timeline(mcs, amount, duration, callback);</pre> 
+* 			<pre>var myTimeline:Timeline = new Timeline(mcs, amount, duration, easing, callback);</pre>
+*			<pre>var myTimeline:Timeline = new Timeline(mcs, values);</pre> 
+* 			<pre>var myTimeline:Timeline = new Timeline(mcs, values, duration, callback);</pre> 
+* 			<pre>var myTimeline:Timeline = new Timeline(mcs, values, duration, easing, callback);</pre>      
+* 			<pre>var myTimeline:Timeline = new Timeline(mc);</pre> 
+* 			<pre>var myTimeline:Timeline = new Timeline(mc, amount, duration, callback);</pre> 
+* 			<pre>var myTimeline:Timeline = new Timeline(mc, amount, duration, easing, callback);</pre>
+*			<pre>var myTimeline:Timeline = new Timeline(mc, values);</pre> 
+* 			<pre>var myTimeline:Timeline = new Timeline(mc, values, duration, callback);</pre> 
+* 			<pre>var myTimeline:Timeline = new Timeline(mc, values, duration, easing, callback);</pre> 
+* @param mc (MovieClip) Movieclip to animate.
+* @param mcs (Array) array of movieclips to animate.
+* @param amount (Number) Targeted frames to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Timeline 
+											extends AnimationCore 
+											implements ISingleAnimatable {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property movieclip (MovieClip) Movieclip to animate.
+	* @property movieclips (Array) Array of Movieclips to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	private var myTLs:Array;
+	
+	public function Timeline() {
+		super();
+		if(typeof(arguments[0]) == "movieclip") {
+			this.mc = arguments[0];
+		} else {
+			this.mcs = arguments[0];
+			var myTLs:Array = [];
+			var len:Number = this.mcs.length;
+			var mcs:Array = this.mcs;
+			var i:Number = len;
+			while(--i>-1) {
+				myTLs[i] = new Timeline(mcs[i]);
+			}
+			this.myTLs = myTLs;
+		}
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		} else {
+			this.init(this.getTotalFrames());
+		}
+	}
+	
+	private function init():Void {
+		if(arguments.length > 0) {
+			super.init.apply(this, arguments);
+			var len:Number = this.mcs.length;
+			var i:Number = len;
+			while(--i>-1) {
+				if(this.startValue == null) {
+					this.myTLs[i].setStartValue(this.startValue, true);
+				} else {
+					this.myTLs[i].setStartValue(this.startValue);
+				}
+				this.myTLs[i].setEndValue(this.endValue);
+			}
+		} else {
+			super.init(this.getTotalFrames());
+		}		
+	}
+	
+	private function initAnimation(amount:Number, duration:Number, easing:Object, callback:String):Void {		
+		if (arguments.length > 1) {		
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}		
+		if(this.mc != null) {
+			this.setStartValue(this.mc._currentframe, true);
+		}
+		this.setEndValue(amount);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		this.roundResult(true);
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = [this.endValue];
+		
+		if(this.mc != null) {
+			this.myAnimator.start = [this.startValue];
+			this.myAnimator.setter = [[this,"gotoAndStopMCAnimator"]];
+		} else {					
+			this.myAnimator.multiStart = ["getCurrentFrame"];										
+			this.myAnimator.multiSetter = [[this.myTLs,"gotoAndStopMCAnimator"]];
+		}
+	
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}		
+	}
+	
+	/**
+	* @method run
+	* @description  Notice that this method only makes sense if Timeline is used for animating 
+	* 				and not only for controling movieclip timelines. See class documentation.
+	* @usage   
+	* 		<pre>myInstance.run();</pre>
+	* 		<pre>myInstance.run(amount);</pre>
+	* 		<pre>myInstance.run(amount, duration);</pre>
+	*		<pre>myInstance.run(amount, duration, callback);</pre>
+	* 		<pre>myInstance.run(amount, duration, easing, callback);</pre>
+	* 		<pre>myInstance.run(values, duration);</pre>
+	* 		<pre>myInstance.run(values, duration, callback);</pre>
+	*		<pre>myInstance.run(values, duration, easing, callback);</pre>
+	* 	  
+	* @param amount (Number) Targeted frames to animate to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* 				Notice that this method only makes sense if Timeline is used for animating 
+	* 				and not only for controling movieclip timelines. See class documentation.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* 				Notice that this method only makes sense if Timeline is used for animating 
+	* 				and not only for controling movieclip timelines. See class documentation.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 			Notice that this method only makes sense if Timeline is used for animating 
+	* 			and not only for controling movieclip timelines. See class documentation.
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	private function gotoAndStopMCAnimator(frame:Number):Void {	
+		if(this.mc._currentframe != frame) {
+			this.mc.gotoAndStop(frame);
+		}
+	}
+	
+	private function gotoAndStopMC(frame:Number):Void {	
+		this.mc.gotoAndStop(frame);
+		this.checkFrame();
+	}	
+	
+	private function gotoAndPlayMC(frame:Number):Void {	
+		this.mc.gotoAndPlay(frame);
+		this.checkFrame();
+		ImpulsDispatcher.addImpulsListener(this, "checkFrame");
+	}
+	
+	private function playMC(Void):Void {	
+		this.mc.play();
+		this.checkFrame();
+		ImpulsDispatcher.addImpulsListener(this, "checkFrame");
+	}
+	
+	private function stopMC(Void):Void {	
+		this.mc.stop();
+		this.checkFrame();
+	}
+	
+	private function nextFrameMC(Void):Void {	
+		this.mc.nextFrame();
+		this.checkFrame();
+	}
+	
+	private function prevFrameMC(Void):Void {	
+		this.mc.prevFrame();
+		this.checkFrame();
+	}	
+
+	private function checkFrame(Void):Void {
+		var c:Number = this.getCurrentFrame();
+		if(c == this.currentValue) {
+			if(c == this.getEndValue() || c == this.getStartValue()) {
+				ImpulsDispatcher.removeImpulsListener(this);
+				return;
+			}
+		}
+		this.currentValue = c;
+		var t:Number = this.getEndValue();
+		if(c == this.getStartValue()) {
+			this.tweening = true;			
+			this.dispatchEvent({type:"onStart", value:c});
+		} else if(c == t) {
+			this.tweening = false;
+			this.dispatchEvent({type:"onEnd", value:c});
+		} else {
+			this.dispatchEvent({type:"onUpdate", value:c});
+		}
+	}
+	
+	/**
+	* @method gotoAndPlay
+	* @description 	invokes gotoAndPlay on movieclip timeline(s).
+	* @usage   <pre>myInstance.gotoAndPlay(frame);</pre> 	  
+	* @param frame (Number)
+	* @return void
+	*/
+	public function gotoAndPlay(frame:Number):Void {	
+		if(this.mc != null) {
+			this.gotoAndPlayMC(frame);
+		} else {
+			this.myTLs[0].addEventListener("onStart", this);
+			this.myTLs[0].addEventListener("onUpdate", this);
+			this.myTLs[0].addEventListener("onEnd", this);
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				this.myTLs[i].gotoAndPlay(frame);
+			}			
+		}
+	}
+	
+	/**
+	* @method gotoAndStop
+	* @description 	invokes gotoAndStop on movieclip timeline(s).
+	* @usage   <pre>myInstance.gotoAndStop(frame);</pre> 	  
+	* @param frame (Number)
+	* @return void
+	*/
+	public function gotoAndStop(frame:Number):Void {		
+		if(this.mc != null) {
+			this.gotoAndStopMC(frame);
+		} else {
+			this.myTLs[0].addEventListener("onStart", this);
+			this.myTLs[0].addEventListener("onUpdate", this);
+			this.myTLs[0].addEventListener("onEnd", this);			
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				this.myTLs[i].gotoAndStop(frame);
+			}
+		}
+	}
+	
+	/**
+	* @method play
+	* @description 	invokes play on movieclip timeline(s).
+	* @usage   <pre>myInstance.play();</pre>
+	* @return void
+	*/
+	public function play(Void):Void {	
+		if(this.mc != null) {
+			this.playMC();			
+		} else {
+			this.myTLs[0].addEventListener("onStart", this);
+			this.myTLs[0].addEventListener("onUpdate", this);
+			this.myTLs[0].addEventListener("onEnd", this);
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				this.myTLs[i].play();
+			}			
+		}
+	}
+	
+	/**
+	* @method nextFrame
+	* @description 	invokes nextFrame on movieclip timeline(s).
+	* @usage   <pre>myInstance.nextFrame();</pre>
+	* @return void
+	*/
+	public function nextFrame(Void):Void {	
+		if(this.mc != null) {
+			this.nextFrameMC();
+		} else {
+			this.myTLs[0].addEventListener("onStart", this);
+			this.myTLs[0].addEventListener("onUpdate", this);
+			this.myTLs[0].addEventListener("onEnd", this);
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				this.myTLs[i].nextFrame();
+			}			
+		}
+	}
+	
+	/**
+	* @method prevFrame
+	* @description 	invokes prevFrame on movieclip timeline(s).
+	* @usage   <pre>myInstance.prevFrame();</pre>
+	* @return void
+	*/
+	public function prevFrame(Void):Void {	
+		if(this.mc != null) {
+			this.prevFrameMC();
+		} else {
+			this.myTLs[0].addEventListener("onStart", this);
+			this.myTLs[0].addEventListener("onUpdate", this);
+			this.myTLs[0].addEventListener("onEnd", this);
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				this.myTLs[i].prevFrame();
+			}			
+		}
+	}
+	
+	public function getStartFrame(Void):Number {
+		return 1;
+	}
+	
+	/**
+	* @method getCurrentFrame
+	* @description asked the timeline movieclip mc for its _currentframe property. In case 
+	* 				an Array of movieclips was specified, only the first element will be asked.
+	* @usage   <pre>myInstance.getCurrentFrame();</pre> 	  
+	* @return Number, number of frames that mc contains.
+	*/
+	public function getCurrentFrame(Void):Number {
+		if(this.mc != null) {
+			return this.mc._currentframe;
+		} else {					
+			return this.mcs[0]._currentframe;	
+		}		
+	}
+	
+	/**
+	* @method getTotalFrames
+	* @description asked the timeline movieclip mc for its _totalframes property. 
+	* 			 In case an Array of movieclips was specified, only the first element will be asked.
+	* @usage   <pre>myInstance.getTotalFrames();</pre> 	  
+	* @return Number, number of frames that mc contains.
+	*/
+	public function getTotalFrames(Void):Number {
+		if(this.mc != null) {
+			return this.mc._totalframes;
+		} else {
+			return this.mcs[0]._totalframes;	
+		}
+	}
+	
+	private function onStart(e:Object):Void {
+		this.tweening = true;
+		this.startValue = e.value;
+		this.dispatchEvent({type:e.type, value:e.value});
+	}
+	
+	private function onUpdate(e:Object):Void {
+		this.currentValue = e.value;
+		this.dispatchEvent({type:e.type, value:e.value});
+	}
+	
+	private function onEnd(e:Object):Void {
+		this.tweening = false;
+		this.endValue = e.value;
+		APCore.broadcastMessage(this.callback, this, e.value);
+		this.dispatchEvent({type:e.type, value:e.value});			
+	}
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked.
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	public function stop(Void):Boolean {
+		if(this.mc != null) {
+			this.stopMC();
+			return super.stop();
+		} else {
+			this.myTLs[0].addEventListener("onStart", this);
+			this.myTLs[0].addEventListener("onUpdate", this);
+			this.myTLs[0].addEventListener("onEnd", this);			
+			var len:Number = this.mcs.length;	
+			var i:Number = len;
+			while(--i>-1) {
+				this.myTLs[i].stop();
+			}			
+		}
+	}	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	public function pause(duration:Number):Boolean {
+		if(this.myAnimator == null) {
+			this.stop();
+			return super.pause(duration);
+		} else {
+			return super.pause(duration);
+		}
+	}	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	public function resume(Void):Boolean {
+		if(this.myAnimator == null) {
+			this.play();
+			return super.resume();
+		} else {
+			return super.resume();
+		}
+	}
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	public function setStartValue(startValue:Number, optional:Boolean):Boolean {
+		startValue = Math.round(startValue);
+		if(optional != true) {
+			this.mc.gotoAndStop(startValue);
+		}
+		return super.setStartValue(startValue, optional);		
+	}
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	public function setEndValue(endValue:Number):Boolean {
+		endValue = Math.round(endValue);
+		return super.setEndValue(endValue);				
+	}
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	public function getDurationElapsed(Void):Number {		
+		if(this.myAnimator == null) {
+			return this.currentValue;
+		} else {
+			return super.getDurationElapsed();
+		}
+	}	
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	public function getDurationRemaining(Void):Number {		
+		if(this.myAnimator == null) {
+			return this.endValue - this.currentValue;
+		} else {
+			return super.getDurationRemaining();
+		}
+	}	
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Timeline";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Timeline.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Trail.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Trail.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Trail.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,406 @@
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.animation.Alpha;
+
+/**
+* @class Trail
+* @author Alex Uhlmann
+* @description  Simulates a trail effect on animated movieclips. Attaches the trail to a movieclip. 
+* 			If null is specified the animation will be infinite.
+* 			<p> 
+* 			Example 1: <a href="Trail_attach_01.html">(Example .swf)</a> Attach a small trail to a back and forth moving movieclip. The trail will expire in 10 seconds.
+* 			<blockquote><pre>			
+*			mc._x = 150;
+*			mc._y = 200;
+*			var myMove:Move = new Move(mc);
+*			myMove.animationStyle(2000,Expo.easeInOut,"onCallback");
+*			myMove.run(500,mc._y);
+*			new Trail(mc).attach(50,40,10000);
+*			myListener.onCallback = function()
+*			{
+*				myMove.callback = "onCallback2";
+*				myMove.run(150,mc._y);
+*			}
+*			myListener.onCallback2 = function()
+*			{	
+*				myMove.callback = "onCallback";	
+*				myMove.run(500,mc._y);
+*			}
+*			</pre></blockquote>  			
+* 			Example 2: <a href="Trail_attach_02.html">(Example .swf)</a> attaches a longer trail to a rotating movieclip. Note: if no duration property is 
+* 			specified, the default duration property is used. The default property of duration is 1000. See AnimationCore.
+* 			<blockquote><pre>	
+* 			new Rotation(mc).run(360);
+*			new Trail(mc).attach(250,40);
+* 			</pre></blockquote>
+* 			Take a look to MoveOnCurve for another example.
+* 			<p>		
+* 			There are two ways to use this class. One way is to specify 
+* 			the duration property outside the current method, 
+* 			either with setting the property directly 
+* 			or with the animationStyle() method like it is used in 
+* 			de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+*		
+* @usage <tt>var myTrail:Trail = new Trail(mc);</tt> 
+* @param mc (MovieClip) Movieclip to simulate a trail effect on.
+*/
+class de.alex_uhlmann.animationpackage.animation.Trail 
+												extends AnimationCore {	
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip to simulate a trail effect on.
+	* @property duration (Number) Duration of animation in milliseconds.
+	*/
+	private static var refs:Object;
+	private var instancesArr:Array;
+	private var startTime:Number;
+	private var startPause:Number;
+	private var durationPaused:Number = 0;
+	private var elapsedDuration:Number = 0;
+	private var paused:Boolean = false;
+	private var stopped:Boolean = false;
+	private var finished:Boolean = false;	
+	private var interval_ID:Number;
+	private var interval_ID2:Number;
+	private var decay:Number;
+	private var startAlpha:Number;
+	private var durationOrig:Number;
+	private var p:Array;
+	private var v:Array;
+	
+	public function Trail(mc:MovieClip) {
+		super();
+		this.mc = mc;
+		/*don't let the garbage collector delete the instance if invoked only via constructor. Save a reference.*/
+		if(Trail.refs == null) {
+			Trail.refs = new Object();
+		}
+		Trail.refs[this.getID()] = this;
+	}	
+	
+	/**
+	* @method attach
+	* @description  		
+	* @usage 	<pre>myTrail.attach(decay, startAlpha);</pre>
+	*		<pre>myTrail.attach(decay, startAlpha, milliseconds);</pre>
+	* 	  
+	* @param decay (Number) fade out time in milliseconds or frames.
+	* @param startAlpha (Number) the _alpha value the dublicated instances shall start to fade out.
+	* @param milliseconds (Number) Duration of animation in milliseconds. If null is specified the animation will be infinite.
+	* @return void
+	*/
+	/*It isn't possible to duplicate textfields and container mc's.*/
+	public function attach(decay:Number, startAlpha:Number, 
+						   milliseconds:Number):Void {
+							   
+		var paramLen:Number = 2;
+		if (arguments.length > paramLen) {
+			if(milliseconds !== null) {
+				this.animationStyle(milliseconds);
+			} else {
+				this.duration = null;
+			}
+		} else {
+			this.animationStyle();
+		}
+		this.tweening = true;
+		this.finished = false;
+
+		this.startTime = getTimer();	
+		this.instancesArr = new Array();
+		this.p = ["_rotation", "_xscale", "_yscale", "_x", "_y"];
+		this.v = [this.mc._rotation, this.mc._xscale, this.mc._yscale, this.mc._x, this.mc._y];
+		this.decay = decay;
+		this.startAlpha = startAlpha;
+		this.dispatchEvent.apply(this, [ {type:"onStart"} ]);
+		
+		this.interval_ID = setInterval(this, "run", 10, this.mc, decay, startAlpha, this.p, this.v);
+		
+		if(this.duration != null) {
+			this.interval_ID2 = setInterval(this, "remove", this.duration);
+		}		
+		this.durationOrig = this.duration;
+	}
+	
+	private function run():Void {
+		
+		var mc:MovieClip = arguments[0];
+		var decay:Number = arguments[1];
+		var startAlpha:Number = arguments[2];
+		var p:Array = arguments[3];
+		var v:Array = arguments[4];
+		var i:Number = 5;
+		while(--i>-1) {
+			if (v[i] != mc[p[i]]) {		
+				/*Flash Player 7 feature disabled*/
+				//dp = loc_mc._parent.getNextHighestDepth();	
+				var dp:Number = this.getNextDepth(mc._parent);				
+				var targ:MovieClip = mc.duplicateMovieClip("apBlur"+dp+"_mc", dp);	
+				targ._alpha = startAlpha;
+				var myAlpha:Alpha = new Alpha(targ, 0, decay);
+				this.instancesArr.push(myAlpha);
+				myAlpha.addEventListener("onEnd", this);
+				myAlpha.animate(0, 100);
+				break;
+			}
+		}
+		this.v = [mc._rotation, mc._xscale, mc._yscale, mc._x, mc._y];
+		updateAfterEvent();
+	}	
+	
+	/**
+	* @method remove
+	* @description 	offers the opportunity to remove an attached Trail. In particular, this might be 
+	* 				useful if a trail is of infinite length (if null is specified for milliseconds).
+	* @usage   <pre>myInstance.remove();</pre> 	  
+	* @return void
+	*/	
+	public function remove(Void):Void {
+		this.tweening = false;
+		this.finished = true;		
+		this.dispatchEvent.apply(this, [ {type:"onEnd", target:this} ]);
+		clearInterval(this.interval_ID);
+		clearInterval(this.interval_ID2);
+		delete Trail.refs[this.getID()];
+	}	
+	
+	public function onEnd(eventObj:Object):Void {		
+		eventObj.target.movieclip.removeMovieClip();
+		this.instancesArr.shift();
+		delete eventObj.target;		
+	}
+	
+	public function stop(Void):Boolean {		
+		if(this.locked == false && this.tweening == true) {
+			this.tweening = false;		
+			this.stopped = true;
+			this.elapsedDuration = this.computeElapsedDuration();
+			var i:Number;
+			var len:Number = this.instancesArr.length;		
+			for (i=0; i<len; i++) {			
+				this.instancesArr[i].stop();			
+			}
+			clearInterval(this.interval_ID);
+			clearInterval(this.interval_ID2);
+			return true;
+		} else {
+			return false;
+		}
+	}
+		
+	public function pause(duration:Number):Boolean {	
+		if(this.locked == false && this.tweening == true) {
+			this.tweening = false;
+			this.paused = true;
+			this.elapsedDuration = this.computeElapsedDuration();
+			this.startPause = getTimer();
+			var i:Number;
+			var len:Number = this.instancesArr.length;			
+			for (i=0; i<len; i++) {
+				this.instancesArr[i].pause();
+			}
+			clearInterval(this.interval_ID);
+			clearInterval(this.interval_ID2);
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+	public function resume(Void):Boolean {		
+		if(this.locked == false && this.paused == true) {
+			this.tweening = true;
+			this.paused = false;
+			var i:Number;
+			var len:Number = this.instancesArr.length;		
+			for (i=0; i<len; i++) {
+				this.instancesArr[i].resume();	
+			}			
+			this.durationPaused += getTimer() - this.startPause;
+			this.interval_ID = setInterval(this, "run", 10, this.mc, this.decay, this.startAlpha, this.p, this.v);
+			if(this.duration != null) {
+				this.duration -= this.elapsedDuration;				
+				this.interval_ID2 = setInterval(this, "remove", this.duration);				
+			}
+			return true;
+		} else {
+			return false;
+		}
+	}
+		
+	public function getDurationElapsed(Void):Number {		
+		if(this.paused == true || this.stopped == true) {
+			return this.elapsedDuration;
+		} else {
+			return this.computeElapsedDuration();
+		}
+	}
+	
+	public function getDurationRemaining(Void):Number {
+		var r:Number;
+		if(this.stopped == false) {
+			r = this.durationOrig - this.getDurationElapsed();
+			if(r < 0) {
+				r = 0;
+			}
+		} else {
+			r = 0;
+		}
+		if(isNaN(r)) {			
+			r = Infinity;
+		} 
+		return r;
+	}
+	
+	private function computeElapsedDuration(Void):Number {
+		if(this.finished == true) {
+			return this.durationOrig;
+		} else {		
+			return getTimer() - this.startTime - this.durationPaused;			
+		}
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set animation setting for animation.
+	* 		
+	* @usage   <pre>myTrail.animationStyle(milliseconds);</pre>
+	* 	  
+	* @param milliseconds (Number) Duration of animation in milliseconds.	
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time in milliseconds since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time in milliseconds since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myTrail.addEventListener(event, listener);</pre>
+	* 		    <pre>myTrail.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myTrail.removeEventListener(event, listener);</pre>
+	* 		    <pre>myTrail.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myTrail.removeAllEventListeners();</pre>
+	* 		    <pre>myTrail.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myTrail.eventListenerExists(event, listener);</pre>
+	* 			<pre>myTrail.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Trail";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Trail.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Volume.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Volume.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Volume.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,486 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Volume
+* @author Ralf Bokelberg, Alex Uhlmann
+* @description  Manipulates the volume of a Sound instance or a number of sound instances. 
+* 			You have to create the Sound instance manually. 
+* 			Take a look into your Flash manual for more information about the Sound class. 
+* 			You have to pass the sound instance to the Volume class to fade your sound. 
+* 			Here is one example how you could create a Sound instance:
+* 			<p>
+* 			<blockquote><pre>			
+*			var mySound:Sound = new Sound(this);
+*			mySound.attachSound("mySoundID");
+*			mySound.setVolume(0);
+*			mySound.start();
+*			</pre></blockquote> 
+* 			<p>
+* 			Example 1: fade in to full volume (100) in 2 seconds using Quad easing and a callback.
+* 			<blockquote><pre>			
+*			var myVolume:Volume = new Volume(mySound);
+*			myVolume.animationStyle(2000,Quad.easeIn,"onCallback");
+*			myVolume.run(100);
+*			</pre></blockquote>
+* 			Note that you could do the same via the SingleAnimator class with almost the same API. See SingleAnimator.
+* 			<p> 
+* 			There are many ways to use this class. One way is to specify 
+* 			the duration, easing equation and callback properties outside 
+* 			the current method, either with setting the properies directly 
+* 			or with the animationStyle() method like it is used in 
+* 			de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 2: 
+* 			<blockquote><pre>			
+*			var myVolume:Volume = new Volume(mySound);
+*			myVolume.animationStyle(2000,Quad.easeIn,"onCallback");
+*			myVolume.run(100);
+*			</pre></blockquote>  			
+* 			Example 3: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new Volume(mySound).run(100,2000,Circ.easeInOut,"onCallback");
+* 			</pre></blockquote>
+* 			Example 4: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 			
+* 			<blockquote><pre>
+* 			var myVolume:Volume = new Volume(mySound,0,2000);
+* 			myVolume.animate(0,100);
+* 			</pre></blockquote>
+* 			Example 5: By default, the start value of your animation is the current value of your sound instance 
+* 			retrieved from getVolume(). You can explicitly define the start values either via the setStartValue 
+* 			or run method or via the constructor. Here is one example for the constructor solution. 
+* 			This also might come in handy using composite classes, like Sequence.
+* 			<blockquote><pre>
+*			var myVolume:Volume = new Volume(mySound,[90,270],2000,Circ.easeIn);
+*			myVolume.run();
+* 			</pre></blockquote>
+* @usage      
+* 			<pre>var myVolume:Volume = new Volume(mySound);</pre> 
+* 			<pre>var myVolume:Volume = new Volume(mySound, amount, duration, callback);</pre> 
+* 			<pre>var myVolume:Volume = new Volume(mySound, amount, duration, easing, callback);</pre>
+*			<pre>var myVolume:Volume = new Volume(mySound, values);</pre> 
+* 			<pre>var myVolume:Volume = new Volume(mySound, values, duration, callback);</pre> 
+* 			<pre>var myVolume:Volume = new Volume(mySound, values, duration, easing, callback);</pre>
+* 			<pre>var myVolume:Volume = new Volume(mySounds);</pre> 
+* 			<pre>var myVolume:Volume = new Volume(mySounds, amount, duration, callback);</pre> 
+* 			<pre>var myVolume:Volume = new Volume(mySounds, amount, duration, easing, callback);</pre>
+*			<pre>var myVolume:Volume = new Volume(mySounds, values);</pre> 
+* 			<pre>var myVolume:Volume = new Volume(mySounds, values, duration, callback);</pre> 
+* 			<pre>var myVolume:Volume = new Volume(mySounds, values, duration, easing, callback);</pre>  
+* @param mySound (Sound) Sound instance to animate.
+* @param mySounds (Array) array of Sound instances to animate.
+* @param amount (Number) Targeted volume to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.animation.Volume 
+											extends AnimationCore 
+											implements ISingleAnimatable,
+													IMultiAnimatable {
+	
+	/*animationStyle properties inherited from AnimationCore*/
+	/** 
+	* @property sound (Sound) Sound instance to animate.
+	* @property sounds (Array) Array of Sound instances to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	
+	private var mySound:Sound;
+	private var mySounds:Array;
+	
+	public function Volume() {
+		super();
+		if(arguments[0] instanceof Sound) {
+			this.mySound = arguments[0];
+		} else {
+			this.mySounds = arguments[0];
+		}		
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function initAnimation(amount:Number, duration:Number, easing:Object, callback:String):Void {		
+		if (arguments.length > 1) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		if(this.mySound != null) {
+			this.setStartValue(this.mySound.getVolume(), true);		
+		}		
+		this.setEndValue(amount);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		this.roundResult(true);
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.end = [this.endValue];
+		
+		if(this.mySound != null) {
+			this.myAnimator.start = [this.startValue];
+			this.myAnimator.setter = [[this.mySound,"setVolume"]];
+		} else {			
+			this.myAnimator.multiStart = ["getVolume"];										
+			this.myAnimator.multiSetter = [[this.mySounds,"setVolume"]];			
+		}		
+
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+
+	/**
+	* @method run
+	* @description 		
+	* @usage   
+	* 		<pre>myVolume.run();</pre>
+	* 		<pre>myVolume.run(amount);</pre>
+	* 		<pre>myVolume.run(amount, duration);</pre>
+	*		<pre>myVolume.run(amount, duration, callback);</pre>
+	* 		<pre>myVolume.run(amount, duration, easing, callback);</pre>
+	* 		<pre>myVolume.run(values, duration);</pre>
+	* 		<pre>myVolume.run(values, duration, callback);</pre>
+	*		<pre>myVolume.run(values, duration, easing, callback);</pre>
+	* 	  
+	* @param amount (Number) Targeted volume to animate to.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/
+
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myVolume.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	public function get sound():Sound {
+		return this.mySound;
+	}
+	
+	public function set sound(mySound:Sound):Void {
+		this.mySound = mySound;
+	}
+	
+	public function get sounds():Array {
+		return this.mySounds;
+	}
+	
+	public function set sounds(mySounds:Array):Void {
+		this.mySounds = mySounds;
+	}	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Volume";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/animation/Volume.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Arc.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Arc.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Arc.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,800 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Arc
+* @author Alex Uhlmann
+* @description Arc is a class for drawing regular and elliptical arc segments 
+* 			and pie shaped wedges. Very useful for creating charts. Similar to 
+* 			java.awt.geom.Arc2D you can specify the closure type of the arc. 
+* 			Available closure types are: 
+* 			<blockquote><pre>
+* 			OPEN = The closure type for an open arc with no path segments connecting the two ends of the arc segment.  
+* 			CHORD = The closure type for an arc closed by drawing a straight line segment from the start of the arc segment to the end of the arc segment. 
+* 			PIE = The closure type for an arc closed by drawing straight line segments from the start of the arc segment to the center of the full ellipse and from that point to the end of the arc segment. 
+* 			Default closure type is CHORD.
+* 			</pre></blockquote>
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: <a href="Arc_01.html">(Example .swf)</a> draw a 3/4 arc with default parameters.		
+* 			<blockquote><pre>
+*			var myArc:Arc = new Arc(275,200);
+*			myArc.setEndValue(270);
+* 			myArc.draw();
+*			</pre></blockquote> 
+* 			Example 2: <a href="Arc_02.html">(Example .swf)</a> draw an open arc, and animate it.		
+* 			<blockquote><pre>
+*			var myArc:Arc = new Arc(275,200);
+*			myArc.lineStyle(0x000000);
+*			myArc.fillStyle(0xff0000);
+*			myArc.setArcType("OPEN");
+*			myArc.setStartValue(0);
+*			myArc.setEndValue(270);
+*			myArc.animate(0,100);
+*			</pre></blockquote> 			
+* 			Example 3: <a href="Arc_03.html">(Example .swf)</a> draw an arc with custom parameters. 
+* 			<blockquote><pre>
+*			var myArc:Arc = new Arc(275,200,200,0,270,"PIE");			
+*			myArc.lineStyle(15,0xff0000,50);
+*			myArc.fillStyle(0xff0000,50);
+*			myArc.draw();
+*			</pre></blockquote>
+* 			Example 4: <a href="Arc_04.html">(Example .swf)</a> draw an animated wedge with custom parameters, that 
+* 			continues to animated to full size and back.
+* 			<blockquote><pre>
+*			var myArc:Arc = new Arc(275,200,150,0,270);	
+*			myArc.setArcType("PIE");
+*			myArc.lineStyle(2,0xff0000,50);
+*			myArc.fillStyle(0xffff00,100);
+*			myArc.animationStyle(2000,Sine.easeInOut,"onCallback");			
+*			myArc.animate(0,100);
+*			myListener.onCallback = function(source, value)
+*			{			
+*				if(value == 270) {
+*					myArc.animate(100,0);
+*				} else {
+*					myArc.animate(0,100);
+*				}	
+*			}
+*			</pre></blockquote> 
+* @usage   <pre>var myArc:Arc = new Arc();</pre> 
+* 		<pre>var myArc:Arc = new Arc(x, y, radius, start, end, type);</pre>
+* 		<pre>var myArc:Arc = new Arc(mc, x, y, radius, start, end, type);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param radius (Number) Radius of the drawing.
+* @param start (Number) The starting angle of the arc in degrees.
+* @param end (Number) The angular extent of the arc in degrees.
+* @param type (String) The String constant that represents the closure type of this arc: OPEN, CHORD, or PIE. 
+*/
+class de.alex_uhlmann.animationpackage.drawing.Arc 
+										extends Shape 
+										implements IDrawable, 
+												ISingleAnimatable {	
+
+	/*static default properties*/	
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/
+	/*animationStyle properties inherited from APCore*/	
+	/**	
+	* @property radius_def (Number)(static) default property. Radius of the drawing. Defaults to 100.
+	* @property start_def (Number)(static) default property. Specifies the size of the drawing to begin with (in degrees). Negative values draw clockwise. Defaults to 0.
+	* @property end_def (Number)(static) default property. Specifies the size of the drawing to draw to (in degrees). Negative values draw clockwise. Defaults to 360.
+	* @property type_def (Number)(static) default property. Default closure type of arc is CHORD.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.
+	* 
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/	
+	public static var radius_def:Number = 100;
+	public static var start_def:Number = 0;
+	public static var end_def:Number = 360;
+	public static var type_def:String = "CHORD";	
+	private var x:Number = 0;
+	private var y:Number = 0;
+	private var radius:Number;
+	private var start:Number;
+	private var end:Number;
+	private var type:String;
+	
+	public function Arc() {
+		super();
+		this.init.apply(this,arguments);
+		this.fillStyle(null);
+		this.animationStyle();
+	}	
+	
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, radius:Number, 
+					start:Number, end:Number, type:String):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:x, y:y});
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, radius:Number, 
+					start:Number, end:Number, type:String):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x:Number, y:Number, radius:Number, 
+					start:Number, end:Number, type:String):Void {
+	
+		this.radius = (radius == null) ? Arc.radius_def : radius;
+		this.start = (start == null) ? Arc.start_def : start;
+		this.end = (end == null) ? Arc.end_def : end;
+		this.type = (type == null) ? Arc.type_def : type;
+		if(this.type == "PIE") {
+			this.x = 0;
+		} else {
+			this.x = this.radius;		
+		}
+		this.setStartValue(this.start);
+		this.setEndValue(this.end);
+	}
+	
+	/**
+	* @method draw
+	* @description 	Draws regular and elliptical arc segments.		
+	* @usage <pre>myArc.draw();</pre>
+	*/
+
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/
+
+	private function invokeAnimation(start:Number, end:Number):Void {
+		this.startInitialized = false;
+		
+		var goto:Boolean;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;			
+		} else {
+			goto = false;
+		}
+
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [this.startValue];
+		this.myAnimator.end = [this.endValue];
+		this.myAnimator.setter = [[this, "drawShape"]];
+		if(goto == false) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(end);
+		}
+	}
+	
+	public function setStartValue(startValue:Number, optional:Boolean):Boolean {
+		this.start = startValue;
+		return super.setStartValue(startValue);
+	}
+	
+	public function setEndValue(endValue:Number):Boolean {
+		this.end = endValue;
+		return super.setEndValue(endValue);
+	}
+	
+	/**
+	* @method animate
+	* @description 	Draws the animated segments.		
+	* @usage  	<pre>myArc.animate(start, end);</pre>  
+	* @param start (Number) Specifies the size of the drawing to begin with (in degrees). Negative values draw clockwise.
+	* @param end (Number) Specifies the size of the drawing to draw to (in degrees). Negative values draw clockwise.
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	public function drawShape(v:Number):Void {
+		this.clearDrawing();
+		this.end = v;
+		this.drawNew();
+	}
+
+	/**
+	* @method getRadius
+	* @description 	Returns the radius.
+	* @usage  <pre>myArc.getRadius();</pre>
+	* @return Number that represents the radius in pixels. 
+	*/	
+	public function getRadius(Void):Number {		
+		return this.radius;		
+	}
+		
+	/**
+	* @method setRadius
+	* @description 	Sets the radius of the drawing.		
+	* 		
+	* @usage   <pre>myArc.setRadius(radius);</pre>
+	* 	  
+	* @param radius (Number) radius in pixels.
+	*/	
+	public function setRadius(radius:Number):Void {	
+		this.radius = radius;		
+	}
+	
+	/**
+	* @method getAngleStart
+	* @description deprecated. Use getStartValue instead.
+	* @usage  <pre>myArc.getAngleStart();</pre>
+	* @return Number
+	*/
+	public function getAngleStart(Void):Number {
+		return this.start;		
+	}
+	
+	/**
+	* @method setAngleStart
+	* @description deprecated. Use setStartValue instead.
+	* @usage  <pre>myArc.setAngleStart(startAngle);</pre>
+	* @param startAngle Number
+	*/
+	public function setAngleStart(startAngle:Number):Void {
+		this.start = startAngle;
+		this.setStartValue(startAngle);
+	}	
+	
+	/**
+	* @method getAngleExtent
+	* @description 	deprecated. Use getEndValue instead. Returns the angular extent of the arc.
+	* @usage  <pre>myArc.getAngleExtent();</pre>
+	* @return Number that represents the angular extent of the arc in degrees.
+	*/
+	public function getAngleExtent(Void):Number {
+		return this.end;		
+	}	
+	
+	/**
+	* @method setAngleExtent
+	* @description 	deprecated. Use setEndValue instead. Sets the angular extent of this arc to the specified value.
+	* @usage  <pre>myArc.setAngleExtent(angExt);</pre>
+	* @param angExt Number The angular extent of the arc in degrees.
+	*/
+	public function setAngleExtent(angExt:Number):Void {
+		this.end = angExt;	
+		this.setEndValue(angExt);
+	}
+	
+	/**
+	* @method getArcType
+	* @description 	Returns the arc closure type of the arc: OPEN, CHORD, or PIE. See class description.
+	* @usage  <pre>myArc.getArcType();</pre>
+	* @return String of the constant closure type defined in this class.
+	*/
+	public function getArcType(Void):String {
+		return this.type;		
+	}
+	
+	/**
+	* @method setArcType
+	* @description 	Sets the closure type of this arc to the specified value: OPEN, CHORD, or PIE. See class description.
+	* @usage  <pre>myArc.setArcType(type);</pre>
+	* @param type (String) The String constant that represents the closure type of this arc: OPEN, CHORD, or PIE. 
+	*/	
+	public function setArcType(type:String):Void {		
+		if(type == "PIE") {			
+			if(this.x > this.radius) {
+				this.x = this.radius;
+			} else {
+				this.x = 0;
+			}
+		} else {
+			if(this.x > this.radius) {
+				this.x = 2*this.radius;
+			} else {
+				this.x = this.radius;
+			}
+		}
+		this.type = type;
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myArc.lineStyle();</pre>
+	* 		<pre>myArc.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/	
+	
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.		
+	* 		
+	* @usage   <pre>myArc.fillStyle();</pre>
+	* 		<pre>myArc.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 		
+	* 		
+	* @usage   <pre>myArc.animationStyle(duration);</pre>
+	* 		<pre>myArc.animationStyle(duration, callback);</pre>
+	* 		<pre>myArc.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/		
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		if(registrationObj.position == "CENTER") {	
+			if(this.type == "PIE") {
+				this.x = 0;
+			} else {
+				this.x = this.radius;
+			}			
+			this.y = 0;
+		} else if (registrationObj.x != null || registrationObj.y != null) {
+			if(this.type == "PIE") {
+				this.x = this.radius + registrationObj.x;
+			} else {
+				this.x = 2* (this.radius + registrationObj.x);
+			}
+			this.y = this.radius + registrationObj.y;
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/
+	
+	private function drawNew(Void):Void {	
+		this.mc.moveTo(this.x, this.y);
+		if (this.fillRGB != null && this.fillGradient == false) {			
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, this.gradientColors, this.gradientAlphas, this.gradientRatios, this.gradientMatrix);
+		}
+		this.drawArc(this.x, this.y, this.start, this.end, this.radius);
+		this.mc.endFill();
+	}
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+
+	/*-------------------------------------------------------------
+		drawArc is a method for drawing regular and elliptical 
+		arc segments and pie shaped wedges. Thanks to: 
+		Robert Penner, Eric Mueller and Michael Hurwicz for their contributions.
+	-------------------------------------------------------------*/
+	private function drawArc(x:Number, y:Number, startAngle:Number,
+							   arc:Number, radius:Number, yRadius):Void {
+				
+		// ==============
+		// drawArc() - by Ric Ewing (ric at formequalsfunction.com) - version 1.5 - 4.7.2002
+		// 
+		// x, y = This must be the current pen position... other values will look bad
+		// radius = radius of Arc. If [optional] yRadius is defined, then r is the x radius
+		// arc = sweep of the arc. Negative values draw clockwise.
+		// startAngle = starting angle in degrees.
+		// yRadius = [optional] y radius of arc. Thanks to Robert Penner for the idea.
+		// ==============
+		// Thanks to: Robert Penner, Eric Mueller and Michael Hurwicz for their contributions.
+		// ==============
+
+		// if yRadius is undefined, yRadius = radius
+		if (yRadius == undefined) {
+			yRadius = radius;
+		}
+		// Init vars
+		var segAngle:Number, theta:Number, angle:Number, angleMid:Number, segs:Number;
+		var ax:Number, ay:Number, bx:Number, by:Number, cx:Number, cy:Number;
+		// no sense in drawing more than is needed :)
+		if (Math.abs(arc)>360) {
+			arc = 360;
+		}
+		// Flash uses 8 segments per circle, to match that, we draw in a maximum
+		// of 45 degree segments. First we calculate how many segments are needed
+		// for our arc.
+		segs = Math.ceil(Math.abs(arc)/45);
+		// Now calculate the sweep of each segment
+		segAngle = arc/segs;		
+		// The math requires radians rather than degrees. To convert from degrees
+		// use the formula (degrees/180)*Math.PI to get radians. 
+		theta = -(segAngle/180)*Math.PI;
+		// convert angle startAngle to radians
+		angle = -(startAngle/180)*Math.PI;
+		if(this.type == "CHORD" || this.type == "OPEN") {			
+			// find our starting points (ax,ay) relative to the secified x,y
+			ax = x-Math.cos(angle)*radius;
+			ay = y-Math.sin(angle)*yRadius;
+		}
+		// if our arc is larger than 45 degrees, draw as 45 degree segments
+		// so that we match Flash's native circle routines.
+		if (segs>0) {			
+			if(this.type == "PIE") {
+				// draw a line from the center to the start of the curve
+				ax = x+Math.cos(startAngle/180*Math.PI)*radius;
+				ay = y+Math.sin(-startAngle/180*Math.PI)*yRadius;
+				this.mc.lineTo(ax, ay);			
+				ax = x;
+				ay = y;
+			} 
+			// Loop for drawing arc segments
+			var i:Number;
+			for(i = 0; i<segs; i++) {
+				// increment our angle
+				angle += theta;
+				// find the angle halfway between the last angle and the new
+				angleMid = angle-(theta/2);
+
+				// calculate our end point
+				bx = ax+Math.cos(angle)*radius;
+				by = ay+Math.sin(angle)*yRadius;
+				// calculate our control point
+				cx = ax+Math.cos(angleMid)*(radius/Math.cos(theta/2));
+				cy = ay+Math.sin(angleMid)*(yRadius/Math.cos(theta/2));				
+	
+				// draw the arc segment
+				this.mc.curveTo(cx, cy, bx, by);
+			}
+			// close the wedge by drawing a line to the center. 
+			// Draw transparent for open arc.
+			if(this.type == "OPEN") {				
+				this.mc.lineStyle();
+				this.mc.lineTo(x, y);
+				this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+			} else {
+				this.mc.lineTo(x, y);
+			}			
+		}
+		// In the native draw methods the user must specify the end point
+		// which means that they always know where they are ending at, but
+		// here the endpoint is unknown unless the user calculates it on their 
+		// own. Lets be nice and let save them the hassle by passing it back. 
+		//return {x:bx, y:by};
+	}
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/	
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myArc.addEventListener(event, listener);</pre>
+	* 		    <pre>myArc.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myArc.removeEventListener(event, listener);</pre>
+	* 		    <pre>myArc.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myArc.removeAllEventListeners();</pre>
+	* 		    <pre>myArc.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myArc.eventListenerExists(event, listener);</pre>
+	* 			<pre>myArc.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "Arc";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Arc.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Burst.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Burst.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Burst.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,347 @@
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+
+/**
+* @class Burst
+* @author Alex Uhlmann
+* @description Burst is a class for drawing bursts (rounded star shaped ovals often seen in advertising). 
+* 			This method also makes some fun flower shapes if you play with the input numbers. 
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a Burst with default parameters.		
+* 			<blockquote><pre>
+*			var myBurst:Burst = new Burst();
+*			myBurst.draw();
+*			</pre></blockquote> 
+* 			Example 2: <a href="Burst_02.html">(Example .swf)</a> draw a Burst with custom parameters.		
+* 			<blockquote><pre>
+*			var myBurst:Burst = new Burst(275,200,40,50,10);
+*			myBurst.lineStyle(2,0xff0000,100);
+*			myBurst.fillStyle(0xff0000,100);
+*			myBurst.draw();
+*			</pre></blockquote> 			
+* 			Example 3: <a href="Burst_03.html">(Example .swf)</a> 
+* 			<blockquote><pre>
+*			var myBurst:Burst = new Burst(275,200,40,25,10);
+*			myBurst.lineStyle(2,0xff0000,100);
+*			myBurst.fillStyle(0xff0000,100);
+*			myBurst.draw();
+*			</pre></blockquote>
+* 			Example 4:
+* 			<blockquote><pre>
+*			var myBurst:Burst = new Burst(275,200,30,100,10);
+*			myBurst.lineStyle(2,0xff0000,100);
+*			myBurst.fillStyle(0xff0000,100);
+*			myBurst.draw();
+*			</pre></blockquote> 		
+* @usage <pre>var myBurst:Burst = new Burst();</pre> 
+* 		<pre>var myBurst:Burst = new Burst(x, y, innerRadius, outerRadius, sides);</pre> 		
+* 		 <pre>var myBurst:Burst = new Burst(mc, x, y, innerRadius, outerRadius, sides);</pre> 
+* 
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param innerRadius (Number) Radius of the indent of the curves.
+* @param outerRadius (Number) Radius of the outermost points.
+* @param sides (Number) Number of sides or points.	
+*/
+class de.alex_uhlmann.animationpackage.drawing.Burst 
+										extends Shape 
+										implements IDrawable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/	
+	/** 
+	* @property innerRadius_def (Number)(static) default property. Radius of the indent of the curves.
+	* @property outerRadius_def (Number)(static) default property. Radius of the outermost points.
+	* @property sides_def (Number)(static) default property. Number of sides or points.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.
+	*/
+	public static var innerRadius_def:Number = 80;
+	public static var outerRadius_def:Number = 100;	
+	public static var sides_def:Number = 10;	
+	private var x:Number = 0;
+	private var y:Number = 0;
+	private var innerRadius:Number;
+	private var outerRadius:Number;
+	private var sides:Number;
+	private var angle:Number;
+
+	public function Burst() {		
+		super(true);
+		this.init.apply(this,arguments);
+		this.fillStyle(null);	
+	}
+	
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, innerRadius:Number, outerRadius:Number, sides:Number):Void {		
+		this.mc = this.createClip({mc:mc, x:x, y:y});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, innerRadius:Number, outerRadius:Number, sides:Number):Void {		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x:Number, y:Number, innerRadius:Number, outerRadius:Number, sides:Number):Void {		
+		this.innerRadius = (innerRadius == null) ? Burst.innerRadius_def : innerRadius;
+		this.outerRadius = (outerRadius == null) ? Burst.outerRadius_def : outerRadius;
+		this.sides = (sides == null) ? Burst.sides_def : sides;
+		this.angle = 0;		
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws bursts.
+	* @usage <pre>myBurst.draw();</pre>
+	*/
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/	
+	
+	/**
+	* @method getInnerRadius
+	* @description 	Return the radius of the indent of the curves.
+	* @usage  <pre>myBurst.getInnerRadius();</pre>
+	* @return Number of the radius of the indent of the curves.
+	*/	
+	public function getInnerRadius(Void):Number {		
+		return this.innerRadius;		
+	}
+		
+	/**
+	* @method setInnerRadius
+	* @description 	Sets the radius of the indent of the curves.		
+	* 		
+	* @usage   <pre>myBurst.setInnerRadius(innerRadius);</pre>
+	* 	  
+	* @param innerRadius (Number) radius of the indent of the curves.
+	*/	
+	public function setInnerRadius(innerRadius:Number):Void {	
+		this.innerRadius = innerRadius;		
+	}	
+	
+	/**
+	* @method getOuterRadius
+	* @description 	Return the radius of the outermost points.
+	* @usage  <pre>myBurst.getOuterRadius();</pre>
+	* @return Number of the radius of the outermost points.
+	*/	
+	public function getOuterRadius(Void):Number {		
+		return this.outerRadius;		
+	}
+		
+	/**
+	* @method setOuterRadius
+	* @description 	Sets the radius of the outermost points.		
+	* 		
+	* @usage   <pre>myBurst.setOuterRadius(outerRadius);</pre>
+	* 	  
+	* @param outerRadius (Number) radius of the outermost points.
+	*/	
+	public function setOuterRadius(outerRadius:Number):Void {	
+		this.outerRadius = outerRadius;		
+	}
+	
+	/**
+	* @method getSides
+	* @description 	Return the sides of the drawing.
+	* @usage  <pre>myBurst.getSides();</pre>
+	* @return Number of sides. 
+	*/	
+	public function getSides(Void):Number {		
+		return this.sides;		
+	}
+		
+	/**
+	* @method setSides
+	* @description 	Sets the sides of the drawing.		
+	* 		
+	* @usage   <pre>myBurst.setSides(sides);</pre>
+	* 	  
+	* @param sides (Number) the number of sides.
+	*/	
+	public function setSides(sides:Number):Void {	
+		this.sides = sides;		
+	}
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		
+		if(registrationObj.position == "CENTER") {		
+			this.x = 0;
+			this.y = 0;
+		} else {			
+			if(this.innerRadius > this.outerRadius) {
+				this.x = this.innerRadius + registrationObj.x;
+				this.y = this.innerRadius + registrationObj.y;
+			} else {
+				this.x = this.outerRadius + registrationObj.x;
+				this.y = this.outerRadius + registrationObj.y;
+			}
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	private function drawNew(Void):Void {		
+		this.mc.moveTo(this.x, this.y);
+		if (this.fillRGB != null && this.fillGradient == false) {
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, this.gradientColors, this.gradientAlphas, this.gradientRatios, this.gradientMatrix);
+		}		
+		this.drawBurst(this.x, this.y, this.sides, this.innerRadius, 
+					   this.outerRadius, this.angle);
+		this.mc.endFill();
+	}	
+	
+	/*-------------------------------------------------------------
+		drawBurst is a method for drawing bursts (rounded
+		star shaped ovals often seen in advertising). This
+		seemingly whimsical method actually had a serious
+		purpose. It was done to accommodate a client that
+		wanted to have custom bursts for 'NEW!' and
+		'IMPROVED!' type elements on their site...
+		personally I think those look tacky, but it's hard
+		to argue with a paying client. :) This method also
+		makes some fun flower shapes if you play with the
+		input numbers. 
+	-------------------------------------------------------------*/
+	private function drawBurst(x:Number, y:Number, sides:Number, 
+							   innerRadius:Number, outerRadius:Number, angle:Number):Void {
+		// ==============
+		// drawBurst() - by Ric Ewing (ric at formequalsfunction.com) - version 1.4 - 4.7.2002
+		// 
+		// x, y = center of burst
+		// sides = number of sides or points
+		// innerRadius = radius of the indent of the curves
+		// outerRadius = radius of the outermost points
+		// angle = [optional] starting angle in degrees. (defaults to 0)
+		// ==============
+		if (sides>2) {
+			// init vars
+			var step:Number, halfStep:Number, qtrStep:Number, start:Number;
+			var n:Number, dx:Number, dy:Number, cx:Number, cy:Number;
+			// calculate length of sides
+			step = (Math.PI*2)/sides;
+			halfStep = step/2;
+			qtrStep = step/4;
+			// calculate starting angle in radians
+			start = (angle/180)*Math.PI;
+			this.mc.moveTo(x+(Math.cos(start)*outerRadius), y-(Math.sin(start)*outerRadius));
+			// draw curves
+			for (n=1; n<=sides; n++) {
+				cx = x+Math.cos(start+(step*n)-(qtrStep*3))*(innerRadius/Math.cos(qtrStep));
+				cy = y-Math.sin(start+(step*n)-(qtrStep*3))*(innerRadius/Math.cos(qtrStep));
+				dx = x+Math.cos(start+(step*n)-halfStep)*innerRadius;
+				dy = y-Math.sin(start+(step*n)-halfStep)*innerRadius;
+				this.mc.curveTo(cx, cy, dx, dy);
+				cx = x+Math.cos(start+(step*n)-qtrStep)*(innerRadius/Math.cos(qtrStep));
+				cy = y-Math.sin(start+(step*n)-qtrStep)*(innerRadius/Math.cos(qtrStep));
+				dx = x+Math.cos(start+(step*n))*outerRadius;
+				dy = y-Math.sin(start+(step*n))*outerRadius;
+				this.mc.curveTo(cx, cy, dx, dy);
+			}
+		}
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myBurst.lineStyle();</pre>
+	* 		<pre>myBurst.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.		
+	* 		
+	* @usage   <pre>myBurst.fillStyle();</pre>
+	* 		<pre>myBurst.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Burst";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Burst.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/CubicCurve.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/CubicCurve.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/CubicCurve.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,1007 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.IOutline;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.BezierToolkit;
+
+/**
+* @class CubicCurve
+* @author Alex Uhlmann
+* @description CubicCurve is a class for drawing curves.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a curve with default parameters.		
+* 			<blockquote><pre>
+*			var myCubicCurve:CubicCurve = new CubicCurve();
+*			myCubicCurve.draw();
+*			</pre></blockquote> 
+* 			Example 2: do the same, just animate it.		
+* 			<blockquote><pre>
+* 			var myCubicCurve:CubicCurve = new CubicCurve();
+*			myCubicCurve.animate(0,100);
+*			</pre></blockquote> 			
+* 			Example 3: draw a curve with custom parameters. 
+* 			<blockquote><pre>
+*			var myCubicCurve:CubicCurve = new CubicCurve(100,100,300,300,500,100,500,400);
+*			myCubicCurve.lineStyle(2,0xff0000,50);
+*			myCubicCurve.draw();
+*			</pre></blockquote>
+* 			Example 4: the same like above using the getter/setter methods. 
+* 			<blockquote><pre>
+*			var myCubicCurve:CubicCurve = new CubicCurve();
+*			myCubicCurve.lineStyle(2,0xff0000,50);
+*			myCubicCurve.setX1(100);
+*			myCubicCurve.setY1(100);
+*			myCubicCurve.setX2(300);
+*			myCubicCurve.setY2(300);
+*			myCubicCurve.setX3(500);
+*			myCubicCurve.setY3(100);
+*			myCubicCurve.setX4(500);
+*			myCubicCurve.setY4(400);
+*			myCubicCurve.draw();
+*			</pre></blockquote> 
+* 			Example 5: <a href="CubicCurve_04.html">(Example .swf)</a> draw an animated curve with custom parameters, that 
+* 			continues to animated to full size and back.
+* 			<blockquote><pre>
+*			var myCubicCurve:CubicCurve = new CubicCurve(50,100,200,300,400,100,550,400);
+*			myCubicCurve.lineStyle(10,0xff0000,50);
+*			myCubicCurve.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			myCubicCurve.animate(0, 100);
+*			myListener.onCallback = function(source, value)
+*			{	
+*				if(value == 100) {
+*					source.animate(100, 0);
+*				} else {
+*					source.animate(0, 100);
+*				}	
+*			}
+*			</pre></blockquote> 	
+* 			The curve is specified with four points. 
+* 			Start point, two points on the curve and the end point.
+*			Instead of the two points on the curve you can use 
+* 			control points. For instance, the MovieClip.curveTo method uses control points.<p>
+* @usage <pre>var myCubicCurve:CubicCurve = new CubicCurve();</pre> 
+* 		<pre>var myCubicCurve:CubicCurve = new CubicCurve(x1, y1, x2, y2, x3, y3, x4, y4);</pre>
+* 		<pre>var myCubicCurve:CubicCurve = new CubicCurve(x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints);</pre> 
+* 		<pre>var myCubicCurve:CubicCurve = new CubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4);</pre>
+* 		<pre>var myCubicCurve:CubicCurve = new CubicCurve(mc, x1, y1, x2, y2, x3, y3, x4, y4, withControlpoints);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x1 (Number) start point to define curve. Coordinate point x
+* @param y1 (Number) start point to define curve. Coordinate point y
+* @param x2 (Number) point on the curve or control point to define curve. Coordinate point x
+* @param y2 (Number) point on the curve or control point to define curve. Coordinate point y
+* @param x3 (Number) point on the curve or control point to define curve. Coordinate point x
+* @param y3 (Number) point on the curveor control point to define curve. Coordinate point y
+* @param x4 (Number) end point to define curve. Coordinate point x
+* @param y4 (Number) end point to define curve. Coordinate point y 
+* @param withControlpoints (Boolean) specify control points between the start and end points of the curve instead of points on the curve. Default is false.
+*/
+class de.alex_uhlmann.animationpackage.drawing.CubicCurve 
+									extends Shape 
+									implements IDrawable, 
+											IOutline, 
+											ISingleAnimatable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/	
+	/*animationStyle properties inherited from APCore*/	
+	/** 
+	* @property x1_def (Number)(static) default property. start point to define curve. Coordinate point x.
+	* @property y1_def (Number)(static) default property. start point to define curve. Coordinate point y.
+	* @property x2_def (Number)(static) default property. point on the curve or control point to define curve. Coordinate point x.
+	* @property y2_def (Number)(static) default property. point on the curve or control point to define curve. Coordinate point y.
+	* @property x3_def (Number)(static) default property. point on the curve or control point to define curve. Coordinate point x.
+	* @property y3_def (Number)(static) default property. point on the curveor control point to define curve. Coordinate point y.
+	* @property x4_def (Number)(static) default property. end point to define curve. Coordinate point x.
+	* @property y4_def (Number)(static) default property. end point to define curve. Coordinate point y.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).	
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/
+	public static var x1_def:Number = 0;
+	public static var y1_def:Number = 0;	
+	public static var x2_def:Number = 180;
+	public static var y2_def:Number = 400;	
+	public static var x3_def:Number = 400;
+	public static var y3_def:Number = 0;
+	public static var x4_def:Number = 550;
+	public static var y4_def:Number = 400;		
+	private var myBezierToolkit:BezierToolkit;
+	/*start, control and end points of curve*/
+	private var x1:Number;
+	private var y1:Number;
+	private var x2:Number;
+	private var y2:Number;
+	private var x3:Number;
+	private var y3:Number;
+	private var x4:Number;
+	private var y4:Number;
+	private var p1:Object;
+	private var p2:Object;
+	private var p3:Object;
+	private var p4:Object;
+	private var x1Orig:Number;
+	private var y1Orig:Number;
+	private var x2Orig:Number;
+	private var y2Orig:Number;
+	private var x3Orig:Number;
+	private var y3Orig:Number;
+	private var x4Orig:Number;
+	private var y4Orig:Number;	
+	private var withControlpoints:Boolean = false;
+	private var x2ControlPoint:Number;
+	private var y2ControlPoint:Number;
+	private var x3ControlPoint:Number;
+	private var y3ControlPoint:Number;
+	public var mode:String = "REDRAW";
+	private var lastStep:Number = 0;
+	private var overriddenRounded:Boolean = true;
+	private var overriddedOptimize:Boolean = true;
+	
+	public function CubicCurve() {
+		super();
+		this.init.apply(this,arguments);
+		this.lineStyle(null);
+		this.animationStyle();
+	}
+
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x1:Number, y1:Number, x2:Number, y2:Number, 
+						x3:Number, y3:Number, x4:Number, y4:Number, withControlpoints:Boolean):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:0, y:0});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x1:Number, y1:Number, x2:Number, y2:Number, 
+						x3:Number, y3:Number, x4:Number, y4:Number, withControlpoints:Boolean):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:0, y:0});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x1:Number, y1:Number, x2:Number, y2:Number, 
+						x3:Number, y3:Number, x4:Number, y4:Number, withControlpoints:Boolean):Void {
+		
+		this.x1 = (x1 == null) ? CubicCurve.x1_def : x1;
+		this.y1 = (y1 == null) ? CubicCurve.y1_def : y1;
+		this.x2 = (x2 == null) ? CubicCurve.x2_def : x2;
+		this.y2 = (y2 == null) ? CubicCurve.y2_def : y2;
+		this.x3 = (x3 == null) ? CubicCurve.x3_def : x3;
+		this.y3 = (y3 == null) ? CubicCurve.y3_def : y3;
+		this.x4 = (x4 == null) ? CubicCurve.x4_def : x4;
+		this.y4 = (y4 == null) ? CubicCurve.y4_def : y4;
+		if(withControlpoints != null) {
+			this.withControlpoints = withControlpoints;
+		}
+		this.x1Orig = this.x1;
+		this.y1Orig = this.y1;
+		this.x2Orig = this.x2;
+		this.y2Orig = this.y2;
+		this.x3Orig = this.x3;
+		this.y3Orig = this.y3;
+		this.x4Orig = this.x4;
+		this.y4Orig = this.y4;
+		this.myBezierToolkit = new BezierToolkit();
+	}
+
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws the curve.
+	* @usage <pre>myCubicCurve.draw();</pre>
+	*/	
+	public function draw(Void):Void {
+		this.setInitialized(false);
+		this.setDefaultRegistrationPoint({position:"CENTER"});
+		this.clearDrawing();
+		this.mc.moveTo(this.x1, this.y1);		
+		this.drawNew();
+	}
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the line without clearing the movieclip.
+	* @usage <pre>myCubicCurve.drawBy();</pre>
+	*/
+	public function drawBy(Void):Void {
+		this.initControlPoints();
+		
+		if(this.lineStyleModified) {
+			this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+		}
+		if(this.penX != this.x1 || this.penY != this.y1) {			
+			this.mc.moveTo(this.x1, this.y1);
+		}
+		
+		this.drawNew();
+	}
+	
+	public function drawTo(Void):Void {
+		this.drawNew();
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		var goto:Boolean;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;			
+		} else {
+			goto = false;
+		}
+		var setter:String;
+		if(this.mode == "REDRAW") {			
+			this.setInitialized(false);
+			this.setDefaultRegistrationPoint({position:"CENTER"});	
+			if(overriddedOptimize) {
+				setter = "drawLineCurve";
+			} else {
+				setter = "drawLineCurveSecure";
+			}
+		} else if(this.mode == "DRAW"){
+			this.initControlPoints();			
+			if(this.penX != this.x1 || this.penY != this.y1) {			
+				if(this.lineStyleModified) {
+					this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+				}
+				this.mc.moveTo(this.x1, this.y1);
+			}
+			if(overriddedOptimize) {
+				setter = "drawLineCurveBy";
+			} else {
+				setter = "drawLineCurveBySecure";
+			}			
+		} else {
+			setter = "drawLineCurveBy";
+		}
+		this.startValue = 0;
+		this.endValue = 100;		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [0];
+		this.myAnimator.end = [100];
+		this.myAnimator.setter = [[this, setter]];
+		if(goto == false) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			if(this.mode == "DRAWTO")return;
+			this.myAnimator.goto(end);
+		}		
+	}
+	
+	/**
+	* @method animate
+	* @description 	Draws an animated curve.		
+	* @usage  	<pre>myCubicCurve.animate(orig, targ);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/
+	public function animate(start:Number, end:Number):Void {		
+		this.mode = "REDRAW";
+		this.invokeAnimation(start, end);
+	}
+	
+	/**
+	* @method animateBy
+	* @description 	Draws an animated curve without clearing the movieclip.		
+	* @usage  	<pre>myCubicCurve.animateBy(start, end);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/	
+	public function animateBy(start:Number, end:Number):Void {		
+		this.mode = "DRAW";
+		this.invokeAnimation(start, end);
+	}
+	
+	public function animateTo(start:Number, end:Number):Void {		
+		this.mode = "DRAWTO";
+		this.invokeAnimation(start, end);
+	}	
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	private function drawNew(Void):Void {
+		var myCC:com.robertpenner.bezier.CubicCurve = new com.robertpenner.bezier.CubicCurve(this.mc);
+		myCC.drawBezier(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3, this.x4, this.y4, 1);
+		this.penX = this.x4;
+		this.penY = this.y4;
+	}
+	
+	private function drawLineCurve(v:Number):Void {		
+		if(this.lastStep == 0) {
+			if(this.lineStyleModified) {
+				this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+			}
+			this.mc.moveTo(this.x1, this.y1);
+		}
+		var len:Number;
+		
+		if(overriddenRounded) {
+			len = Math.round(v);	
+		} else {
+			len = v;
+		}
+
+		var s:Number;
+		if(len < this.lastStep) {
+			this.clearDrawing();
+			this.mc.moveTo(this.x1, this.y1);
+			s = this.startValue;
+		} else {
+			s = this.lastStep;
+		}
+		if(len == this.lastStep) {
+			return;
+		}
+		this.lastStep = len;
+		var p:Object;
+		var i:Number;
+		for(i = s; i <= len; i++) {
+			p = this.myBezierToolkit.getPointsOnCubicCurve(i, this.p1, this.p2, this.p3, this.p4);
+			this.mc.lineTo(p.x, p.y);			
+		}
+	}
+	
+	private function drawLineCurveBy(v:Number):Void {		
+		var p:Object;
+		var s:Number = (this.lastStep == null) ? this.startValue : this.lastStep;		
+		var len:Number;
+		if(overriddenRounded) {
+			len = Math.round(v);	
+		} else {
+			len = v;
+		}
+		if(len == this.lastStep) {
+			return;
+		}		
+		this.lastStep = len;
+		var i:Number;		
+		for(i = s; i <= len; i++) {
+			p = this.myBezierToolkit.getPointsOnCubicCurve(i, this.p1, this.p2, this.p3, this.p4);
+			this.mc.lineTo(p.x, p.y);				
+		}
+	}	
+	
+	//clunky and slow. I don't like it. But it does the job.
+	private function drawLineCurveSecure(v:Number):Void {		
+		this.clearDrawing();
+		this.mc.moveTo(this.x1, this.y1);		
+		var p:Object;
+		var s:Number = this.startValue;		
+		var len:Number = Math.round(v);		
+		var i:Number;
+		for(i = s; i <= len; i++) {
+			p = this.myBezierToolkit.getPointsOnCubicCurve(i, this.p1, this.p2, this.p3, this.p4);
+			this.mc.lineTo(p.x, p.y);	
+		}
+	}
+	
+	private function drawLineCurveBySecure(v:Number):Void {		
+		this.mc.moveTo(this.x1, this.y1);		
+		var p:Object;
+		var s:Number = this.startValue;		
+		var len:Number = Math.round(v);
+		var i:Number;
+		for(i = s; i <= len; i++) {
+			p = this.myBezierToolkit.getPointsOnCubicCurve(i, this.p1, this.p2, this.p3, this.p4);
+			this.mc.lineTo(p.x, p.y);
+		}
+	}
+	
+	/**
+	* @method useControlPoints
+	* @description 	offers the opportunity to specify control points between the start and end points 
+	* 				of the curve instead of points on the curve. Default is false.
+	* 				If true points between start and end points are control points.
+	*                  		If false points between start and end points are points on the curve.
+	* @usage   <pre>myInstance.useControlPoints(withControlpoints);</pre> 	  
+	* @param withControlpoints (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/
+	public function useControlPoints(withControlpoints:Boolean):Void {
+		if(withControlpoints && this.initialized == true) {
+			this.x2 = this.x2ControlPoint;
+			this.y2 = this.y2ControlPoint;
+			this.x3 = this.x3ControlPoint;
+			this.y3 = this.y3ControlPoint;
+			this.p2 = {x:this.x2, y:this.y2};
+			this.p3 = {x:this.x3, y:this.y3};
+		}
+		this.withControlpoints = withControlpoints;		
+	}
+	
+	public function initControlPoints(Void):Void {
+		if(!this.initialized) {
+			if(this.withControlpoints == false) {
+				this.x2ControlPoint = x2;
+				this.y2ControlPoint = y2;
+				this.x3ControlPoint = x3;
+				this.y3ControlPoint = y3;
+				var controlPoint:Object = this.myBezierToolkit.getCubicControlPoints(this.x1, this.y1, 
+								this.x2, this.y2, this.x3, this.y3, this.x4, this.y4);
+				this.x2 = controlPoint.x1;
+				this.y2 = controlPoint.y1;
+				this.x3 = controlPoint.x2;
+				this.y3 = controlPoint.y2;				
+			}
+			this.p1 = {x:this.x1, y:this.y1};
+			this.p2 = {x:this.x2, y:this.y2};
+			this.p3 = {x:this.x3, y:this.y3};
+			this.p4 = {x:this.x4, y:this.y4};
+			this.initialized = true;
+		}
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myCubicCurve.lineStyle();</pre>
+	* 		<pre>myCubicCurve.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 	
+	* 		
+	* @usage   <pre>myCubicCurve.animationStyle(duration);</pre>
+	* 		<pre>myCubicCurve.animationStyle(duration, callback);</pre>
+	* 		<pre>myCubicCurve.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {	
+		this.initialized = false;
+		
+		var centerX:Number;
+		var centerY:Number;
+		
+		var minX:Number = Math.min(Math.min(Math.min(this.x1Orig, this.x2Orig), this.x3Orig), this.x4Orig);
+		var maxX:Number = Math.max(Math.max(Math.max(this.x1Orig, this.x2Orig), this.x3Orig), this.x4Orig);
+		var minY:Number = Math.min(Math.min(Math.min(this.y1Orig, this.y2Orig), this.y3Orig), this.y4Orig);
+		var maxY:Number = Math.max(Math.max(Math.max(this.y1Orig, this.y2Orig), this.y3Orig), this.y4Orig);		
+		
+		if(registrationObj.position == "CENTER") {
+			centerX = (maxX - minX) / 2 + minX;
+			centerY = (maxY - minY) / 2 + minY;		
+		} else if (registrationObj.x != null || registrationObj.y != null) {
+			centerX = minX + registrationObj.x;
+			centerY = minY + registrationObj.y;		
+		} else {
+			centerX = 0;
+			centerY = 0;
+		}
+		this.mc._x = centerX;
+		this.mc._y = centerY;	
+		this.x1 = this.x1Orig - centerX;
+		this.y1 = this.y1Orig - centerY;
+		this.x2 = this.x2Orig - centerX;
+		this.y2 = this.y2Orig - centerY;
+		this.x3 = this.x3Orig - centerX;
+		this.y3 = this.y3Orig - centerY;
+		this.x4 = this.x4Orig - centerX;
+		this.y4 = this.y4Orig - centerY;
+		this.initControlPoints();
+	}	
+	
+	private function setDefaultRegistrationPoint(registrationObj:Object):Void {		
+		if(!this.initialized) {
+			this.setRegistrationPoint(registrationObj);
+		}
+	}
+	
+	public function reset() {
+		this.x1 = this.x1Orig;
+		this.y1 = this.y1Orig;
+		this.x2 = this.x2Orig;
+		this.y2 = this.y2Orig;
+		this.x3 = this.x3Orig;
+		this.y3 = this.y3Orig;
+		this.x4 = this.x4Orig;
+		this.y4 = this.y4Orig;
+		this.initialized = false;
+		this.initControlPoints();		
+	}
+
+	/**
+	* @method getX1
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX1();</tt>
+	* @return Number
+	*/	
+	public function getX1(Void):Number {
+		return this.x1;
+	}
+	
+	/**
+	* @method setX1
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX1();</tt>
+	* @param point (Number)
+	*/
+	public function setX1(x1:Number):Void {
+		this.x1Orig = x1;
+		this.x1 = x1;
+	}
+	
+	/**
+	* @method getY1
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY1();</tt>
+	* @return Number
+	*/
+	public function getY1(Void):Number {
+		return this.y1;
+	}
+	
+	/**
+	* @method setY1
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY1();</tt>
+	* @param point (Number)
+	*/	
+	public function setY1(y1:Number):Void {
+		this.y1Orig = y1;
+		this.y1 = y1;
+	}	
+	
+	/**
+	* @method getX2
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX2();</tt>
+	* @return Number
+	*/	
+	public function getX2(Void):Number {
+		return this.x2;
+	}
+	
+	/**
+	* @method setX2
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX2();</tt>
+	* @param point (Number)
+	*/	
+	public function setX2(x2:Number):Void {
+		this.x2Orig = x2;
+		this.x2 = x2;
+	}
+	
+	/**
+	* @method getY2
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY2();</tt>
+	* @return Number
+	*/
+	public function getY2(Void):Number {
+		return this.y2;
+	}
+	
+	/**
+	* @method setY2
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY2();</tt>
+	* @param point (Number)
+	*/		
+	public function setY2(y2:Number):Void {
+		this.y2Orig = y2;
+		this.y2 = y2;
+	}
+	
+	/**
+	* @method getX3
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX3();</tt>
+	* @return Number
+	*/	
+	public function getX3(Void):Number {
+		return this.x3;
+	}
+	
+	/**
+	* @method setX3
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX3();</tt>
+	* @param point (Number)
+	*/	
+	public function setX3(x3:Number):Void {
+		this.x3Orig = x3;
+		this.x3 = x3;
+	}
+	
+	/**
+	* @method getY3
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY3();</tt>
+	* @return Number
+	*/	
+	public function getY3(Void):Number {
+		return this.y3;
+	}
+	
+	/**
+	* @method setY3
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY3();</tt>
+	* @param point (Number)
+	*/	
+	public function setY3(y3:Number):Void {
+		this.y3Orig = y3;
+		this.y3 = y3;
+	}
+	
+	/**
+	* @method getX4
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX4();</tt>
+	* @return Number
+	*/	
+	public function getX4(Void):Number {
+		return this.x4;
+	}
+	
+	/**
+	* @method setX4
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX4();</tt>
+	* @param point (Number)
+	*/	
+	public function setX4(x4:Number):Void {
+		this.x4Orig = x4;
+		this.x4 = x4;
+	}
+	
+	/**
+	* @method getY4
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY4();</tt>
+	* @return Number
+	*/	
+	public function getY4(Void):Number {
+		return this.y4;
+	}
+	
+	/**
+	* @method setY4
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY4();</tt>
+	* @param point (Number)
+	*/	
+	public function setY4(y4:Number):Void {
+		this.y4Orig = y4;
+		this.y4 = y4;
+	}
+
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	public function checkIfRounded(Void):Boolean {
+		return this.overriddenRounded;
+	}
+	
+	public function roundResult(overriddenRounded:Boolean):Void {
+		this.overriddenRounded = overriddenRounded;
+	}	
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	public function getOptimizationMode(Void):Boolean {		
+		return this.overriddedOptimize;
+	}
+	
+	public function setOptimizationMode(overriddedOptimize:Boolean):Void {		
+		this.overriddedOptimize = overriddedOptimize;
+	}
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/	
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myCubicCurve.addEventListener(event, listener);</pre>
+	* 		    <pre>myCubicCurve.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myCubicCurve.removeEventListener(event, listener);</pre>
+	* 		    <pre>myCubicCurve.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myCubicCurve.removeAllEventListeners();</pre>
+	* 		    <pre>myCubicCurve.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myCubicCurve.eventListenerExists(event, listener);</pre>
+	* 			<pre>myCubicCurve.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "CubicCurve";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/CubicCurve.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Curve.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Curve.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Curve.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,627 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.MoveOnCurve;
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Curve
+* @author Alex Uhlmann, Steve Schwarz
+* @description Curve is a class for drawing bezier curves with n controlpoints. With Curve 
+* 			you can create bezier curves with an arbitrary length. The start and end points are the points 
+* 			on the curve. In contrary to i.e. QuadCurve the Curve class by default 
+* 			uses control points instead of points on the curve between the start and end points (anchor points).<p>
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc by default.
+* 			<p>
+* 			Take a look into MoveOnCurve for a more comprehensive example.
+* 			Example 1: draw a quadratic bezier curve.
+* 			<blockquote><pre>
+*			var points:Array = new Array();
+*			points.push({x:0, y:0});
+*			points.push({x:275, y:200});
+*			points.push({x:550, y:0});
+*			
+*			var myCurve:Curve = new Curve(points);
+*			myCurve.draw();
+*			</pre></blockquote>
+* 			Example 2: draw an animated quadratic bezier curve with custom parameters, that 
+* 			continues to animated to full size and back.
+* 			<blockquote><pre>
+*			var points:Array = new Array();
+*			points.push({x:0, y:0});
+*			points.push({x:275, y:200});
+*			points.push({x:550, y:0});
+* 			
+* 			var myCurve:Curve = new Curve(points);
+*			myCurve.lineStyle(10,0xff0000,50);
+*			myCurve.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			myCurve.animate(0, 100);
+*			myListener.onCallback = function(source, value)
+*			{	
+*				if(value == 100) {
+*					source.animate(100, 0);
+*				} else {
+*					source.animate(0, 100);
+*				}	
+*			}
+*			</pre></blockquote>	
+* @usage <pre>var myCurve:Curve = new Curve();</pre> 
+* 		<pre>var myCurve:Curve = new Curve(points);</pre> 
+* 		<pre>var myCurve:Curve = new Curve(mc, points);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param points (Array) Array of objects with x and y properties that define the curve.
+*/
+class de.alex_uhlmann.animationpackage.drawing.Curve 
+											extends Shape 
+											implements IDrawable, 
+													ISingleAnimatable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/	
+	/*animationStyle properties inherited from APCore*/	
+	/**
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).	
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/	
+	private var mc:MovieClip;
+	private var points:Array;
+	private var myPoints:Array;
+	/*points already calculated by getPointsOnCurve*/
+	private var calculatedPoints:Array;
+	private var myMoveOnCurve:MoveOnCurve;
+	private var x1:Number;
+	private var y1:Number;
+	private var mode:String = "REDRAW";
+
+	public function Curve() {
+		super();
+		this.init.apply(this,arguments);
+		this.lineStyle(null);
+		this.animationStyle();
+	}
+
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, points:Array):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:0, y:0});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(points:Array):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:0, y:0});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(points:Array):Void {
+		
+		this.points = points;
+		var i:Number = this.points.length;		
+		this.myPoints = new Array();
+		while(--i>-1) {
+			//Copy array by value.			
+			this.myPoints[i] = {x: this.points[i].x, y: this.points[i].y};
+		}
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws the curve.
+	* @usage <pre>myInstance.draw();</pre>
+	*/
+	public function draw(Void):Void {
+		this.setDefaultRegistrationPoint({position:"CENTER"});
+		this.clearDrawing();
+		this.mode = "REDRAW";
+		this.goto(100);
+	}
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/
+	//TODO: include a *real* drawBy method. ( ;
+	public function drawBy(Void):Void {
+		this.mode = "DRAW";
+		this.goto(100);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		
+		var goto:Boolean;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;			
+		} else {
+			goto = false;
+		}
+		var setter:String;	
+		if(this.mode == "REDRAW") {
+			this.setDefaultRegistrationPoint({position:"CENTER"});
+			setter = "drawLineCurve";
+		} else {
+			if(this.lineStyleModified) {
+				this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+			}
+			setter = "drawLineCurveBy";
+		}
+		this.startValue = 0;
+		this.endValue = 100;		
+		/*how to continuesly draw a curve. Ask MoveOnCurve.*/
+		this.myMoveOnCurve = new MoveOnCurve(null, this.myPoints);		
+		this.x1 = this.myPoints[0].x;
+		this.y1 = this.myPoints[0].y;			
+		
+		this.calculatedPoints = new Array();
+
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [0];
+		this.myAnimator.end = [100];
+		this.myAnimator.setter = [[this, setter]];
+		if(goto == false) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(end);
+		}		
+	}
+	
+	/**
+	* @method animate
+	* @description 	Draws an animated curve.		
+	* @usage  	<pre>myInstance.animate(orig, targ);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/
+	public function animate(start:Number, end:Number):Void {
+		this.mode = "REDRAW";
+		this.invokeAnimation(start, end);
+	}
+		
+	/**
+	* @method animateBy
+	* @description 	Draws an animated curve without clearing the movieclip.		
+	* @usage  	<pre>myInstance.animateBy(orig, targ);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/
+	public function animateBy(start:Number, end:Number):Void {	
+		this.mode = "DRAW";
+		this.invokeAnimation(start, end);
+	}
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	//clunky and slow. I don't like it. But it does the job.
+	private function drawLineCurve(v:Number):Void {		
+		this.clearDrawing();
+		this.mc.moveTo(this.x1, this.y1);
+		var p:Object;
+		var calc:Array = this.calculatedPoints;
+		var s:Number = this.startValue;		
+		var len:Number = Math.round(v);
+		var i:Number;
+		for(i = s; i <= len; i++) {
+			if(calc[i] == null) {
+				p = calc[i] = this.myMoveOnCurve.getPointsOnCurve(i);
+			} else {
+				p = calc[i];
+			}
+			this.mc.lineTo(p.x, p.y);
+		}
+	}
+	
+	private function drawLineCurveBy(v:Number):Void {		
+		this.mc.moveTo(this.x1, this.y1);		
+		var p:Object;
+		var calc:Array = this.calculatedPoints;
+		var calcL:Number = this.calculatedPoints.length;		
+		var s:Number = this.startValue;		
+		var len:Number = Math.round(v);
+		var i:Number;
+		for(i = s; i <= len; i++) {
+			if(calc[i] == null) {
+				p = calc[i] = this.myMoveOnCurve.getPointsOnCurve(i);
+			} else {
+				p = calc[i];
+			}
+			this.mc.lineTo(p.x, p.y);				
+		}
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myInstance.lineStyle();</pre>
+	* 		<pre>myInstance.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/	
+	public function setRegistrationPoint(registrationObj:Object):Void {	
+		this.reset();
+		/*retrieve boundaries of the curve in order to compute the center for positioning.*/
+		var minX:Number = this.getBoundary("x", "min");
+		var minY:Number = this.getBoundary("y", "min");
+		var maxX:Number = this.getBoundary("x", "max");
+		var maxY:Number = this.getBoundary("y", "max");
+		
+		var centerX:Number;
+		var centerY:Number;		
+		if(registrationObj.position == "CENTER") {	
+			centerX = (maxX - minX) / 2 + minX;
+			centerY = (maxY - minY) / 2 + minY;		
+		} else if (registrationObj.x != null || registrationObj.y != null) {
+			centerX = minX + registrationObj.x;
+			centerY = minY + registrationObj.y;		
+		} else {
+			centerX = 0;
+			centerY = 0;
+		}
+	
+		this.mc._x = centerX;
+		this.mc._y = centerY;
+		
+		/*apply center values*/
+		var i:Number = this.points.length;		
+		this.myPoints = new Array();
+		while(--i>-1) {
+			//Copy array by value and modify that value.			
+			this.myPoints[i] = {x: this.points[i].x, y: this.points[i].y};
+			this.myPoints[i].x -= centerX;
+			this.myPoints[i].y -= centerY;			
+		}
+		this.initialized = true;
+	}
+
+	private function getBoundary(prop:String, meth:String):Number {
+		var i:Number = this.points.length;
+		var result:Number = this.points[--i][prop];
+		while(--i>-1) {
+			var element:Number = this.points[i][prop];
+			result = Math[meth](element, result);
+		}
+		return result;
+	}
+
+	private function setDefaultRegistrationPoint(registrationObj:Object):Void {		
+		
+		if(!this.initialized) {			
+			this.setRegistrationPoint(registrationObj);			
+		}
+	}
+	
+	public function reset(Void):Void {
+		this.initialized = false;
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "Curve";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Curve.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/DashLine.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/DashLine.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/DashLine.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,602 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.IOutline;
+import de.alex_uhlmann.animationpackage.drawing.Line;
+
+/**
+* @class DashLine
+* @author Alex Uhlmann
+* @description DashLine is a class for drawing dashed (and dotted) lines. 
+*  			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a line with default parameters.		
+* 			<blockquote><pre>
+*			var myLine:DashLine = new DashLine();
+*			myLine.draw();			
+*			</pre></blockquote> 
+* 			Example 2: do the same, just animate it.		
+* 			<blockquote><pre>
+* 			var myLine:DashLine = new DashLine();
+*			myLine.animate(0,100);
+*			</pre></blockquote> 			
+* 			Example 3: draw a line with custom parameters. A dotted line. 
+* 			<blockquote><pre>
+*			var myLine:DashLine = new DashLine(0,0,275,200,1,8);
+*			myLine.lineStyle(1,0xff0000,100);
+*			myLine.draw();
+*			</pre></blockquote>
+* 			Example 4: <a href="DashLine_04.html">(Example .swf)</a> draw an animated line with custom parameters, that 
+* 			continues to animated to full size and back.
+* 			<blockquote><pre>
+*			var myLine:DashLine = new DashLine(0,0,275,200,4,20);
+*			myLine.lineStyle(10,0xff0000,50);
+*			myLine.animationStyle(2000,Sine.easeOut,"onCallback");
+*			myLine.animate(0,100);
+*			myListener.onCallback = function(source, value)
+*			{	
+*				if(value == 100) {
+*					source.animate(100, 0);
+*				} else {
+*					source.animate(0, 100);
+*				}	
+*			}
+*			</pre></blockquote>
+* 			The dashed line is defined with two points. Start point and end point.
+* 			To make a dotted line, specify a dash length between .5 and 1. 		
+* @usage <pre>var myLine:DashLine = new DashLine();</pre> 
+* 		<pre>var myLine:DashLine = new DashLine(x1, y1, x2, y2, len, gap);</pre>
+* 		<pre>var myLine:DashLine = new DashLine(mc, x1, y1, x2, y2, len, gap);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x1 (Number) start point to define line. Coordinate point x.
+* @param y1 (Number) start point to define line. Coordinate point y.
+* @param x2 (Number) end point to define line. Coordinate point x.
+* @param y2 (Number) end point to define line. Coordinate point y.
+* @param len (Number) length of dash. Defaults to 8.
+* @param gap (Number) length of gap between dashes. Defaults to 8.
+*/
+class de.alex_uhlmann.animationpackage.drawing.DashLine 
+											extends Line 
+											implements IDrawable, 
+													IOutline, 
+													ISingleAnimatable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/	
+	/*animationStyle properties inherited from AnimationCore*/	
+	/** 
+	* @property len_def (Number)(static) default property. length of dash. Defaults to 8.
+	* @property gap_def (Number)(static) default property. length of gap between dashes. Defaults to 8.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).	
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/	
+	public static var len_def:Number = 8;
+	public static var gap_def:Number = 8;	
+	private var len:Number;
+	private var gap:Number;	
+	
+	public function DashLine() {
+		super(false);
+		this.init.apply(this, arguments);
+		this.lineStyle(null);
+		this.animationStyle();
+	}	
+	
+	private function init():Void {
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x1:Number, y1:Number, x2:Number, y2:Number):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:0, y:0});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x1:Number, y1:Number, x2:Number, y2:Number):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:0, y:0});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x1:Number, y1:Number, x2:Number, y2:Number):Void {
+	
+		var len:Number = arguments[4];
+		var gap:Number = arguments[5];
+		this.len = (len == null) ? DashLine.len_def : len;
+		this.gap = (gap == null) ? DashLine.gap_def : gap;
+		super.initShape(x1, y1, x2, y2);		
+	}
+
+	/*inherited from Line*/		
+	/**
+	* @method draw
+	* @description 	Draws the dashed line.
+	* @usage <pre>myLine.draw();</pre>
+	*/
+
+	/**
+	* @method drawBy
+	* @description 	Draws the line without clearing the movieclip.
+	* @usage <pre>myLine.drawBy();</pre>
+	*/
+
+	/**
+	* @method animate
+	* @description 	Draws an animated dashed line.		
+	* @usage  	<pre>myLine.animate(start, end);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	* @return MovieClip that contains the drawing. 
+	*/
+	
+	/**
+	* @method animateBy
+	* @description 	Draws an animated line without clearing the movieclip.		
+	* @usage  	<pre>myLine.animateBy(start, end);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	private function drawLine(v:Number):Void {
+		var p:Object = this.getPointsOnLine(v);		
+		this.clearDrawing();			
+		this.drawNewPoint(p.x, p.y);
+	}	
+	
+	private function drawNewPoint(x2:Number, y2:Number):Void {	
+		this.dashTo(this.x1, this.y1, x2, y2);
+		this.penX = x2;
+		this.penY = y2;		
+	}
+	
+	/*-------------------------------------------------------------
+	mc.dashTo is a metod for drawing dashed (and dotted) 
+	lines. I made this to extend the lineTo function because it
+	doesnÕt have the cutom line types that the in program
+	line tool has. To make a dotted line, specify a dash length
+	between .5 and 1.
+	-------------------------------------------------------------*/
+	private function dashTo(startx:Number, starty:Number, 
+							endx:Number, endy:Number):Void {
+		// ==============
+		// mc.dashTo() - by Ric Ewing (ric at formequalsfunction.com) - version 1.2 - 5.3.2002
+		// 
+		// startx, starty = beginning of dashed line
+		// endx, endy = end of dashed line
+		// len = length of dash
+		// gap = length of gap between dashes
+		// ==============
+		// init vars
+		var seglength:Number, deltax:Number, deltay:Number;
+		var segs:Number, cx:Number, cy:Number;
+		// calculate the legnth of a segment
+		seglength = this.len + this.gap;
+		// calculate the length of the dashed line
+		deltax = endx - startx;
+		deltay = endy - starty;
+		var delta:Number = Math.sqrt((deltax * deltax) + (deltay * deltay));
+		// calculate the number of segments needed
+		segs = Math.floor(Math.abs(delta / seglength));
+		// get the angle of the line in radians
+		var radians:Number = Math.atan2(deltay,deltax);
+		// start the line here
+		cx = startx;
+		cy = starty;
+		// add these to cx, cy to get next seg start
+		deltax = Math.cos(radians)*seglength;
+		deltay = Math.sin(radians)*seglength;
+		// loop through each seg
+		var n:Number;
+		for (n = 0; n < segs; n++) {
+			this.mc.moveTo(cx,cy);
+			this.mc.lineTo(cx+Math.cos(radians)*this.len,cy+Math.sin(radians)*this.len);
+			cx += deltax;
+			cy += deltay;
+		}
+		// handle last segment as it is likely to be partial
+		this.mc.moveTo(cx,cy);
+		delta = Math.sqrt((endx-cx)*(endx-cx)+(endy-cy)*(endy-cy));
+		if(delta>this.len){
+			// segment ends in the gap, so draw a full dash
+			this.mc.lineTo(cx+Math.cos(radians)*this.len,cy+Math.sin(radians)*this.len);
+		} else if(delta>0) {
+			// segment is shorter than dash so only draw what is needed
+			this.mc.lineTo(cx+Math.cos(radians)*delta,cy+Math.sin(radians)*delta);
+		}
+		// move the pen to the end position
+		this.mc.moveTo(endx,endy);
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myLine.lineStyle();</pre>
+	* 		<pre>myLine.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 	
+	* 		
+	* @usage   <pre>myLine.animationStyle(duration);</pre>
+	* 		<pre>myLine.animationStyle(duration, callback);</pre>
+	* 		<pre>myLine.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/*inherited from Line*/
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	
+	/**
+	* @method getX1
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX1();</tt>
+	* @return Number
+	*/	
+	
+	/**
+	* @method setX1
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX1();</tt>
+	* @param point (Number)
+	*/
+	
+	/**
+	* @method getY1
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY1();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setY1
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY1();</tt>
+	* @param point (Number)
+	*/	
+	
+	/**
+	* @method getX2
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX2();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method setX2
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX2();</tt>
+	* @param point (Number)
+	*/	
+	
+	/**
+	* @method getY2
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY2();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method setY2
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY2();</tt>
+	* @param point (Number)
+	*/		
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param milliseconds (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myLine.addEventListener(event, listener);</pre>
+	* 		    <pre>myLine.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myLine.removeEventListener(event, listener);</pre>
+	* 		    <pre>myLine.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myLine.removeAllEventListeners();</pre>
+	* 		    <pre>myLine.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myLine.eventListenerExists(event, listener);</pre>
+	* 			<pre>myLine.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "DashLine";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/DashLine.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Drawer.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Drawer.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Drawer.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,1232 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.drawing.IOutline;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+import de.alex_uhlmann.animationpackage.drawing.Line;
+import de.alex_uhlmann.animationpackage.drawing.DashLine;
+import de.alex_uhlmann.animationpackage.utility.IVisitor;
+import de.alex_uhlmann.animationpackage.utility.IVisitorElement;
+import de.alex_uhlmann.animationpackage.utility.IComposite;
+
+/**
+* @class Drawer
+* @author Alex Uhlmann
+* @description
+* 			 Drawer allows to draw and animate arbitrary shapes/lines and can also
+* 			treat the outline and fill separately.
+* 			Drawer uses the composite design pattern. [GoF]
+* 			There are two different approaches using Drawer:
+* 			</p>
+* 			For most use cases the drawBy/animateBy approach will 
+* 			probably work for you. It is also the most optimized approach. Behind the 
+* 			scences Drawer shares a single movieclip for all children that 
+* 			each represent one outline and another 
+* 			movieclip for the fill. Since all children share a single movieclip 
+* 			the Flash Player connects the different outlines.
+* 			</p>
+* 			Example 1: <a href="Drawer_03.html">(Example .swf)</a> Draw a consistent, filled shape.
+* 			<blockquote><pre>
+*			var part1:Line = new Line(100,100,200,100);
+*			var part2:CubicCurve = new CubicCurve(200,100,250,50,300,150,350,100);
+*			var part3:QuadCurve = new QuadCurve(350,100,400,250,300,400);
+*			var part4:Line = new Line(300,400,90,350,1,8);
+*			var part5:Line = new Line(90,350,100,100);
+*			
+*			var myDraw_mc:MovieClip = this.createEmptyMovieClip("draw_mc",999);
+*			var myDrawer:Drawer = new Drawer(myDraw_mc);
+*			
+*			myDrawer.addChild(part1);
+*			myDrawer.addChild(part2);
+*			myDrawer.addChild(part3);
+*			myDrawer.addChild(part4);
+*			myDrawer.addChild(part5);
+*			
+*			myDrawer.lineStyle(5,0x000000,50);
+*			myDrawer.drawBy();
+*			myDrawer.fillStyle(0xff0000,50);
+*			myDrawer.fill();
+*			</pre></blockquote>
+* 			</p>
+* 			For a much better example, check out  
+* 			<a href="http://www.flash-creations.com/notes/sample_svgtoflash.php">Helen Triolo's usage of Drawer</a>
+* 			 to animate an SVG file at runtime.
+* 			</p>
+* 			For some use cases, however you might want to treat outline styles separately. 
+* 			Here, for each child representing an outline, 
+* 			a new movieclip is created and individual lineStyle 
+* 			properties are applied. To use the draw/animate approach:
+* 			</p>
+* 			Example 2: <a href="Drawer_01.html">(Example .swf)</a> Drawing a filled shape.
+* 			<blockquote><pre>
+*			var part1:DashLine = new DashLine(100,100,200,100);
+*			part1.lineStyle(2,0x000000,50);
+*			var part2:CubicCurve = new CubicCurve(200,100,250,50,300,150,350,100);
+*			part2.lineStyle(1,0xff0000,100);
+*			var part3:QuadCurve = new QuadCurve(350,100,400,250,300,400);
+*			part3.lineThickness = 4;
+*			var part4:DashLine = new DashLine(300,400,90,350,1,8);
+*			part4.lineStyle(6,0x0000ff,100);
+*			var part5:Line = new Line(90,350,100,100);
+*			part5.lineStyle(6,0x00ff00);
+*			
+*			var myDraw_mc:MovieClip = this.createEmptyMovieClip("draw_mc",999);
+*			var myDrawer:Drawer = new Drawer(myDraw_mc);
+*			myDrawer.addChild(part1);
+*			myDrawer.addChild(part2);
+*			myDrawer.addChild(part3);
+*			myDrawer.addChild(part4);
+*			myDrawer.addChild(part5);
+*			
+*			myDrawer.draw();
+*			myDrawer.fillStyle(0xff0000,50);
+*			myDrawer.fill();
+*			</pre></blockquote>
+* 			</p>
+* 			Note, that you could also have used the DashLine class 
+* 			in the drawBy/animateBy approach. If you do, Drawer will create 
+* 			a new movieclip for DashLine and the Flash Player will not be able 
+* 			to connect this outline with other surrounding outlines. 
+* 			</p>
+* 			Example 3: <a href="Drawer_02.html">(Example .swf)</a> Animating a filled shape.
+* 			<blockquote><pre>
+*			AnimationCore.duration_def = 500;
+*			AnimationCore.easing_def = Circ.easeInOut;
+*			
+*			var part1:DashLine = new DashLine(100,100,200,100);
+*			part1.lineStyle(2,0x000000,50);
+*			part1.animationStyle(1000,Sine.easeIn);
+*			var part2:CubicCurve = new CubicCurve(200,100,250,50,300,150,350,100);
+*			part2.lineStyle(1,0xff0000,100);
+*			var part3:QuadCurve = new QuadCurve(350,100,400,250,300,400);
+*			part3.lineThickness = 4;
+*			var part4:DashLine = new DashLine(300,400,90,350,1,8);
+*			part4.lineStyle(6,0x0000ff,100);
+*			var part5:Line = new Line(90,350,100,100);
+*			part5.lineStyle(6,0x00ff00);
+*			part5.animationStyle(1000,Bounce.easeOut);
+*			
+*			var myDraw_mc:MovieClip = this.createEmptyMovieClip("draw_mc",999);
+*			var myDrawer:Drawer = new Drawer(myDraw_mc);
+*			myDrawer.addChild(part1);
+*			myDrawer.addChild(part2);
+*			myDrawer.addChild(part3);
+*			myDrawer.addChild(part4);
+*			myDrawer.addChild(part5);
+*			
+*			myDrawer.addEventListener("onEnd",this,"fillShape");
+*			myDrawer.animate(0,100);
+*			
+*			function fillShape(eventObject:Object) {
+*				myDrawer.fillStyle(0xff0000,50);
+*				myDrawer.fill();
+*				myDrawer.fillMovieclip._alpha = 0;
+*				new Alpha(myDrawer.fillMovieclip).run(100,1000);
+*				new ColorTransform(myDrawer.lineMovieclip).run(0xffff00,0,3000,Quad.easeOut);
+*			}
+*			</pre></blockquote> 
+* 			<p>For another example take a look at example no. 2 from the Animator class. 
+* 
+* @usage    <pre>var myDrawer:Drawer = new Drawer();</pre> 
+* 		<pre>var myDrawer:Drawer = new Drawer(mc);</pre>
+* 
+* @param mc (MovieClip) Movieclip container that will be used for drawing.
+*/
+class de.alex_uhlmann.animationpackage.drawing.Drawer 
+											extends Shape 
+											implements ISingleAnimatable, 
+													IOutline, 
+													IVisitorElement, 
+													IComposite {	
+
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/
+	/** 
+	* @property movieclip (MovieClip) Movieclip that contains the drawing.
+	* @property lineMovieclip (MovieClip) Movieclip that contains all outlines.
+	* @property fillMovieclip (MovieClip) Movieclip that contains the fill.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.
+	*/	
+	private var childsArr:Array;
+	private var start:Number;
+	private var end:Number;	
+	private var firstChild:Object;
+	private var currentChild:Object;
+	private var childDuration:Number;
+	private var position:Number = 0;
+	private var animateMode:String = "JOIN";
+	private var percentages:Array;
+	private var backwards:Boolean = false;
+	private var sequenceArr:Array;
+	private var redraw:Boolean = true;	
+	private var areMovieclipsInjected:Boolean = false;
+	private var m_lineMovieclip:MovieClip;
+	private var m_fillMovieclip:MovieClip;	
+	
+	public function Drawer() {			
+		super();		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.mc = arguments[0];
+		} else {	
+			this.mc = this.createClip({name:"apDraw", x:0, y:0});
+		}
+		this.childsArr = new Array();
+		this.sequenceArr = new Array();
+		super.lineStyle(null);
+		this.fillStyle(null);	
+	}
+
+	/**
+	* @method draw
+	* @description 	Draws the contents of the composite.
+	* @usage <pre>myInstance.draw();</pre>
+	*/
+	public function draw(Void):Void {
+		this.redraw = true;
+		
+		this.initLineMovieclip();
+		this.injectNewMovieclipsToChilds();
+		
+		this.firstChild = this.childsArr[0];
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];
+			if(child instanceof Drawer) {				
+				child.draw();
+			} else {
+				this.lineMovieclip.clear();
+				this.fillMovieclip.clear();					
+				child.draw();
+			}			
+		}
+	}
+	
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the contents of the composite. 
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/	
+	public function drawBy(Void):Void {	
+		this.redraw = false;
+		
+		this.initLineMovieclip();		 	
+		this.injectSingleMovieclipToChilds();
+	
+		this.lineMovieclip.lineStyle(this.lineThickness, 
+									this.lineRGB, 
+									this.lineAlpha);
+
+		
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];
+			if(child instanceof Drawer) {				
+				child.drawBy();
+			} else {
+				if(this.firstChild == null) {
+					this.firstChild = child;
+					this.lineMovieclip.moveTo(child.getX1(), child.getY1());
+				}
+				child.reset();
+				child.drawTo();
+			}	
+		}
+		this.firstChild = null;
+	}
+	
+	public function invokeAnimation(start:Number, end:Number):Void {		
+		var goto:Boolean;
+		var percentage:Number;
+		if(end == null) {
+			goto = true;
+			percentage = end = start;
+			start = 0;			
+		} else {
+			goto = false;
+			this.start = start;
+			this.end = end;
+			this.tweening = true;
+		}
+			
+		var i:Number, len:Number = this.childsArr.length;
+		var fChild:Object;
+		
+		var posStart:Number = start / 100 * len;
+		var posEnd:Number = end / 100 * len;
+		
+		this.setStartValue(posStart);
+		this.setEndValue(posEnd);
+
+		if(this.initialized == false) {
+			this.initLineMovieclip();
+			if(this.redraw) {				
+				this.injectNewMovieclipsToChilds();
+			} else {			 	
+				this.injectSingleMovieclipToChilds();
+				this.lineMovieclip.lineStyle(this.lineThickness, 
+											this.lineRGB, 
+											this.lineAlpha);
+			}
+			this.initialized = true;
+		} else {
+			if(this.redraw) {				
+				this.fillMovieclip.clear();
+			} else {
+				this.lineMovieclip.clear();
+				this.fillMovieclip.clear();			
+				this.lineMovieclip.lineStyle(this.lineThickness, 
+											this.lineRGB, 
+											this.lineAlpha);				
+			}
+		}
+		
+		if(this.animateMode == "JOIN") {		
+		
+			if(!goto) {
+				var details:Object = this.getAnimateDetails(start, end, this.childsArr, this);
+				this.backwards = details.backwards;
+				this.position = details.position;			
+				var roundedPosStart:Number = details.roundedPosStart;
+				var roundedPosEnd:Number = details.roundedPosEnd;
+				this.percentages = details.percentages;				
+				
+				fChild = this.currentChild = this.childsArr[roundedPosStart];
+				this.firstChild = fChild;
+				if(this.redraw) {
+					fChild.movieclip.clear();
+					fChild.initControlPoints();
+					fChild.setInitialized(true);
+					fChild.animate(this.percentages[this.position-1].start, this.percentages[this.position-1].end);
+				} else {
+					this.lineMovieclip.moveTo(fChild.getX1(), fChild.getY1());
+					fChild.initControlPoints();
+					fChild.setInitialized(true);					
+					fChild.animateTo(this.percentages[this.position-1].start, this.percentages[this.position-1].end);
+				}
+
+			} else {				
+
+				if(percentage < 0) {
+					this.invokeAnimation(0);
+					return;
+				} else if(percentage > 100) {
+					this.invokeAnimation(100);
+					return;
+				}
+				var posPerc:Number = percentage / 100 * (len);
+				var roundedPosPerc:Number = Math.floor(posPerc);	
+				var perc_loc:Number = (posPerc - roundedPosPerc) * 100;
+				this.position = roundedPosPerc + 1;
+				this.currentChild = this.childsArr[roundedPosPerc];				
+				
+				for (i = 0; i < len; i++) {
+					var child:Object = this.childsArr[i];
+					if(i < roundedPosPerc) {
+						child.goto(100);
+					} else {
+						child.goto(0);
+					}
+				}
+				
+				this.childsArr[roundedPosPerc].goto(perc_loc);
+				
+				if(percentage == 0) {
+					this.dispatchEvent({type:"onStart", 
+									value:this.getStartValue(),
+									childDuration:this.childDuration});
+				} else if(percentage == 100) {
+					this.dispatchEvent({type:"onEnd", 
+									value:this.getEndValue(), 
+									childDuration:this.childDuration});
+				} else {
+					this.dispatchEvent({type:"onUpdate", 
+									value:this.getCurrentValue(), 
+									childDuration:this.childDuration});		
+				}				
+			}
+			
+		} else {
+
+			this.percentages = new Array();
+			this.position = 1;
+			for (i = 0; i < len; i++) {
+				var child:Object = this.childsArr[i];
+				this.sequenceArr.push(this.childsArr[i+1]);
+				child.addEventListener("onEnd", this);				
+				this.percentages[i] = {start:start, end:end};
+			}		
+			fChild = this.currentChild = this.childsArr[0];
+			this.firstChild = fChild;
+			if(this.redraw) {
+				fChild.setInitialized(true);
+				fChild.initControlPoints();		
+				fChild.movieclip.clear();							
+				fChild.animate(start, end);
+			} else {
+				this.lineMovieclip.moveTo(fChild.getX1(), fChild.getY1());
+				fChild.setInitialized(true);
+				fChild.initControlPoints();				
+				fChild.animateTo(start, end);
+			}
+		}
+		if(!goto) {
+			this.myAnimator = fChild.myAnimator;
+			this.childDuration = fChild.duration;
+			this.dispatchEvent.apply(this, [ {type:"onStart", 
+												value:this.getStartValue(),
+												nextChild:fChild, 
+												lastChild:null, 
+												childDuration:this.childDuration} ]);			
+		}		
+	}
+	
+	private function initLineMovieclip(Void):Void {	
+		if(this.m_lineMovieclip == null) {
+			this.m_lineMovieclip = this.createClip({parentMC:this.mc, name:"apDraw"});
+		}
+	}
+	
+	private function injectNewMovieclipsToChilds(Void):Void {	
+		if(!this.areMovieclipsInjected) {
+			var i:Number, len:Number = this.childsArr.length;
+			for (i = 0; i < len; i++) {				
+				var child:Object = this.childsArr[i];
+				child.movieclip.removeMovieClip();
+				child.movieclip = this.createClip({parentMC:this.m_lineMovieclip, name:"apDraw"});
+			}
+			this.areMovieclipsInjected = true;
+		}		
+	}
+	
+	private function injectSingleMovieclipToChilds(Void):Void {	
+		if(!this.areMovieclipsInjected) {
+			var i:Number, len:Number = this.childsArr.length;
+			for (i = 0; i < len; i++) {
+				var child:Object = this.childsArr[i];			
+				child.movieclip.removeMovieClip();
+				child.movieclip = this.m_lineMovieclip;
+				child.reset();
+			}		
+			this.areMovieclipsInjected = true;
+		}
+	}	
+	
+	/**
+	* @method animate
+	* @description 	animates the contents of the composite.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/		
+	public function animate(start:Number, end:Number):Void {	
+		this.redraw = true;
+		super.animate(start, end);
+	}
+	
+	/**
+	* @method animateBy
+	* @description 	animateBy the contents of the composite.
+	* @usage   <pre>myInstance.animateBy(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/		
+	public function animateBy(start:Number, end:Number):Void {	
+		this.redraw = false;		
+		super.animate(start, end);
+	}	
+	
+	/**
+	* @method fill
+	* @description 	Fills the contents of the composite.
+	* @usage <pre>myInstance.fill();</pre>
+	*/	
+	public function fill(Void):Void {
+		
+		this.m_fillMovieclip = this.createClip({parentMC:this.mc, name:"apDraw"});
+		/*
+		* TRICKY: Drawer creates two movieclips. One for the outline and one for the fill. 
+		* This workaround is needed because MovieClip.beginFill 
+		* and MovieClip.endFill only work in one frame. If the user uses animate and wants to fill 
+		* the shape afterwards this workaround comes into play. Furthermore, the user can manipulate the 
+		* fill and outline by itself.
+		*/
+		this.m_fillMovieclip.lineStyle();
+		var penPos:Object = this.firstChild.getPenPosition();
+		penPos.x = this.firstChild.getX1();
+		penPos.y = this.firstChild.getY1();
+		/*
+		* TRICKY: prevent the MovieClip.moveTo() to be invoked one every child.
+		* Tell each child that the pen position is already in place.
+		* In MovieClip.beginFill() - endFill() blocks the moveTo() method 
+		* shall only be invoked once before beginFill().
+		*/
+		this.m_fillMovieclip.moveTo(penPos.x, penPos.y);
+		this.firstChild.setPenPosition(penPos);		
+		
+		if (this.fillRGB != null && this.fillGradient == false) {			
+			this.m_fillMovieclip.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.m_fillMovieclip.beginGradientFill(this.gradientFillType, 
+													this.gradientColors, 
+													this.gradientAlphas, 
+													this.gradientRatios, 
+													this.gradientMatrix);
+		}
+		//Hijack children to draw the outline of the fill movieclip.
+		this.drawFillOutline();
+		//The fill should stay behind the outline.
+		this.m_fillMovieclip.swapDepths(this.m_lineMovieclip);
+		this.m_fillMovieclip.endFill();
+	}	
+	
+	private function drawFillOutline():Void {
+		var lastChild:Object = this.firstChild;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];
+			if(child instanceof DashLine) {
+				child.reset();
+				child = new Line(child.getX1(),child.getY1(),
+								child.getX2(),child.getY2());
+			}
+			//the fill doesn't need an outline. But save properties before overwriting.
+			var lineThickness:Number = child.lineThickness;
+			var lineRGB:Number = child.lineRGB;
+			var lineAlpha:Number = child.lineAlpha;
+			child.lineStyle();
+			child.setPenPosition(lastChild.getPenPosition());
+			var origMC:MovieClip = child.movieclip;
+			child.movieclip = this.m_fillMovieclip;
+			if(child instanceof Drawer) {
+				child.draw();
+			} else {
+				child.reset();
+				child.drawBy();				
+			}
+			child.initControlPoints();
+			if(this.redraw) {
+				child.setInitialized(false);
+			}
+			child.movieclip = origMC;
+			child.lineStyle(lineThickness, lineRGB, lineAlpha);
+			lastChild = child;
+		}		
+	}
+		
+	private function getAnimateDetails(start:Number, end:Number, 
+										childsArr:Array, ref:Object):Object {
+		
+		
+		var backwards:Boolean;
+		if(start > end) {
+			backwards = true;				
+		} else {
+			backwards = false;
+		}
+		/*			
+		* To compute start and end values for all childs combined, 
+		* I first compute the childs where the tween will start and end. (rule of three)
+		* The integer part of the number posStart and posEnd represents that.
+		* The fractional part of those numbers represent the percentage to be animated in integer child.
+		*/
+		var i:Number, len:Number = this.childsArr.length;
+		var posStart:Number = start / 100 * (len);
+		var posEnd:Number = end / 100 * (len);
+		
+		var roundedPosStart:Number = Math.floor(posStart);
+		var roundedPosEnd:Number = Math.floor(posEnd);			
+		var start_loc:Number;
+		if(posStart > roundedPosStart) {				
+			start_loc = (posStart - roundedPosStart) * 100;					
+		} else {
+			if(backwards) {
+				roundedPosStart--;
+				start_loc = 100;
+			} else {					
+				start_loc = 0;
+			}
+		}			
+		var end_loc:Number;
+		if(posEnd > roundedPosEnd) {				
+			end_loc = (posEnd - roundedPosEnd) * 100;					
+		} else {				
+			if(backwards) {
+				end_loc = 0;
+			} else {
+				roundedPosEnd--;
+				end_loc = 100;
+			}				
+		}
+		
+		this.position = roundedPosStart+1;		
+		
+		//apply animate state to all children.			
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];			
+			if(!this.redraw) {
+				child.mode = "DRAWTO";
+			}
+			if(backwards) {
+				if(i > roundedPosStart) {
+					child.goto(0);
+				} else {
+					child.goto(100);
+				}
+			}
+		}
+		
+		for (i = len-1; i > -1; i--) {
+			var child:Object = this.childsArr[i];
+			if(!this.redraw) {
+				child.mode = "DRAWTO";
+			}		
+			if(!backwards) {
+				if(i < roundedPosStart) {
+					child.goto(100);
+				} else {
+					child.goto(0);
+				}
+			}
+			child.addEventListener("onUpdate", this);
+		}		
+
+		//reset succossors.
+		this.sequenceArr = new Array();
+		
+		var percentages:Array = new Array();
+		var child:Object;
+		//for forward tweening
+		for (i = roundedPosStart; i < roundedPosEnd; i++) {
+			child = childsArr[i];
+			this.sequenceArr.push(this.childsArr[i+1]);
+			child.addEventListener("onEnd", ref);
+			if(i == roundedPosStart) {
+				percentages[i] = {start:start_loc, end:100};
+			} else {
+				percentages[i] = {start:0, end:100};
+			}
+		}
+		//for backward tweening
+		for (i = roundedPosStart; i > roundedPosEnd; i--) {
+			child = childsArr[i];
+			this.sequenceArr.push(this.childsArr[i-1]);
+			child.addEventListener("onEnd", ref);
+			if(i == roundedPosStart) {
+				percentages[i] = {start:start_loc, end:0};
+			} else {
+				percentages[i] = {start:100, end:0};
+			}
+		}
+		child = childsArr[roundedPosEnd];
+		child.addEventListener("onEnd", ref);
+		if(backwards) {
+			percentages[roundedPosEnd] = {start:100, end:end_loc};
+		} else {
+			percentages[roundedPosEnd] = {start:0, end:end_loc};
+		}
+		
+		var details = new Object();
+		details.backwards = backwards;
+		details.position = roundedPosStart+1;
+		details.roundedPosStart = roundedPosStart;
+		details.roundedPosEnd = roundedPosEnd;		
+		details.percentages = percentages;		
+		return details;
+	}
+	
+	public function onStart(eventObject:Object):Void {		
+		this.dispatchEvent({type:"onStart", 
+							value:this.getStartValue(),
+							childDuration:this.childDuration});
+	}	
+	
+	public function onUpdate(eventObject:Object):Void {		
+		this.dispatchEvent({type:"onUpdate", 
+							value:this.getCurrentValue(), 
+							childDuration:this.childDuration});
+	}	
+	
+	public function onEnd(eventObj:Object):Void {
+		
+		eventObj.target.removeEventListener("onEnd", this);
+		var successor:Object = this.sequenceArr.shift();
+		
+		this.childDuration = successor.duration;
+		
+		if(successor == null) {
+			this.tweening = false;
+			this.duration = 0;			
+			APCore.broadcastMessage(this.callback, this);			
+			this.dispatchEvent.apply(this, [ {type:"onEnd", 
+												value:this.getEndValue(),
+												nextChild:null, 
+												lastChild:eventObj.target, 
+												childDuration:null} ]);			
+		} else {
+			
+			/*backwards will only be true in Sequence mode JOIN*/
+			if(this.backwards) {
+				this.position--;
+			} else {
+				this.position++;
+			}			
+			this.currentChild = successor;
+			if(this.redraw) {
+				successor.movieclip.clear();
+				successor.movieclip.lineStyle(successor.lineThickness, 
+											successor.lineRGB, 
+											successor.lineAlpha);
+			}
+			
+			this.dispatchEvent.apply(this, [ {type:"onUpdatePosition",
+											value:this.getCurrentValue(),
+											nextChild:successor, 
+											lastChild:eventObj.target, 
+											childDuration:this.childDuration} ]);			
+			
+			var animateMeth:String;
+			if(this.redraw) {				
+				animateMeth = "animate";
+			} else {
+				animateMeth = "animateTo";
+			}
+			successor.initControlPoints();
+			successor.setInitialized(true);
+			successor[animateMeth].apply(successor, [this.percentages[this.position-1].start, 
+												this.percentages[this.position-1].end]);
+			this.myAnimator = successor.myAnimator;
+		}		
+	}
+	
+	/**
+	* @method lineStyle
+	* @description 	define outline. Overwrites lineStyle settings from childs.
+	* 		
+	* @usage   <pre>myInstance.lineStyle();</pre>
+	* 		<pre>myInstance.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/	
+	public function lineStyle(lineThickness:Number, lineRGB:Number, lineAlpha:Number):Void {		
+		super.lineStyle(lineThickness, lineRGB, lineAlpha);
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {			
+			this.childsArr[i].lineStyle(lineThickness, lineRGB, lineAlpha);			
+		}
+	}
+	
+	/**
+	* @method fillStyle
+	* @description 	 define fill.		
+	* 		
+	* @usage   <pre>myInstance.fillStyle();</pre>
+	* 		<pre>myInstance.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myInstance.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/
+
+	/**
+	* @method animationStyle
+	* @description 	set animation settings. Overwrites animationStyle settings from childs.
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation(s) in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation(s). See APCore class.
+	*/	
+	public function animationStyle(duration:Number, easing:Object, callback:String):Void {
+		super.animationStyle(duration, easing, callback);
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {					
+			this.childsArr[i].animationStyle(duration, easing);
+		}
+		this.duration = duration;
+		this.callback = callback;
+	}
+	
+	/**
+	* @method setAnimateMode
+	* @description 	sets the animate mode. If JOIN, the start and end percentage 
+	* 				parameters influences the composite animation as a whole. Defaults to JOIN. 
+	* 				See class documentation of Sequence for details.
+	* @usage   <tt>myInstance.setAnimateMode();</tt>
+	* @param animateMode (String) Either EACH or JOIN.
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	public function setAnimateMode(animateMode:String):Boolean {
+		if(animateMode == "EACH" || animateMode == "JOIN") {	
+			this.animateMode = animateMode;
+		} else {
+			return false;
+		}
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];
+			if(child instanceof Drawer) {
+				child.setAnimateMode(animateMode);
+			}
+		}
+		return true;	
+	}
+	
+	/**
+	* @method getAnimateMode
+	* @description 	returns the current animate mode.
+	* @usage   <tt>myInstance.getAnimateMode();</tt>
+	* @return String
+	*/
+	public function getAnimateMode(Void):String {
+		return this.animateMode;
+	}
+
+	/**
+	* @method getChild
+	* @description 	returns the current child of the sequence.
+	* @usage   <tt>myInstance.getChild();</tt>
+	* @return IOutline
+	*/	
+	public function getChild(Void):IOutline {		
+		return IOutline(this.currentChild);
+	}
+	
+	/**
+	* @method getChildren
+	* @description 	returns an Array of all children of the sequence. 
+	* 				Could contain other Sequences.
+	* @usage   <tt>myInstance.getChildren();</tt>
+	* @return Array
+	*/	
+	public function getChildren(Void):Array {
+		return this.childsArr;
+	}
+	
+	/**
+	* @method getNextChild
+	* @description 	returns the next child of the sequence.
+	* @usage   <tt>myInstance.getNextChild();</tt>
+	* @return IOutline
+	*/	
+	public function getNextChild(Void):IOutline {
+		if(this.animateMode == "JOIN" && this.backwards) {
+			return IOutline(this.childsArr[this.position-2]);
+		} else {
+			return IOutline(this.childsArr[this.position]);
+		}
+	}
+	
+	/**
+	* @method getPreviousChild
+	* @description 	returns the previous child of the sequence.
+	* @usage   <tt>myInstance.getPreviousChild();</tt>
+	* @return IAnimatable
+	*/	
+	public function getPreviousChild(Void):IOutline {		
+		if(this.animateMode == "JOIN" && this.backwards) {
+			if(this.position-1 == this.childsArr.length) {
+				return IOutline(this.childsArr[this.position-1]);
+			} else {
+				return IOutline(this.childsArr[this.position]);
+			}			
+		} else {
+			return IOutline(this.childsArr[this.position-2]);
+		}
+	}	
+	
+	/**
+	* @method getChildDuration
+	* @description 	returns the duration of every single child in constrast to the duration property, 
+	* 				which is the duration of the whole Sequence.  
+	* @usage   <tt>myInstance.getChildDuration();</tt>
+	* @return Number
+	*/	
+	public function getChildDuration(Void):Object {		
+		return this.childDuration;
+	}
+	
+	/**
+	* @method addChild
+	* @description 	adds a primitive or composite to the composite instance of Drawer 
+	* See class description.
+	* @usage  <pre>myInstance.addChild(component);</pre>
+	* @param component (IOutline) Must be compatible to IOutline.
+	* @return IOutline class that was added.
+	*/	
+	public function addChild(component:IOutline):IOutline {		
+		if(component instanceof Object) {
+			this.childsArr.push(component);
+			return component;
+		}
+	}
+
+	/**
+	* @method removeChild
+	* @description 	removes a primitive or composite from the composite instance of Drawer 
+	* See class description.
+	* @usage  <pre>myInstance.removeChild(component);</pre>
+	* @param component (IOutline) Must be compatible to IOutline.	
+	*/
+	public function removeChild(component:IOutline):Void {		
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			if(this.childsArr[i] == component) {
+				this.childsArr.splice(i, 1);
+			}
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings.
+	* @usage <pre>myInstance.clear();</pre>
+	*/
+	public function clear(Void):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			var child:Object = this.childsArr[i];			
+			child.mc.clear();			
+		}
+		this.fillMovieclip.clear();
+	}	
+	
+	/**
+	* @method accept
+	* @description 	Allow a visitor to visit its elements. See Visitor design pattern [GoF].
+	* @usage  <pre>myInstance.accept(visitor);</pre>
+	* @param visitor (IVisitor) Must be compatible to de.alex_uhlmann.animationpackage.utility.IVisitor.	
+	*/
+	public function accept(visitor:IVisitor):Void {
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			visitor.visit(this.childsArr[i]);			
+		}
+	}
+	
+	public function get lineMovieclip():MovieClip {
+		return this.m_lineMovieclip;
+	}
+	
+	public function set lineMovieclip(m_lineMovieclip:MovieClip):Void {
+		this.m_lineMovieclip= m_lineMovieclip;
+	}	
+	
+	public function get fillMovieclip():MovieClip {
+		return this.m_fillMovieclip;
+	}
+	
+	public function set fillMovieclip(m_fillMovieclip:MovieClip):Void {
+		this.m_fillMovieclip= m_fillMovieclip;
+	}
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	public function setOptimizationMode(optimize:Boolean):Void {
+		this.equivalentsRemoved = optimize;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			this.childsArr[i].setOptimizationMode(optimize);		
+		}
+	}	
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode(tweenMode);</tt> 	
+	* @param tweenMode (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	public function setTweenMode(tweenMode:String):Boolean {
+		this.tweenMode = tweenMode;
+		var isSet:Boolean;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			isSet =this.childsArr[i].setTweenMode(tweenMode);		
+		}
+		return isSet;
+	}
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode(durationMode);</tt> 	
+	* @param durationMode (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/	
+	public function setDurationMode(durationMode:String):Boolean {
+		this.durationMode = durationMode;
+		var isSet:Boolean;
+		var i:Number, len:Number = this.childsArr.length;
+		for (i = 0; i < len; i++) {
+			isSet = this.childsArr[i].setDurationMode(durationMode);		
+		}
+		return isSet;
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. First position of sequence. Always zero.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	public function getStartValue(Void):Number {		
+		var startValue:Number = super.getStartValue();
+		if(startValue == null) {
+			startValue = 0;
+		}		
+		return startValue;
+	}	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. first position of sequence. 
+	* 				Last position of sequence. Number of childs added to the sequence.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	public function getEndValue(Void):Number {		
+		var endValue:Number = super.getEndValue();
+		if(endValue == null) {
+			endValue = 100;
+		}
+		return endValue;
+	}	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Current position of sequence.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	public function getCurrentValue(Void):Number {
+		return this.position;
+	}	
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/
+	public function getCurrentPercentage(Void):Number {
+		
+		var pos:Number = this.getCurrentValue()-1;
+		var perc:Number = this.currentChild.getCurrentPercentage();
+		if(typeof(perc) != "number" || isNaN(perc)) {
+			perc = 0;			
+		}
+		var currentValue:Number = pos + perc / 100;		
+		return currentValue / (this.childsArr.length) * 100;		
+	}	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when sequence starts.<br>
+	* 			<b>onUpdate</b>, broadcasted when sequence animates a new object.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Sequence) event source.<br>
+	* 			<b>nextChild</b> (IAnimatable) next child in sequence to be animated.<br>
+	* 			<b>lastChild</b> (IAnimatable) last child in sequence that has been animated.<br>
+	* 			<b>childDuration</b> (Number) duration of every single child.<br>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+
+	public function toString(Void):String {
+		return "Drawer";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Drawer.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Ellipse.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Ellipse.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Ellipse.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,285 @@
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+
+/**
+* @class Ellipse
+* @author Alex Uhlmann
+* @description Ellipse is a class for creating circles and ellipses.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw an ellipse with default parameters. Results in a circle with a radius of 50.	
+* 			<blockquote><pre>
+*			var myEllipse:Ellipse = new Ellipse();
+*			myEllipse.draw();
+*			</pre></blockquote> 
+* 			Example 2: <a href="Ellipse_02.html">(Example .swf)</a> draw an ellipse with custom parameters.		
+* 			<blockquote><pre>
+*			var myEllipse:Ellipse = new Ellipse(275,200,50,100);
+*			myEllipse.lineStyle(3,0xff0000,100);
+*			myEllipse.fillStyle(0x000000,100);
+*			myEllipse.draw();
+*			</pre></blockquote>
+* 			Example 3. <a href="Ellipse_03.html">(Example .swf)</a> A circle.
+*			<blockquote><pre>
+* 			var myEllipse:Ellipse = new Ellipse(275,200,100,100);
+*			myEllipse.lineStyle(2,0xff0000,100);
+*			myEllipse.fillStyle(0x000000,100);
+*			myEllipse.draw();
+* 			</pre></blockquote>			
+* @usage <pre>var myEllipse:Ellipse = new Ellipse();</pre> 
+* 		<pre>var myEllipse:Ellipse = new Ellipse(x, y, xradius, yradius);</pre>
+*		<pre>var myEllipse:Ellipse = new Ellipse(mc, x, y, xradius, yradius);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param xradius (Number) X radius of ellipse.
+* @param yradius (Number) Y radius of ellipse.
+*/
+class de.alex_uhlmann.animationpackage.drawing.Ellipse 
+										extends Shape 
+										implements IDrawable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/		
+	/** 
+	* @property xradius_def (Number)(static) default property. X radius of ellipse. Defaults to 50.
+	* @property yradius_def (Number)(static) default property. Y radius of ellipse. Defaults to 50.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.	
+	*/
+	public static var yradius_def:Number = 50;
+	public static var xradius_def:Number = 50;
+	private var x:Number = 0;
+	private var y:Number = 0;
+	private var xradius:Number;
+	private var yradius:Number;	
+	
+	public function Ellipse() {
+		super(true);
+		this.init.apply(this,arguments);
+		this.fillStyle(null);		
+	}
+	
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, xradius:Number, yradius:Number):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:x, y:y});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, xradius:Number, yradius:Number):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});		
+		this.initShape.apply(this,arguments);
+	}
+	
+	private function initShape(x:Number, y:Number, xradius:Number, yradius:Number):Void {
+	
+		this.xradius = (xradius == null) ? Ellipse.xradius_def : xradius;
+		this.yradius = (yradius == null) ? Ellipse.yradius_def : yradius;
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws ellipses.
+	* @usage <pre>myEllipse.draw();</pre>
+	*/
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/	
+	
+	/**
+	* @method getSize
+	* @description 	Returns the dimensions of the ellipse.
+	* @usage  <pre>myEllipse.getSize();</pre>
+	* @return Object that contains w for with and h for height properties that define the dimension of the drawing in pixels. 
+	*/	
+	public function getSize(Void):Object {		
+		return { w:this.xradius * 2, h:this.yradius * 2 };	
+	}
+		
+	/**
+	* @method setSize
+	* @description 	Sets the dimensions of the ellipse.		
+	* 		
+	* @usage   <pre>myEllipse.setSize(width, height);</pre>
+	* 	  
+	* @param width (Number) width of ellipse in pixels.
+	* @param height (Number) height of ellipse in pixels.
+	*/	
+	public function setSize(width:Number, height:Number):Void {	
+		this.xradius = width / 2;
+		this.yradius = height / 2;		
+	}
+	
+	private function drawNew(Void):Void {		
+		this.mc.moveTo(this.x, this.y);
+		if (this.fillRGB != null && this.fillGradient == false) {
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, this.gradientColors, this.gradientAlphas, this.gradientRatios, this.gradientMatrix);
+		}		
+		this.drawEllipse(this.x, this.y, this.xradius, this.yradius);
+		this.mc.endFill();
+	}	
+	
+	/*-------------------------------------------------------------
+	drawEllipse() is a method for creating circles and
+	ellipses. Hopefully this one is pretty straight
+	forward. This method, like most of the others, is
+	not as optimized as it could be. This was a
+	conscious decision to keep the code as accessible as
+	possible for those either new to AS or to the math
+	involved in plotting points on a curve.
+	-------------------------------------------------------------*/
+	private function drawEllipse(x:Number, y:Number, radius:Number, yRadius:Number):Void {
+		// ==============
+		// drawEllipse() - by Ric Ewing (ric at formequalsfunction.com) - version 1.1 - 4.7.2002
+		// 
+		// x, y = center of ellipse
+		// radius = radius of ellipse. If [optional] yRadius is defined, r is the x radius.
+		// yRadius = [optional] y radius of ellipse.
+		// ==============
+
+		// init variables
+		var theta:Number, xrCtrl:Number, yrCtrl:Number, angle:Number;
+		var angleMid:Number, px:Number, py:Number, cx:Number, cy:Number;
+		// if only yRadius is undefined, yRadius = radius
+		if (yRadius == undefined) {
+			yRadius = radius;
+		}
+		// covert 45 degrees to radians for our calculations
+		theta = Math.PI/4;
+		// calculate the distance for the control point
+		xrCtrl = radius/Math.cos(theta/2);
+		yrCtrl = yRadius/Math.cos(theta/2);
+		// start on the right side of the circle
+		angle = 0;
+		this.mc.moveTo(x+radius, y);
+		// this loop draws the circle in 8 segments
+		var i:Number;
+		for (i = 0; i<8; i++) {
+			// increment our angles
+			angle += theta;
+			angleMid = angle-(theta/2);
+			// calculate our control point
+			cx = x+Math.cos(angleMid)*xrCtrl;
+			cy = y+Math.sin(angleMid)*yrCtrl;
+			// calculate our end point
+			px = x+Math.cos(angle)*radius;
+			py = y+Math.sin(angle)*yRadius;
+			// draw the circle segment
+			this.mc.curveTo(cx, cy, px, py);
+		}
+	}	
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myEllipse.lineStyle();</pre>
+	* 		<pre>myEllipse.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.		
+	* 		
+	* @usage   <pre>myEllipse.fillStyle();</pre>
+	* 		<pre>myEllipse.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		if(registrationObj.position == "CENTER") {		
+			this.x = 0;
+			this.y = 0;
+		} else {	
+			this.x = this.xradius + registrationObj.x;
+			this.y = this.yradius + registrationObj.y;			
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "Ellipse";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Ellipse.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Gear.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Gear.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Gear.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,421 @@
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+
+/**
+* @class Gear
+* @author Alex Uhlmann
+* @description Gear is a class for drawing gears... you know, cogs with teeth 
+* 			and a hole in the middle where the axle goes? FYI: if you modify 
+* 			this to draw the hole polygon in the opposite direction, it will remain
+*			transparent if the gear is used for a mask.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a gear with default parameters.		
+* 			<blockquote><pre>
+*			var myGear:Gear = new Gear();
+*			myGear.draw();
+*			</pre></blockquote> 
+* 			Example 2: <a href="Gear_02.html">(Example .swf)</a> draw a gear with custom parameters.		
+* 			<blockquote><pre>
+*			var myGear:Gear = new Gear(275,200,40,50,10,8,15);
+*			myGear.lineStyle(2,0xff0000,100);
+*			myGear.fillStyle(0xff0000,100);
+*			myGear.draw();
+*			</pre></blockquote> 			
+* 			Example 3: 
+* 			<blockquote><pre>
+* 			var myGear:Gear = new Gear(275,200,40,25,10);
+* 			myGear.lineStyle(2,0xff0000,100);
+* 			myGear.fillStyle(0xff0000,100);
+*			myGear.draw();
+*			</pre></blockquote>
+* 			Example 4: <a href="Gear_04.html">(Example .swf)</a> Kind of a sun.
+* 			<blockquote><pre>
+*			var myGear:Gear = new Gear(275,200,30,100,10);
+*			myGear.lineStyle(2,0xff0000,100);
+*			myGear.fillStyle(0xff0000,100);
+*			myGear.draw();
+*			</pre></blockquote> 		
+* @usage <pre>var myGear:Gear = new Gear();</pre> 
+* 		<pre>var myGear:Gear = new Gear(x, y, innerRadius, outerRadius, sides, holeSides, holeRadius);</pre>
+* 		<pre>var myGear:Gear = new Gear(mc, x, y, innerRadius, outerRadius, sides, holeSides, holeRadius);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param innerRadius (Number) Radius of the indent of the teeth.
+* @param outerRadius (Number) Outer radius of the teeth.
+* @param sides (Number) Number of teeth on gear. (must be > 2)	
+* @param holeSides (Number) draw a polygonal hole with this many sides (must be > 2). Defaults to 8.
+* @param holeRadius (Number) size of hole. Defaults to 3.
+*/
+class de.alex_uhlmann.animationpackage.drawing.Gear 
+										extends Shape 
+										implements IDrawable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/
+	/** 
+	* @property innerRadius_def (Number)(static) default property. Radius of the indent of the teeth.
+	* @property outerRadius_def (Number)(static) default property. Outer radius of the teeth.
+	* @property sides_def (Number)(static) default property. Number of teeth on gear. (must be > 2). Defaults to 10.
+	* @property holeSides_def_def (Number)(static) default property. draw a polygonal hole with this many sides (must be > 2). Defaults to 8.
+	* 
+	* @property movieclip (MovieClip) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.
+	*/
+	public static var innerRadius_def:Number = 80;
+	public static var outerRadius_def:Number = 100;	
+	public static var sides_def:Number = 10;
+	public static var holeSides_def:Number = 8;	
+	public static var holeRadius_def:Number = 20;
+	private var x:Number = 0;
+	private var y:Number = 0;
+	private var innerRadius:Number;
+	private var outerRadius:Number;
+	private var sides:Number;
+	private var angle:Number;
+	private var holeSides:Number;
+	private var holeRadius:Number;
+	
+	public function Gear() {
+		super(true);
+		this.init.apply(this,arguments);
+		this.fillStyle(null);		
+	}
+	
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, innerRadius:Number, outerRadius:Number, 
+						holeSides:Number, holeRadius:Number, sides:Number):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:x, y:y});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, innerRadius:Number, outerRadius:Number, 
+					holeSides:Number, holeRadius:Number, sides:Number):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x:Number, y:Number, innerRadius:Number, outerRadius:Number, 
+					holeSides:Number, holeRadius:Number, sides:Number):Void {
+	
+		this.innerRadius = (innerRadius == null) ? Gear.innerRadius_def : innerRadius;
+		this.outerRadius = (outerRadius == null) ? Gear.outerRadius_def : outerRadius;		
+		this.sides = (sides == null) ? Gear.sides_def : sides;
+		this.angle = 0;	
+		this.holeSides = (holeSides == null || holeSides < 2) ? Gear.holeSides_def : holeSides;
+		this.holeRadius = (holeRadius == null) ? Gear.holeRadius_def : holeRadius;		
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws gears.
+	* @usage <pre>myGear.draw();</pre>
+	*/
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/	
+	
+	/**
+	* @method getInnerRadius
+	* @description 	Return the radius of the indent of the teeth.
+	* @usage  <pre>myGear.getInnerRadius();</pre>
+	* @return Number of the radius of the indent of the teeth.
+	*/	
+	public function getInnerRadius(Void):Number {		
+		return this.innerRadius;		
+	}
+		
+	/**
+	* @method setInnerRadius
+	* @description 	Sets the radius of the indent of the teeth.		
+	* 		
+	* @usage   <pre>myGear.setInnerRadius(innerRadius);</pre>
+	* 	  
+	* @param innerRadius (Number) radius of the indent of the teeth.
+	*/	
+	public function setInnerRadius(innerRadius:Number):Void {	
+		this.innerRadius = innerRadius;		
+	}	
+	
+	/**
+	* @method getOuterRadius
+	* @description 	Return the outer radius of the teeth.
+	* @usage  <pre>myGear.getOuterRadius();</pre>
+	* @return Number of the outer radius of the teeth.
+	*/	
+	public function getOuterRadius(Void):Number {		
+		return this.outerRadius;		
+	}
+		
+	/**
+	* @method setOuterRadius
+	* @description 	Sets the outer radius of the teeth.	
+	* 		
+	* @usage   <pre>myGear.setOuterRadius(outerRadius);</pre>
+	* 	  
+	* @param outerRadius (Number) outer radius of the teeth.
+	*/	
+	public function setOuterRadius(outerRadius:Number):Void {	
+		this.outerRadius = outerRadius;		
+	}
+	
+	/**
+	* @method getHoleSides
+	* @description 	Return the number of sides of the inner polygonal hole.
+	* @usage  <pre>myGear.getHoleSides();</pre>
+	* @return Number of sides of the inner polygonal hole.
+	*/	
+	public function getHoleSides(Void):Number {		
+		return this.holeSides;		
+	}
+		
+	/**
+	* @method setHoleSides
+	* @description 	Sets the number of sides of the inner polygonal hole.		
+	* 		
+	* @usage   <pre>myGear.setHoleSides(holeSides);</pre>
+	* 	  
+	* @param holeSides (Number) sides of the inner polygonal hole.
+	*/	
+	public function setHoleSides(holeSides:Number):Void {	
+		this.holeSides = holeSides;		
+	}	
+	
+	/**
+	* @method getHoleRadius
+	* @description 	Return the size of hole.
+	* @usage  <pre>myGear.getHoleRadius();</pre>
+	* @return Number of the size of hole in pixels.
+	*/	
+	public function getHoleRadius(Void):Number {		
+		return this.holeRadius;		
+	}
+		
+	/**
+	* @method setHoleRadius
+	* @description 	Sets the size of hole.	
+	* 		
+	* @usage   <pre>myGear.setHoleRadius(holeRadius);</pre>
+	* 	  
+	* @param outerRadius (Number) size of hole in pixels.
+	*/	
+	public function setHoleRadius(holeRadius:Number):Void {	
+		this.holeRadius = holeRadius;		
+	}
+	
+	/**
+	* @method getSides
+	* @description 	Return the sides of the drawing.
+	* @usage  <pre>myGear.getSides();</pre>
+	* @return Number of sides. 
+	*/	
+	public function getSides(Void):Number {		
+		return this.sides;		
+	}
+		
+	/**
+	* @method setSides
+	* @description 	Sets the sides of the drawing.		
+	* 		
+	* @usage   <pre>myGear.setSides(sides);</pre>
+	* 	  
+	* @param sides (Number) the number of sides.
+	*/	
+	public function setSides(sides:Number):Void {	
+		this.sides = sides;		
+	}
+	
+	private function drawNew(Void):Void {		
+		this.mc.moveTo(this.x, this.y);
+		if (this.fillRGB != null && this.fillGradient == false) {
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, this.gradientColors, this.gradientAlphas, this.gradientRatios, this.gradientMatrix);
+		}		
+		this.drawGear(this.x, this.y, this.sides, this.innerRadius, 
+					  this.outerRadius, this.angle, this.holeSides, this.holeRadius);
+		this.mc.endFill();
+	}	
+	
+	/*-------------------------------------------------------------
+		drawGear is a method that draws gears... you
+		know, cogs with teeth and a hole in the middle where
+		the axle goes? Okay, okay... so nobody *needs* a
+		method to draw a gear. I know that this is probably
+		one of my least useful methods. But it was an easy
+		adaptation of the polygon method so I did it anyway.
+		Enjoy. FYI: if you modify this to draw the hole
+		polygon in the opposite direction, it will remain
+		transparent if the gear is used for a mask.
+	-------------------------------------------------------------*/
+	private function drawGear(x:Number, y:Number, sides:Number, 
+							  innerRadius:Number, outerRadius:Number, 
+							  angle:Number, holeSides:Number, holeRadius:Number):Void {
+		// ==============
+		// drawGear() - by Ric Ewing (ric at formequalsfunction.com) - version 1.3 - 3.5.2002
+		// 
+		// x, y = center of gear.
+		// sides = number of teeth on gear. (must be > 2)
+		// innerRadius = radius of the indent of the teeth.
+		// outerRadius = outer radius of the teeth.
+		// angle = [optional] starting angle in degrees. Defaults to 0.
+		// holeSides = [optional] draw a polygonal hole with this many sides (must be > 2).
+		// holeRadius = [optional] size of hole. Default = innerRadius/3.
+		// ==============
+		if (sides>2) {
+			// init vars
+			var step:Number, qtrStep:Number, start:Number, n:Number, dx:Number, dy:Number;
+			// calculate length of sides
+			step = (Math.PI*2)/sides;
+			qtrStep = step/4;
+			// calculate starting angle in radians
+			start = (angle/180)*Math.PI;
+			this.mc.moveTo(x+(Math.cos(start)*outerRadius), y-(Math.sin(start)*outerRadius));
+			// draw lines
+			for (n=1; n<=sides; n++) {
+				dx = x+Math.cos(start+(step*n)-(qtrStep*3))*innerRadius;
+				dy = y-Math.sin(start+(step*n)-(qtrStep*3))*innerRadius;
+				this.mc.lineTo(dx, dy);
+				dx = x+Math.cos(start+(step*n)-(qtrStep*2))*innerRadius;
+				dy = y-Math.sin(start+(step*n)-(qtrStep*2))*innerRadius;
+				this.mc.lineTo(dx, dy);
+				dx = x+Math.cos(start+(step*n)-qtrStep)*outerRadius;
+				dy = y-Math.sin(start+(step*n)-qtrStep)*outerRadius;
+				this.mc.lineTo(dx, dy);
+				dx = x+Math.cos(start+(step*n))*outerRadius;
+				dy = y-Math.sin(start+(step*n))*outerRadius;
+				this.mc.lineTo(dx, dy);
+			}
+			// This is complete overkill... but I had it done already. :)
+			if (holeSides>2) {
+				if(holeRadius == undefined) {
+					holeRadius = innerRadius/3;
+				}
+				step = (Math.PI*2)/holeSides;
+				this.mc.moveTo(x+(Math.cos(start)*holeRadius), y-(Math.sin(start)*holeRadius));
+				for (n=1; n<=holeSides; n++) {
+					dx = x+Math.cos(start+(step*n))*holeRadius;
+					dy = y-Math.sin(start+(step*n))*holeRadius;
+					this.mc.lineTo(dx, dy);
+				}
+			}
+		}
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myGear.lineStyle();</pre>
+	* 		<pre>myGear.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.		
+	* 		
+	* @usage   <pre>myGear.fillStyle();</pre>
+	* 		<pre>myGear.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/	
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		if(registrationObj.position == "CENTER") {		
+			this.x = 0;
+			this.y = 0;
+		} else {			
+			if(this.innerRadius > this.outerRadius) {
+				this.x = this.innerRadius + registrationObj.x;
+				this.y = this.innerRadius + registrationObj.y;
+			} else {
+				this.x = this.outerRadius + registrationObj.x;
+				this.y = this.outerRadius + registrationObj.y;
+			}
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "Gear";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Gear.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IDrawable.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IDrawable.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IDrawable.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,10 @@
+import de.alex_uhlmann.animationpackage.IAnimationPackage;
+interface de.alex_uhlmann.animationpackage.drawing.IDrawable extends IAnimationPackage {
+	public function lineStyle(lineThickness:Number, lineRGB:Number, lineAlpha:Number):Void;
+	public function fillStyle(fillRGB:Number, fillAlpha:Number):Void;
+	public function gradientStyle(fillType:String, colors:Array, alphas:Array, ratios:Array, matrix:Object):Void;
+	public function draw(Void):Void;
+	public function drawBy(Void):Void;
+	public function setRegistrationPoint(registrationObj:Object):Void;
+	public function clear(Void):Void;
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IDrawable.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IOutline.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IOutline.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IOutline.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,12 @@
+import de.alex_uhlmann.animationpackage.IAnimationPackage;
+interface de.alex_uhlmann.animationpackage.drawing.IOutline extends IAnimationPackage {
+	public function animationStyle(duration:Number, easing:Object, callback:String):Void;
+	public function animate(start:Number, end:Number):Void;
+	public function animateBy(start:Number, end:Number):Void;
+	public function lineStyle(lineThickness:Number, lineRGB:Number, lineAlpha:Number):Void;	
+	public function draw(Void):Void;
+	public function drawBy(Void):Void;
+	public function getPenPosition(Void):Object;
+	public function setPenPosition(p:Object):Void;
+	public function clear(Void):Void;
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/IOutline.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Line.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Line.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Line.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,726 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.IOutline;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Line
+* @author Alex Uhlmann
+* @description Line is a class for drawing lines.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a line with default parameters.		
+* 			<blockquote><pre>
+*			var myLine:Line = new Line();
+*			myLine.draw();		
+*			</pre></blockquote> 
+* 			Example 2: do the same, just animate it.		
+* 			<blockquote><pre>
+* 			var myLine:Line = new Line();
+*			myLine.animate(0,100);
+*			</pre></blockquote> 			
+* 			Example 3: draw a line with custom parameters. 
+* 			<blockquote><pre>
+*			var myLine:Line = new Line(0,0,275,200);
+*			myLine.lineStyle(20,0xff0000,50);
+*			myLine.draw();
+*			</pre></blockquote>
+* 			Example 4: the same like above using the getter/setter methods.
+* 			<blockquote><pre>
+*			var myLine:Line = new Line();
+*			myLine.lineStyle(20,0xff0000,50);
+*			myLine.setX1(0);
+*			myLine.setY1(0);
+*			myLine.setX2(275);
+*			myLine.setY2(200);
+*			myLine.draw();
+*			</pre></blockquote>
+* 			Example 5: <a href="Line_04.html">(Example .swf)</a> draw an animated line with custom parameters, that 
+* 			continues to animated to full size and back.
+* 			<blockquote><pre>
+*			var myLine:Line = new Line(0,0,275,200);
+*			myLine.lineStyle(10,0xff0000,50);
+*			myLine.animationStyle(2000,Elastic.easeOut,"onCallback");
+*			myLine.animate(0,100);
+*			myListener.onCallback = function(source, value)
+*			{	
+*				if(value == 100) {
+*					source.animate(100, 0);
+*				} else {
+*					source.animate(0, 100);
+*				}
+*			}
+*			</pre></blockquote>
+* 			The line is defined with two points. Start point and end point.  		
+* @usage   <pre>var myLine:Line = new Line();</pre> 
+* 		<pre>var myLine:Line = new Line(x1, y1, x2, y2);</pre> 
+* 		<pre>var myLine:Line = new Line(mc, x1, y1, x2, y2);</pre> 
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x1 (Number) start point to define line. Coordinate point x.
+* @param y1 (Number) start point to define line. Coordinate point y.
+* @param x2 (Number) end point to define line. Coordinate point x.
+* @param y2 (Number) end point to define line. Coordinate point y.
+*/
+class de.alex_uhlmann.animationpackage.drawing.Line 
+									extends Shape 
+									implements IDrawable, 
+											IOutline, 
+											ISingleAnimatable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/	
+	/*animationStyle properties inherited from APCore*/	
+	/** 
+	* @property x1_def (Number)(static) default property. start point to define line. Coordinate point x.
+	* @property y1_def (Number)(static) default property. start point to define line. Coordinate point y.
+	* @property x2_def (Number)(static) default property. end point to define line. Coordinate point x.
+	* @property y2_def (Number)(static) default property. end point to define line. Coordinate point y.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/
+	public static var x1_def:Number = 0;
+	public static var y1_def:Number = 0;
+	public static var x2_def:Number = 550;
+	public static var y2_def:Number = 400;	
+	private var x1:Number;
+	private var y1:Number;
+	private var x2:Number;
+	private var y2:Number;
+	private var x1Orig:Number;
+	private var y1Orig:Number;
+	private var x2Orig:Number;
+	private var y2Orig:Number;
+	public var mode:String = "REDRAW";
+	
+	public function Line() {
+		super();
+		if(arguments[0] === false) {
+			return;
+		}
+		this.init.apply(this,arguments);
+		this.lineStyle(null);
+		this.animationStyle();
+	}	
+
+	private function init():Void {
+		if(typeof(arguments[0]) == "movieclip") {				
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x1:Number, y1:Number, x2:Number, y2:Number):Void {		
+		this.mc = this.createClip({mc:mc, x:0, y:0});
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x1:Number, y1:Number, x2:Number, y2:Number):Void {
+		
+		this.mc = this.createClip({name:"apDraw", x:0, y:0});
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x1:Number, y1:Number, x2:Number, y2:Number):Void {
+		
+		this.x1 = (x1 == null) ? Line.x1_def : x1;
+		this.y1 = (y1 == null) ? Line.y1_def : y1;		
+		this.x2 = (x2 == null) ? Line.x2_def : x2;
+		this.y2 = (y2 == null) ? Line.y2_def : y2;		
+		this.x1Orig = this.x1;
+		this.y1Orig = this.y1;
+		this.x2Orig = this.x2;
+		this.y2Orig = this.y2;
+	}
+	
+	/**
+	* @method draw
+	* @description 	Draws the line.
+	* @usage <pre>myLine.draw();</pre>
+	*/
+	public function draw(Void):Void {
+		this.setInitialized(false);
+		this.setDefaultRegistrationPoint({position:"CENTER"});
+		this.clearDrawing();
+		this.mc.moveTo(this.x1, this.y1);
+		this.drawNewPoint(this.x2, this.y2);		
+	}
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the line without clearing the movieclip.
+	* @usage <pre>myLine.drawBy();</pre>
+	*/
+	public function drawBy(Void):Void {
+		if(this.lineStyleModified) {
+			this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+		}
+		if(this.penX != this.x1 || this.penY != this.y1) {			
+			this.mc.moveTo(this.x1, this.y1);
+		}
+		this.drawNewPoint(this.x2, this.y2);
+	}
+	
+	public function drawTo(Void):Void {		
+		this.drawNewPoint(this.x2, this.y2);
+	}
+	
+	private function drawNewPoint(x2:Number, y2:Number):Void {		
+		this.mc.lineTo(x2, y2);
+		this.penX = x2;
+		this.penY = y2;
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		var goto:Boolean;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;			
+		} else {
+			goto = false;
+		}
+		var setter:String;	
+		if(this.mode == "REDRAW") {
+			this.setDefaultRegistrationPoint({position:"CENTER"});
+			setter = "drawLine";
+		} else if(this.mode == "DRAW") {
+			if(this.penX != this.x1 || this.penY != this.y1) {			
+				if(this.lineStyleModified) {
+					this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+				}
+				this.mc.moveTo(this.x1, this.y1);
+				this.mc.lineTo(this.x1, this.y1);
+			}			
+			setter = "drawLineBy";
+		} else {
+			setter = "drawLineTo";
+		}
+		this.startValue = 0;
+		this.endValue = 100;
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [0];
+		this.myAnimator.end = [100];
+		this.myAnimator.setter = [[this, setter]];
+		if(goto == false) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			if(this.mode == "DRAWTO")return;
+			this.myAnimator.goto(end);
+		}
+	}	
+
+	/**
+	* @method animate
+	* @description 	Draws an animated line.		
+	* @usage  	<pre>myLine.animate(start, end);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/
+	public function animate(start:Number, end:Number):Void {
+		this.mode = "REDRAW";
+		this.invokeAnimation(start, end);
+	}
+	
+	/**
+	* @method animateBy
+	* @description 	Draws an animated line without clearing the movieclip.		
+	* @usage  	<pre>myLine.animateBy(start, end);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/	
+	public function animateBy(start:Number, end:Number):Void {
+		this.mode = "DRAW";		
+		this.invokeAnimation(start, end);
+	}
+	
+	public function animateTo(start:Number, end:Number):Void {
+		this.mode = "DRAWTO";
+		this.invokeAnimation(start, end);
+	}
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	private function drawLine(v:Number):Void {
+		this.clearDrawing();
+		this.mc.moveTo(this.x1, this.y1);
+		var p:Object = this.getPointsOnLine(v);
+		this.drawNewPoint(p.x, p.y);
+	}
+
+	private function drawLineBy(v:Number):Void {
+		this.mc.moveTo(this.x1, this.y1);
+		var p:Object = this.getPointsOnLine(v);
+		this.drawNewPoint(p.x, p.y);
+	}
+	
+	private function drawLineTo(v:Number):Void {
+		var p:Object = this.getPointsOnLine(v);
+		this.drawNewPoint(p.x, p.y);
+	}	
+		
+	private function getPointsOnLine(t:Number):Object {
+		var v:Number = t / 100;
+		var p:Object = {};
+		p.x = (v * (this.x2 - this.x1))+this.x1;
+		p.y = (v * (this.y2 - this.y1))+this.y1;	
+		return p;
+	}	
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myLine.lineStyle();</pre>
+	* 		<pre>myLine.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 	
+	* 		
+	* @usage   <pre>myLine.animationStyle(duration);</pre>
+	* 		<pre>myLine.animationStyle(duration, callback);</pre>
+	* 		<pre>myLine.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {		
+		var centerX:Number;
+		var centerY:Number;
+		
+		var minX:Number = Math.min(this.x1Orig, this.x2Orig);
+		var maxX:Number = Math.max(this.x1Orig, this.x2Orig);
+		var minY:Number = Math.min(this.y1Orig, this.y2Orig);
+		var maxY:Number = Math.max(this.y1Orig, this.y2Orig);			
+
+		if(registrationObj.position == "CENTER") {
+			centerX = (maxX - minX) / 2 + minX;
+			centerY = (maxY - minY) / 2 + minY;		
+		} else if (registrationObj.x != null || registrationObj.y != null) {
+			centerX = minX + registrationObj.x;
+			centerY = minY + registrationObj.y;
+		} else {
+			centerX = 0;
+			centerY = 0;
+		}
+		this.mc._x = centerX;
+		this.mc._y = centerY;	
+		this.x1 = this.x1Orig - centerX;
+		this.y1 = this.y1Orig - centerY;
+		this.x2 = this.x2Orig - centerX;
+		this.y2 = this.y2Orig - centerY;
+		this.initialized = true;
+	}
+	
+	private function setDefaultRegistrationPoint(registrationObj:Object):Void {		
+		if(!this.initialized) {
+			this.setRegistrationPoint(registrationObj);
+		}
+	}
+	
+	public function reset() {
+		this.x1 = this.x1Orig;
+		this.y1 = this.y1Orig;
+		this.x2 = this.x2Orig;
+		this.y2 = this.y2Orig;
+	}
+
+	/**
+	* @method getX1
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX1();</tt>
+	* @return Number
+	*/	
+	public function getX1(Void):Number {		
+		return this.x1;
+	}
+	
+	/**
+	* @method setX1
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX1();</tt>
+	* @param point (Number)
+	*/
+	public function setX1(x1:Number):Void {
+		this.x1Orig = x1;
+		this.x1 = x1;
+	}
+	
+	/**
+	* @method getY1
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY1();</tt>
+	* @return Number
+	*/
+	public function getY1(Void):Number {		
+		return this.y1;
+	}
+	
+	/**
+	* @method setY1
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY1();</tt>
+	* @param point (Number)
+	*/	
+	public function setY1(y1:Number):Void {
+		this.y1Orig = y1;
+		this.y1 = y1;
+	}	
+	
+	/**
+	* @method getX2
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX2();</tt>
+	* @return Number
+	*/	
+	public function getX2(Void):Number {
+		return this.x2;
+	}
+	
+	/**
+	* @method setX2
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX2();</tt>
+	* @param point (Number)
+	*/	
+	public function setX2(x2:Number):Void {
+		this.x2Orig = x2;
+		this.x2 = x2;
+	}
+	
+	/**
+	* @method getY2
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY2();</tt>
+	* @return Number
+	*/	
+	public function getY2(Void):Number {
+		return this.y2;
+	}
+	
+	/**
+	* @method setY2
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY2();</tt>
+	* @param point (Number)
+	*/		
+	public function setY2(y2:Number):Void {
+		this.y2Orig = y2;
+		this.y2 = y2;
+	}	
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/	
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myLine.addEventListener(event, listener);</pre>
+	* 		    <pre>myLine.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myLine.removeEventListener(event, listener);</pre>
+	* 		    <pre>myLine.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myLine.removeAllEventListeners();</pre>
+	* 		    <pre>myLine.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myLine.eventListenerExists(event, listener);</pre>
+	* 			<pre>myLine.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Line";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Line.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Poly.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Poly.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Poly.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,302 @@
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+
+/**
+* @class Poly
+* @author Alex Uhlmann
+* @description Poly is a class for creating regular polygons. Negative values 
+* 			for sides will draw the polygon in the reverse direction, 
+* 			which allows for creating knock-outs in masks.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a poly with default parameters.		
+* 			<blockquote><pre>
+*			var myPoly:Poly = new Poly();
+*			myPoly.draw();
+*			</pre></blockquote> 
+* 			Example 2: <a href="Poly_02.html">(Example .swf)</a> draw a poly with custom parameters.		
+* 			<blockquote><pre>
+*			var myPoly:Poly = new Poly(275,200,100,6);
+*			myPoly.lineStyle(2,0xff0000,100);
+*			myPoly.fillStyle(0xff0000,100);
+*			myPoly.draw();
+*			</pre></blockquote>
+* 			Example 3. A triangle.
+*			<blockquote><pre>
+* 			var myPoly:Poly = new Poly(275,200,100,3);
+*			myPoly.lineStyle(2,0xff0000,100);
+*			myPoly.fillStyle(0xff0000,100);
+*			myPoly.draw();
+*			</pre></blockquote>
+* 			Example 4. A circle.
+*			<blockquote><pre>
+* 			var myPoly:Poly = new Poly(275,200,50,50);
+*			myPoly.lineStyle(2,0xff0000,100);
+*			myPoly.fillStyle(0xff0000,100);
+*			myPoly.draw();
+*			</pre></blockquote>
+* @usage <pre>var myPoly:Poly = new Poly();</pre> 
+* 		<pre>var myPoly:Poly = new Poly(x, y, radius, sides);</pre>
+* 		<pre>var myPoly:Poly = new Poly(mc, x, y, radius, sides);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param radius (Number) radius of poly.
+* @param sides (Number) sides of poly.
+*/
+class de.alex_uhlmann.animationpackage.drawing.Poly 
+									extends Shape 
+									implements IDrawable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/	
+	/** 
+	* @property radius_def (Number)(static) default property. radius of poly.
+	* @property sides_def (Number)(static) default property. sides of poly. Defaults to 4.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.	
+	*/	
+	public static var radius_def:Number = 50;
+	public static var sides_def:Number = 6;
+	private var x:Number = 0;
+	private var y:Number = 0;
+	private var radius:Number;
+	private var sides:Number;
+	private var angle:Number;
+	
+	public function Poly() {
+		super(true);
+		this.init.apply(this,arguments);
+		this.fillStyle(null);		
+	}
+	
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, radius:Number, sides:Number):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:x, y:y});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, radius:Number, sides:Number):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x:Number, y:Number, radius:Number, sides:Number):Void {
+	
+		this.radius = (radius == null) ? Poly.radius_def : radius;
+		this.sides = (sides == null) ? Poly.sides_def : sides;
+		this.angle = 0;
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws it.		
+	* @usage <pre>myPoly.draw();</pre>
+	*/
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/	
+	
+	/**
+	* @method getRadius
+	* @description 	Returns the radius.
+	* @usage  <pre>myPoly.getRadius();</pre>
+	* @return Number that represents the radius in pixels. 
+	*/	
+	public function getRadius(Void):Number {		
+		return this.radius;		
+	}
+		
+	/**
+	* @method setRadius
+	* @description 	Sets the radius of the drawing.		
+	* 		
+	* @usage   <pre>myPoly.setRadius(radius);</pre>
+	* 	  
+	* @param radius (Number) radius in pixels.
+	*/	
+	public function setRadius(radius:Number):Void {	
+		this.radius = radius;		
+	}	
+	
+	/**
+	* @method getSides
+	* @description 	Return the sides of the drawing.
+	* @usage  <pre>myPoly.getSides();</pre>
+	* @return Number of sides. 
+	*/	
+	public function getSides(Void):Number {		
+		return this.sides;		
+	}
+		
+	/**
+	* @method setSides
+	* @description 	Sets the sides of the drawing.		
+	* 		
+	* @usage   <pre>myPoly.setSides(sides);</pre>
+	* 	  
+	* @param sides (Number) the number of sides.
+	*/	
+	public function setSides(sides:Number):Void {	
+		this.sides = sides;		
+	}	
+	
+	private function drawNew(Void):Void {		
+		this.mc.moveTo(this.x, this.y);
+		if (this.fillRGB != null && this.fillGradient == false) {
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, this.gradientColors, this.gradientAlphas, this.gradientRatios, this.gradientMatrix);
+		}		
+		this.drawPoly(this.x, this.y, this.sides, this.radius, this.angle);
+		this.mc.endFill();
+	}
+	
+	/*-------------------------------------------------------------
+		drawPoly is a method for creating regular
+		polygons. Negative values for sides will draw the
+		polygon in the reverse direction, which allows for
+		creating knock-outs in masks.
+	-------------------------------------------------------------*/
+	private function drawPoly(x:Number, y:Number, sides:Number, 
+							  radius:Number, angle:Number):Void {
+		// ==============
+		// drawPoly() - by Ric Ewing (ric at formequalsfunction.com) - version 1.4 - 4.7.2002
+		// 
+		// x, y = center of polygon
+		// sides = number of sides (Math.abs(sides) must be > 2)
+		// radius = radius of the points of the polygon from the center
+		// angle = [optional] starting angle in degrees. (defaults to 0)
+		// ==============
+		// convert sides to positive value
+		var count:Number = Math.abs(sides);
+		// check that count is sufficient to build polygon
+		if (count>2) {
+			// init vars
+			var step:Number, start:Number, n:Number, dx:Number, dy:Number;
+			// calculate span of sides
+			step = (Math.PI*2)/sides;
+			// calculate starting angle in radians
+			start = (angle/180)*Math.PI;
+			this.mc.moveTo(x+(Math.cos(start)*radius), y-(Math.sin(start)*radius));
+			// draw the polygon
+			for (n=1; n<=count; n++) {
+				dx = x+Math.cos(start+(step*n))*radius;
+				dy = y-Math.sin(start+(step*n))*radius;
+				this.mc.lineTo(dx, dy);
+			}
+		}
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myPoly.lineStyle();</pre>
+	* 		<pre>myPoly.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.		
+	* 		
+	* @usage   <pre>myPoly.fillStyle();</pre>
+	* 		<pre>myPoly.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/	
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		if(registrationObj.position == "CENTER") {		
+			this.x = 0;
+			this.y = 0;
+		} else {	
+			this.x = this.radius + registrationObj.x;
+			this.y = this.radius + registrationObj.y;
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Poly";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Poly.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/QuadCurve.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/QuadCurve.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/QuadCurve.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,922 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.IOutline;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+import de.alex_uhlmann.animationpackage.utility.BezierToolkit;
+
+/**
+* @class QuadCurve
+* @author Alex Uhlmann
+* @description QuadCurve is a class for drawing curves.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a curve with default parameters.		
+* 			<blockquote><pre>
+*			var myQuadCurve:QuadCurve = new QuadCurve();
+*			myQuadCurve.draw();
+*			</pre></blockquote> 
+* 			Example 2: do the same, just animate it.		
+* 			<blockquote><pre>
+* 			var myQuadCurve:QuadCurve = new QuadCurve();
+*			myQuadCurve.animate(0,100);
+*			</pre></blockquote> 			
+* 			Example 3: draw a curve with custom parameters. 
+* 			<blockquote><pre>
+*			var myQuadCurve:QuadCurve = new QuadCurve(0,0,200,200,500,50);
+*			myQuadCurve.lineStyle(2,0xff0000,50);
+*			myQuadCurve.draw();
+*			</pre></blockquote>
+* 			Example 4: the same like above using the getter/setter methods. 
+* 			<blockquote><pre>
+*			var myQuadCurve:QuadCurve = new QuadCurve();
+*			myQuadCurve.lineStyle(2,0xff0000,50);
+*			myQuadCurve.setX1(0);
+*			myQuadCurve.setY1(0);
+*			myQuadCurve.setX2(200);
+*			myQuadCurve.setY2(200);
+*			myQuadCurve.setX3(500);
+*			myQuadCurve.setY3(50);
+*			myQuadCurve.draw();
+*			</pre></blockquote> 
+* 			Example 5: <a href="QuadCurve_04.html">(Example .swf)</a> draw an animated curve with custom parameters, that 
+* 			continues to animated to full size and back.
+* 			<blockquote><pre>
+*			var myQuadCurve:QuadCurve = new QuadCurve(0,0,200,200,500,50);
+*			myQuadCurve.lineStyle(10,0xff0000,50);
+*			myQuadCurve.animationStyle(2000,Circ.easeInOut,"onCallback");
+*			myQuadCurve.animate(0, 100);
+*			myListener.onCallback = function(source, value)
+*			{	
+*				if(value == 100) {
+*					source.animate(100, 0);
+*				} else {
+*					source.animate(0, 100);
+*				}	
+*			}
+*			</pre></blockquote> 	
+* 			The curve is specified with three points. 
+* 			Start point, mid point, end point. Note: The mid point 
+* 			is the point the curve passes through, it is not the 
+* 			control point the i.e. MovieClip.curveTo method needs.	
+* @usage <pre>var myQuadCurve:QuadCurve = new QuadCurve();</pre> 
+* 		<pre>var myQuadCurve:QuadCurve = new QuadCurve(x1, y1, x2, y2, x3, y3);</pre>
+* 		<pre>var myQuadCurve:QuadCurve = new QuadCurve(x1, y1, x2, y2, x3, y3, withControlpoints);</pre>
+* 		<pre>var myQuadCurve:QuadCurve = new QuadCurve(mc, x1, y1, x2, y2, x3, y3);</pre>
+* 		<pre>var myQuadCurve:QuadCurve = new QuadCurve(mc, x1, y1, x2, y2, x3, y3, withControlpoints);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x1 (Number) start point to define curve. Coordinate point x.
+* @param y1 (Number) start point to define curve. Coordinate point y.
+* @param x2 (Number) mid point to define curve. Coordinate point x.
+* @param y2 (Number) mid point to define curve. Coordinate point y.
+* @param x3 (Number) end point to define curve. Coordinate point x.
+* @param y3 (Number) end point to define curve. Coordinate point y.
+* @param withControlpoints (Boolean) specify control points between the start and end points of the curve instead of points on the curve. Default is false.
+*/
+class de.alex_uhlmann.animationpackage.drawing.QuadCurve 
+									extends Shape 
+									implements IDrawable, 
+											IOutline, 
+											ISingleAnimatable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/	
+	/*animationStyle properties inherited from APCore*/	
+	/** 
+	* @property x1_def (Number)(static) default property. start point to define curve. Coordinate point x.
+	* @property y1_def (Number)(static) default property. start point to define curve. Coordinate point y.
+	* @property x2_def (Number)(static) default property. mid point to define curve. Coordinate point x.
+	* @property y2_def (Number)(static) default property. mid point to define curve. Coordinate point y.
+	* @property x3_def (Number)(static) default property. end point to define curve. Coordinate point x.
+	* @property y3_def (Number)(static) default property. end point to define curve. Coordinate point y.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).	
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/
+	public static var x1_def:Number = 0;
+	public static var y1_def:Number = 0;	
+	public static var x2_def:Number = 275;
+	public static var y2_def:Number = 200;	
+	public static var x3_def:Number = 550;
+	public static var y3_def:Number = 0;	
+	private var myBezierToolkit:BezierToolkit;	
+	/*start, control and end points of curve*/
+	private var x1:Number;
+	private var y1:Number;
+	private var x2:Number;
+	private var y2:Number;
+	private var x3:Number;
+	private var y3:Number;
+	private var p1:Object;
+	private var p2:Object;
+	private var p3:Object;
+	private var x1Orig:Number;
+	private var y1Orig:Number;
+	private var x2Orig:Number;
+	private var y2Orig:Number;
+	private var x3Orig:Number;
+	private var y3Orig:Number;
+	private var mcXOrig:Number;
+	private var mcYOrig:Number;	
+	private var withControlpoints:Boolean = false;
+	private var x2ControlPoint:Number;
+	private var y2ControlPoint:Number;
+	public var mode:String = "REDRAW";
+	private var lastStep:Number = 0;
+	private var overriddenRounded:Boolean = true;
+	private var overriddedOptimize:Boolean = true;
+	
+	public function QuadCurve() {
+		super();
+		this.init.apply(this,arguments);
+		this.lineStyle(null);
+		this.animationStyle();
+	}
+
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x1:Number, y1:Number, x2:Number, y2:Number, 
+						x3:Number, y3:Number, withControlpoints:Boolean):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:0, y:0});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x1:Number, y1:Number, x2:Number, y2:Number, 
+						x3:Number, y3:Number, withControlpoints:Boolean):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:0, y:0});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x1:Number, y1:Number, x2:Number, y2:Number, 
+						x3:Number, y3:Number, withControlpoints:Boolean):Void {
+	
+		this.x1 = (x1 == null) ? QuadCurve.x1_def : x1;
+		this.y1 = (y1 == null) ? QuadCurve.y1_def : y1;
+		this.x2 = (x2 == null) ? QuadCurve.x2_def : x2;
+		this.y2 = (y2 == null) ? QuadCurve.y2_def : y2;
+		this.x3 = (x3 == null) ? QuadCurve.x3_def : x3;
+		this.y3 = (y3 == null) ? QuadCurve.y3_def : y3;
+		if(withControlpoints != null) {
+			this.withControlpoints = withControlpoints;
+		}
+		this.x1Orig = this.x1;
+		this.y1Orig = this.y1;
+		this.x2Orig = this.x2;
+		this.y2Orig = this.y2;
+		this.x3Orig = this.x3;
+		this.y3Orig = this.y3;
+		this.mcXOrig = this.mc._x;
+		this.mcYOrig = this.mc._y;
+		this.myBezierToolkit = new BezierToolkit();
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws the curve.
+	* @usage <pre>myQuadCurve.draw();</pre>
+	*/
+	public function draw(Void):Void {
+		this.setInitialized(false);
+		this.setDefaultRegistrationPoint({position:"CENTER"});
+		this.clearDrawing();
+		this.mc.moveTo(this.x1, this.y1);
+		this.drawNew();
+	}
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the line without clearing the movieclip.
+	* @usage <pre>myQuadCurve.drawBy();</pre>
+	*/
+	public function drawBy(Void):Void {
+		
+		this.initControlPoints();
+		
+		if(this.lineStyleModified) {
+			this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+		}
+		if(this.penX != this.x1 || this.penY != this.y1) {
+			this.mc.moveTo(this.x1, this.y1);
+		}
+		this.drawNew();
+	}
+	
+	public function drawTo(Void):Void {
+		this.drawNew();
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		var goto:Boolean;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;			
+		} else {
+			goto = false;
+		}
+		var setter:String;
+		if(this.mode == "REDRAW") {
+			this.setInitialized(false);
+			this.setDefaultRegistrationPoint({position:"CENTER"});	
+			if(overriddedOptimize) {
+				setter = "drawLineCurve";
+			} else {
+				setter = "drawLineCurveSecure";
+			}
+		} else if(this.mode == "DRAW"){
+			this.initControlPoints();			
+			if(this.penX != this.x1 || this.penY != this.y1) {			
+				if(this.lineStyleModified) {
+					this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+				}
+				this.mc.moveTo(this.x1, this.y1);
+			}
+			if(overriddedOptimize) {
+				setter = "drawLineCurveBy";
+			} else {
+				setter = "drawLineCurveBySecure";
+			}			
+		} else {
+			setter = "drawLineCurveBy";
+		}
+		this.startValue = 0;
+		this.endValue = 100;		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [0];
+		this.myAnimator.end = [100];
+		this.myAnimator.setter = [[this, setter]];
+		if(goto == false) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			if(this.mode == "DRAWTO")return;
+			this.myAnimator.goto(end);
+		}
+	}
+	
+	/**
+	* @method animate
+	* @description 	Draws an animated curve.		
+	* @usage  	<pre>myQuadCurve.animate(start, end);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/
+	public function animate(start:Number, end:Number):Void {
+		this.mode = "REDRAW";
+		this.invokeAnimation(start, end);		
+	}
+	
+	/**
+	* @method animateBy
+	* @description 	Draws an animated curve without clearing the movieclip.		
+	* @usage  	<pre>myQuadCurve.animateBy(start, end);</pre>  
+	* @param start (Number) A percent value that specifies where the animation shall beginn. (0 - 100).
+	* @param end (Number) A percent value that specifies where the animation shall end. (0 - 100).
+	*/	
+	public function animateBy(start:Number, end:Number):Void {		
+		this.mode = "DRAW";
+		this.invokeAnimation(start, end);
+	}
+	
+	public function animateTo(start:Number, end:Number):Void {		
+		this.mode = "DRAWTO";
+		this.invokeAnimation(start, end);
+	}	
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+
+	private function drawNew(Void):Void {
+		this.mc.curveTo(this.x2, this.y2, this.x3, this.y3);
+		this.penX = this.x3;
+		this.penY = this.y3;
+	}
+	
+	private function drawLineCurve(v:Number):Void {		
+		if(this.lastStep == 0) {
+			if(this.lineStyleModified) {
+				this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+			}
+			this.mc.moveTo(this.x1, this.y1);
+		}
+		var len:Number;
+		
+		if(overriddenRounded) {
+			len = Math.round(v);	
+		} else {
+			len = v;
+		}
+
+		var s:Number;
+		if(len < this.lastStep) {
+			this.clearDrawing();
+			this.mc.moveTo(this.x1, this.y1);
+			s = this.startValue;
+		} else {
+			s = this.lastStep;
+		}
+		if(len == this.lastStep) {
+			return;
+		}
+		this.lastStep = len;
+		var p:Object;
+		var i:Number;
+		for(i = s; i <= len; i++) {
+			p = this.myBezierToolkit.getPointsOnQuadCurve(i, this.p1, this.p2, this.p3);
+			this.mc.lineTo(p.x, p.y);			
+		}
+	}
+
+	private function drawLineCurveBy(v:Number):Void {		
+		var p:Object;
+		var s:Number = (this.lastStep == null) ? this.startValue : this.lastStep;		
+		var len:Number;
+		if(overriddenRounded) {
+			len = Math.round(v);	
+		} else {
+			len = v;
+		}
+		if(len == this.lastStep) {
+			return;
+		}		
+		this.lastStep = len;
+		var i:Number;		
+		for(i = s; i <= len; i++) {
+			p = this.myBezierToolkit.getPointsOnQuadCurve(i, this.p1, this.p2, this.p3);
+			this.mc.lineTo(p.x, p.y);				
+		}
+	}
+	
+	//clunky and slow. I don't like it. But it does the job.
+	private function drawLineCurveSecure(v:Number):Void {		
+		this.clearDrawing();
+		this.mc.moveTo(this.x1, this.y1);		
+		var p:Object;
+		var s:Number = this.startValue;		
+		var len:Number = Math.round(v);		
+		var i:Number;
+		for(i = s; i <= len; i++) {
+			p = this.myBezierToolkit.getPointsOnQuadCurve(i, this.p1, this.p2, this.p3);
+			this.mc.lineTo(p.x, p.y);	
+		}
+	}
+	
+	private function drawLineCurveBySecure(v:Number):Void {		
+		this.mc.moveTo(this.x1, this.y1);
+		var p:Object;
+		var s:Number = this.startValue;		
+		var len:Number = Math.round(v);
+		var i:Number;
+		for(i = s; i <= len; i++) {
+			p = this.myBezierToolkit.getPointsOnQuadCurve(i, this.p1, this.p2, this.p3);
+			this.mc.lineTo(p.x, p.y);				
+		}
+	}	
+
+	/**
+	* @method useControlPoints
+	* @description 	offers the opportunity to specify control points between the start and end points 
+	* 				of the curve instead of points on the curve. Default is false.
+	* 				If true points between start and end points are control points.
+	*                  		If false points between start and end points are points on the curve.
+	* @usage   <pre>myInstance.useControlPoints(withControlpoints);</pre> 	  
+	* @param withControlpoints (Boolean) <code>true</code> or <code>false</code>.
+	* @return void
+	*/
+	public function useControlPoints(withControlpoints:Boolean):Void {		
+		if(withControlpoints == true && this.initialized == true) {
+			this.x2 = this.x2ControlPoint;
+			this.y2 = this.y2ControlPoint;
+			this.p2 = {x:this.x2, y:this.y2};
+		}		
+		this.withControlpoints = withControlpoints;		
+	}
+	
+	public function initControlPoints(Void):Void {		
+		if(!this.initialized) {
+			if(this.withControlpoints == false) {
+				this.x2ControlPoint = this.x2;
+				this.y2ControlPoint = this.y2;
+				var controlPoint:Object = this.myBezierToolkit.getQuadControlPoints(this.x1, this.y1, 
+								this.x2, this.y2, this.x3, this.y3);
+				this.x2 = controlPoint.x;
+				this.y2 = controlPoint.y;		
+			}
+			this.p1 = {x:this.x1, y:this.y1};
+			this.p2 = {x:this.x2, y:this.y2};
+			this.p3 = {x:this.x3, y:this.y3};
+			this.initialized = true;		
+		}
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myQuadCurve.lineStyle();</pre>
+	* 		<pre>myQuadCurve.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set animation setting for animation.		
+	* 		
+	* @usage   <pre>myQuadCurve.animationStyle(duration);</pre>
+	* 		<pre>myQuadCurve.animationStyle(duration, callback);</pre>
+	* 		<pre>myQuadCurve.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {	
+		this.initialized = false;
+		
+		var minX:Number = Math.min(Math.min(this.x1Orig, this.x2Orig), this.x3Orig);
+		var maxX:Number = Math.max(Math.max(this.x1Orig, this.x2Orig), this.x3Orig);
+		var minY:Number = Math.min(Math.min(this.y1Orig, this.y2Orig), this.y3Orig);
+		var maxY:Number = Math.max(Math.max(this.y1Orig, this.y2Orig), this.y3Orig);
+
+		var centerX:Number;
+		var centerY:Number;
+
+		if(registrationObj.position == "CENTER") {
+			centerX = (maxX - minX) / 2 + minX;
+			centerY = (maxY - minY) / 2 + minY;		
+		} else if (registrationObj.x != null || registrationObj.y != null) {
+			centerX = minX + registrationObj.x;
+			centerY = minY + registrationObj.y;		
+		} else {
+			centerX = 0;
+			centerY = 0;
+		}
+		this.mc._x = centerX;
+		this.mc._y = centerY;
+		this.x1 = this.x1Orig - centerX;
+		this.y1 = this.y1Orig - centerY;
+		this.x2 = this.x2Orig - centerX;
+		this.y2 = this.y2Orig - centerY;
+		this.x3 = this.x3Orig - centerX;
+		this.y3 = this.y3Orig - centerY;	
+		this.initControlPoints();
+	}
+	
+	private function setDefaultRegistrationPoint(registrationObj:Object):Void {		
+		if(!this.initialized) {
+			this.setRegistrationPoint(registrationObj);
+		}		
+	}
+	
+	public function reset() {
+		this.x1 = this.x1Orig;
+		this.y1 = this.y1Orig;
+		this.x2 = this.x2Orig;
+		this.y2 = this.y2Orig;
+		this.x3 = this.x3Orig;
+		this.y3 = this.y3Orig;
+		this.initialized = false;
+		this.initControlPoints();
+	}
+		
+	/**
+	* @method getX1
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX1();</tt>
+	* @return Number
+	*/	
+	public function getX1(Void):Number {
+		return this.x1;
+	}
+	
+	/**
+	* @method setX1
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX1();</tt>
+	* @param point (Number)
+	*/
+	public function setX1(x1:Number):Void {
+		this.x1Orig = x1;
+		this.x1 = x1;
+	}
+	
+	/**
+	* @method getY1
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY1();</tt>
+	* @return Number
+	*/
+	public function getY1(Void):Number {
+		return this.y1;
+	}
+	
+	/**
+	* @method setY1
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY1();</tt>
+	* @param point (Number)
+	*/	
+	public function setY1(y1:Number):Void {
+		this.y1Orig = y1;
+		this.y1 = y1;
+	}	
+	
+	/**
+	* @method getX2
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX2();</tt>
+	* @return Number
+	*/	
+	public function getX2(Void):Number {
+		return this.x2;
+	}
+	
+	/**
+	* @method setX2
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX2();</tt>
+	* @param point (Number)
+	*/	
+	public function setX2(x2:Number):Void {
+		this.x2Orig = x2;
+		this.x2 = x2;
+	}
+	
+	/**
+	* @method getY2
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY2();</tt>
+	* @return Number
+	*/
+	public function getY2(Void):Number {
+		return this.y2;
+	}
+	
+	/**
+	* @method setY2
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY2();</tt>
+	* @param point (Number)
+	*/		
+	public function setY2(y2:Number):Void {
+		this.y2Orig = y2;
+		this.y2 = y2;
+	}
+	
+	/**
+	* @method getX3
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getX3();</tt>
+	* @return Number
+	*/	
+	public function getX3(Void):Number {
+		return this.x3;
+	}
+	
+	/**
+	* @method setX3
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setX3();</tt>
+	* @param point (Number)
+	*/	
+	public function setX3(x3:Number):Void {
+		this.x3Orig = x3;
+		this.x3 = x3;
+	}
+	
+	/**
+	* @method getY3
+	* @description returns a specific point of the outline.
+	* @usage   <tt>myInstance.getY3();</tt>
+	* @return Number
+	*/	
+	public function getY3(Void):Number {
+		return this.y3;
+	}
+	
+	/**
+	* @method setY3
+	* @description 	sets a specific point of the outline.
+	* @usage   <tt>myInstance.setY3();</tt>
+	* @param point (Number)
+	*/	
+	public function setY3(y3:Number):Void {
+		this.y3Orig = y3;
+		this.y3 = y3;
+	}
+
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers to prevent dirty renderings 
+	* 				of the Flash Player Drawing API. Default is true.
+	* @usage   <pre>myInstance.roundResult(event, listener);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy.
+	*                  				<code>false</code> animates with floating point numbers.
+	*/
+	public function checkIfRounded(Void):Boolean {
+		return this.overriddenRounded;
+	}
+	
+	public function roundResult(overriddenRounded:Boolean):Void {
+		this.overriddenRounded = overriddenRounded;
+	}
+	
+	/**
+	* @method forceEnd
+	* @description 	forces the end value(s) to be reached. By default this can't be guaranteed because of the nature of easing equations. 
+	* 			Exception: All drawing classes force the end value by default. 		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	public function getOptimizationMode(Void):Boolean {		
+		return this.overriddedOptimize;
+	}
+	
+	public function setOptimizationMode(overriddedOptimize:Boolean):Void {		
+		this.overriddedOptimize = overriddedOptimize;
+	}
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myQuadCurve.addEventListener(event, listener);</pre>
+	* 		    <pre>myQuadCurve.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myQuadCurve.removeEventListener(event, listener);</pre>
+	* 		    <pre>myQuadCurve.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myQuadCurve.removeAllEventListeners();</pre>
+	* 		    <pre>myQuadCurve.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myQuadCurve.eventListenerExists(event, listener);</pre>
+	* 			<pre>myQuadCurve.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "QuadCurve";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/QuadCurve.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Rectangle.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Rectangle.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Rectangle.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,275 @@
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+
+/**
+* @class Rectangle
+* @author Alex Uhlmann
+* @description Rectangle is a class for creating rectangles.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a rectangle with default parameters.		
+* 			<blockquote><pre>
+*			var myRectangle:Rectangle = new Rectangle();
+*			myRectangle.draw();
+*			</pre></blockquote> 
+* 			Example 2: draw a rectangle with custom parameters.		
+* 			<blockquote><pre>
+*			var myRectangle:Rectangle = new Rectangle(275,200,100,100);
+*			myRectangle.lineStyle(2,0x000000,100);
+*			myRectangle.fillStyle(0xff0000,100);
+*			myRectangle.draw();
+*			</pre></blockquote>
+* 			Example 3: If we scale our rectangle from example 2 with the MovieClip._xscale, 
+* 			MovieClip._yscale properties, the outline will scale too. If you want the outline 
+* 			to stay fixed and just scale the fill, you need to redraw the rectangle in each step. 
+* 			This allows the setSize method. Let's do a test to illustrate this: After the code 
+* 			from example 2, write:
+* 			<blockquote><pre>
+* 			new Scale(myRectangle.movieclip).run(400,400);
+* 			</pre></blockquote>
+* 			<a href="Rectangle_03a.html">(Example .swf)</a> 
+*  			You'll notice the that the outline also scaled. Instead using the Scale class, 
+* 			use setScale() in combination with the Animator class from the ultility package. 
+* 			<blockquote><pre>
+*			var myAnimator:Animator = new Animator();				
+*			myAnimator.caller = myAnimator;	
+*			myAnimator.start = [myRectangle.getSize().w,myRectangle.getSize().h];
+*			myAnimator.end = [400,400];
+*			myAnimator.setter = [[_root,"scale"]];
+*			myAnimator.run();
+*			//Proxy class.			
+*			function scale(w:Number,h:Number) {	
+*				myRectangle.setSize(w,h);
+*				myRectangle.draw();		
+*			}
+* 			</pre></blockquote>
+* 			<a href="Rectangle_03b.html">(Example .swf)</a> 
+* 			See Animator class.
+* 
+* @usage <pre>var myRectangle:Rectangle = new Rectangle();</pre> 
+* 		<pre>var myRectangle:Rectangle = new Rectangle(x, y, width, height);</pre>
+*		<pre>var myRectangle:Rectangle = new Rectangle(mc, x, y, width, height);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param width (Number) width of rectangle in pixels.
+* @param height (Number) height of rectangle in pixels.
+*/
+class de.alex_uhlmann.animationpackage.drawing.Rectangle 
+											extends Shape 
+											implements IDrawable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/	
+	/** 
+	* @property width_def (Number)(static) default property. width of rectangle. Defaults to 100.
+	* @property height_def (Number)(static) default property. height of rectangle. Defaults to 100.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.	
+	*/	
+	public static var x_def:Number = 0;
+	public static var y_def:Number = 0;
+	public static var width_def:Number = 100;
+	public static var height_def:Number = 100;	
+	private var x:Number = 0;
+	private var y:Number = 0;
+	private var m_width:Number;
+	private var m_height:Number;
+	
+	public function Rectangle() {
+		super(true);
+		if(arguments[0] === false) {
+			return;
+		}
+		this.init.apply(this,arguments);		
+		this.fillStyle(null);		
+	}
+	
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {		
+			this.initCustom.apply(this,arguments);
+		} else {
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, width:Number, height:Number):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:x, y:y});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, width:Number, height:Number):Void {		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});	
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x:Number, y:Number, width:Number, height:Number):Void {
+	
+		this.x = (x == null) ? Rectangle.x_def : x;
+		this.y = (y == null) ? Rectangle.y_def : width;
+		this.m_width = (width == null) ? Rectangle.width_def : width;
+		this.m_height = (height == null) ? Rectangle.height_def : height;		
+		this.setRegistrationPoint({position:"CENTER"});
+	}	
+	
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws the rectangle.
+	* @usage  <pre>myRectangle.draw();</pre>
+	*/
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/
+	
+	/**
+	* @method getSize
+	* @description 	Returns the dimensions of the rectangle.
+	* @usage  <pre>myRectangle.getSize();</pre>
+	* @return Object that contains w for with and h for height properties that define the dimension of the drawing in pixels. 
+	*/	
+	public function getSize(Void):Object {		
+		return {w:this.m_width, h:this.m_height};	
+	}
+	
+	/**
+	* @method setSize
+	* @description 	Sets the dimensions of the rectangle.		
+	* 		
+	* @usage   <pre>myRectangle.setSize(width, height);</pre>
+	* 	  
+	* @param width (Number) width of rectangle in pixels.
+	* @param height (Number) height of rectangle in pixels.
+	*/	
+	public function setSize(width:Number, height:Number):Void {
+		this.x -= (width - this.m_width) / 2;
+		this.y -= (height - this.m_height) / 2;
+		this.m_width = width;
+		this.m_height = height;		
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myRectangle.lineStyle();</pre>
+	* 		<pre>myRectangle.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/	
+	
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.		
+	* 		
+	* @usage   <pre>myRectangle.fillStyle();</pre>
+	* 		<pre>myRectangle.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/
+	
+	private function drawNew(Void):Void {		
+		this.mc.moveTo(x, y);
+		if (this.fillRGB != null && this.fillGradient == false) {
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, this.gradientColors, this.gradientAlphas, this.gradientRatios, this.gradientMatrix);
+		}			
+		this.drawRect(this.x, this.y, this.m_width, this.m_height);		
+		this.mc.endFill();
+	}
+	
+	private function drawRect(x:Number, y:Number, w:Number, h:Number):Void {	
+		this.mc.lineTo(x+w, y);
+		this.mc.lineTo(x+w, y+h);
+		this.mc.lineTo(x, y+h);
+		this.mc.lineTo(x, y);
+	}
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/	
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		if(registrationObj.position == "CENTER") {		
+			this.x = -(this.m_width / 2);
+			this.y = -(this.m_height / 2);			
+		} else { 
+			if(registrationObj.x != null ) {
+				this.x = registrationObj.x;
+			}
+			if(registrationObj.y != null ) {
+				this.y = registrationObj.y;
+			}
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Rectangle";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Rectangle.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/RoundRectangle.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/RoundRectangle.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/RoundRectangle.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,429 @@
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Rectangle;
+
+/**
+* @class RoundRectangle
+* @author Alex Uhlmann
+* @description RoundRectangle is a class for creating rectangles and	rounded rectangles. 
+* 			The rounding is very much like that of the rectangle tool in Flash where if the
+*			rectangle is smaller in either dimension than the rounding would permit, 
+*			the rounding scales down to fit.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a rectangle with default parameters.		
+* 			<blockquote><pre>
+*			var myRoundRectangle:RoundRectangle = new RoundRectangle();			
+* 			myRoundRectangle.draw();
+*			</pre></blockquote> 
+* 			Example 2: draw a rectangle with custom parameters.		
+* 			<blockquote><pre>
+*			var myRoundRectangle:RoundRectangle = new RoundRectangle(275,200,200,100);
+*			myRoundRectangle.setCornerRadius(60);
+* 			myRoundRectangle.lineStyle(2,0xff0000,100);
+*			myRoundRectangle.fillStyle(0x000000,100);
+*			myRoundRectangle.draw();
+*			</pre></blockquote> 
+* 			Example 3: Draw another rounded rectangle with each corner different.
+* 			<blockquote><pre>
+*			var myRoundRectangle:RoundRectangle = new RoundRectangle(275,200,200,100);
+*			myRoundRectangle.setCornerRadii({tl:5,tr:10,bl:20,br:40});
+*			myRoundRectangle.lineStyle(5,0xff0000,100);
+*			myRoundRectangle.fillStyle(0x000000,100);
+*			myRoundRectangle.draw();
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 4: Take a look at example 3 of the Rectangle class documentation. Same applies to RoundRectangle.
+* 
+* @usage <pre>var myRoundRectangle:RoundRectangle = new RoundRectangle();</pre> 
+* 		<pre>var myRoundRectangle:RoundRectangle = new RoundRectangle(x, y, width, height, cornerRadius);</pre>
+* 		<pre>var myRoundRectangle:RoundRectangle = new RoundRectangle(x, y, width, height, cornerRadii);</pre>
+* 		<pre>var myRoundRectangle:RoundRectangle = new RoundRectangle(mc, x, y, width, height, cornerRadius);</pre>
+*  		<pre>var myRoundRectangle:RoundRectangle = new RoundRectangle(mc, x, y, width, height, cornerRadii);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param width (Number) width of rectangle in pixels.
+* @param height (Number) height of rectangle in pixels.
+* @param cornerRadii or cornerRadius(Object or Number) see setCornerRadii and setCornerRadius.
+*/
+class de.alex_uhlmann.animationpackage.drawing.RoundRectangle 
+											extends Rectangle 
+											implements IDrawable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/	
+	/** 
+	* @property width_def (Number)(static) default property. width of rectangle. Defaults to 100.
+	* @property height_def (Number)(static) default property. height of rectangle. Defaults to 100.
+	* @property cornerRadii_def (Object)(static) default property. corner radii of rectangle. Defaults to 25 degrees each.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.	
+	*/
+	public static var cornerRadii_def:Object = {tl:25,tr:25,bl:25,br:25};
+	private var cornerRadii:Object;
+	private var cornerRadius:Number;
+	
+	public function RoundRectangle() {
+		super(false);
+		this.init.apply(this,arguments);		
+		this.fillStyle(null);		
+	}
+	
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, width:Number, height:Number):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:x, y:y});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, width:Number, height:Number):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x:Number, y:Number, width:Number, height:Number):Void {	
+		var cornerRadii:Object = arguments[4];
+		var temp = cornerRadii;
+		if(typeof(temp) == "number") {
+			this.setCornerRadius(temp);
+		} else {
+			this.cornerRadii = (cornerRadii == null) ? RoundRectangle.cornerRadii_def : cornerRadii;		
+			if(this.setCornerRadii(cornerRadii) == false) {
+				this.cornerRadii = RoundRectangle.cornerRadii_def;
+			}
+		}
+		super.initShape(x, y, width, height);
+	}
+	
+	/*inherited from Rectangle*/
+	/**
+	* @method draw
+	* @description 	Draws the rectangle.
+	* @usage  <pre>myRoundRectangle.draw();</pre>
+	*/
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/
+	
+	/**
+	* @method getCornerRadius
+	* @description 	returns the corner radius of the rectangle in degrees.
+	* @usage  <pre>myRoundRectangle.getCornerRadius();</pre>
+	* @return Number 
+	*/
+	public function getCornerRadius(Void):Number {
+		return this.cornerRadius;		
+	}
+	
+	/**
+	* @method setCornerRadius
+	* @description 	sets the corner radius of the rectangle in degrees.
+	* @usage  <pre>myRoundRectangle.getCornerRadius();</pre>
+	* @param cornerRadius (Number) 
+	*/
+	public function setCornerRadius(cornerRadius:Number):Void {
+		this.cornerRadius = cornerRadius;		
+	}
+	
+	/**
+	* @method getCornerRadii
+	* @description 	returns the corner radii (plural of radius) of the rectangle in degrees.
+	* @usage  <pre>myRoundRectangle.setCornerRadii();</pre>
+	* @return Object 
+	*/
+	public function getCornerRadii(Void):Object {
+		return this.cornerRadii;		
+	}
+	
+	/**
+	* @method setCornerRadii
+	* @description 	sets the corner radii (plural of radius) of the rectangle in degrees.
+	* 				Only accepts objects with tl (top left), tr (top right), bl (bottom left) and br (bottom right) properties.
+	* @usage  <pre>myRoundRectangle.setCornerRadii();</pre>
+	* @param cornerRadius (Object) 
+	*/
+	public function setCornerRadii(cornerRadii:Object):Boolean {		
+		if(cornerRadii.tl != null && cornerRadii.tr != null && cornerRadii.bl != null && cornerRadii.br != null) {
+			this.cornerRadii = cornerRadii;
+			return true;
+		} else {
+			return false;
+		}
+	}	
+	
+	/*inherited from Rectangle*/	
+	/**
+	* @method getSize
+	* @description 	Returns the dimensions of the rectangle.
+	* @usage  <pre>myRectangle.getSize();</pre>
+	* @return Object that contains w for with and h for height properties that define the dimension of the drawing in pixels. 
+	*/	
+	
+	/*inherited from Rectangle*/	
+	/**
+	* @method setSize
+	* @description 	Sets the dimensions of the rectangle.		
+	* 		
+	* @usage   <pre>myRectangle.setSize(width, height);</pre>
+	* 	  
+	* @param width (Number) width of rectangle in pixels.
+	* @param height (Number) height of rectangle in pixels.
+	*/
+	
+	private function drawNew(Void):Void {
+		this.mc.moveTo(this.x, this.y);
+		if (this.fillRGB != null && this.fillGradient == false) {
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, 
+									this.gradientColors, 
+									this.gradientAlphas, 
+									this.gradientRatios, 
+									this.gradientMatrix);
+		}		
+		var c:Number = this.cornerRadius;
+		if(c != null) {
+			this.cornerRadii = {tl:c,tr:c,bl:c,br:c};
+		}
+		this.drawRect(this.x, this.y, this.m_width, this.m_height, this.cornerRadii);
+		this.mc.endFill();
+	}
+	
+	/*-------------------------------------------------------------
+		drawRect() is a method for drawing rectangles and
+		rounded rectangles. Regular rectangles are
+		sufficiently easy that I often just rebuilt the
+		method in any file I needed it in, but the rounded
+		rectangle was something I was needing more often,
+		hence the method. The rounding is very much like
+		that of the rectangle tool in Flash where if the
+		rectangle is smaller in either dimension than the
+		rounding would permit, the rounding scales down to
+		fit.
+	-------------------------------------------------------------*/
+	private function drawRect(x:Number, y:Number, w:Number, h:Number):Void {
+		var cornerRadii:Object = arguments[4];
+		// ==============
+		// drawRect() - by Ric Ewing (ric at formequalsfunction.com) - version 1.1 - 4.7.2002
+		// 
+		// x, y = top left corner of rect
+		// w = width of rect
+		// h = height of rect
+		// cornerRadius = [optional] radius of rounding for corners (defaults to 0)
+		// ==============
+		// if the user has defined cornerRadius our task is a bit more complex. :)
+		if(cornerRadii.tl >= 0 && cornerRadii.tr >= 0 && cornerRadii.bl >= 0 && cornerRadii.br >= 0) {
+			// init vars
+			var theta:Number, angle:Number, cx:Number, cy:Number, px:Number, py:Number;
+			// make sure that w + h are larger than 2*cornerRadius
+			var maxRadii:Number = Math.min(w, h)/2;
+			if(cornerRadii.tl > maxRadii) {
+				cornerRadii.tl = maxRadii;
+			}
+			if(cornerRadii.tr > maxRadii) {
+				cornerRadii.tr = maxRadii;
+			}
+			if(cornerRadii.bl > maxRadii) {
+				cornerRadii.bl = maxRadii;
+			}
+			if(cornerRadii.br > maxRadii) {
+				cornerRadii.br = maxRadii;
+			}			
+			// theta = 45 degrees in radians
+			theta = Math.PI/4;
+			
+			if(cornerRadii.tr > 0) {
+				// draw top line
+				this.mc.moveTo(x+cornerRadii.tl, y); 
+				this.mc.lineTo(x+w-cornerRadii.tr, y);
+				//angle is currently 90 degrees
+				angle = -Math.PI/2;
+				// draw tr corner in two parts
+				cx = x+w-cornerRadii.tr+(Math.cos(angle+(theta/2))*cornerRadii.tr/Math.cos(theta/2));
+				cy = y+cornerRadii.tr+(Math.sin(angle+(theta/2))*cornerRadii.tr/Math.cos(theta/2));
+				px = x+w-cornerRadii.tr+(Math.cos(angle+theta)*cornerRadii.tr);
+				py = y+cornerRadii.tr+(Math.sin(angle+theta)*cornerRadii.tr);
+				this.mc.curveTo(cx, cy, px, py);
+				angle += theta;
+				cx = x+w-cornerRadii.tr+(Math.cos(angle+(theta/2))*cornerRadii.tr/Math.cos(theta/2));
+				cy = y+cornerRadii.tr+(Math.sin(angle+(theta/2))*cornerRadii.tr/Math.cos(theta/2));
+				px = x+w-cornerRadii.tr+(Math.cos(angle+theta)*cornerRadii.tr);
+				py = y+cornerRadii.tr+(Math.sin(angle+theta)*cornerRadii.tr);
+				this.mc.curveTo(cx, cy, px, py);
+			} else {				
+				this.mc.moveTo(x+cornerRadii.tl, y);
+				this.mc.lineTo(x+w, y);
+				//angle is currently 90 degrees
+				angle = -Math.PI/2;
+				angle += theta;
+			}			
+			if(cornerRadii.br > 0) {
+				// draw right line
+				this.mc.lineTo(x+w, y+h-cornerRadii.br);
+				// draw br corner
+				angle += theta;
+				cx = x+w-cornerRadii.br+(Math.cos(angle+(theta/2))*cornerRadii.br/Math.cos(theta/2));
+				cy = y+h-cornerRadii.br+(Math.sin(angle+(theta/2))*cornerRadii.br/Math.cos(theta/2));
+				px = x+w-cornerRadii.br+(Math.cos(angle+theta)*cornerRadii.br);
+				py = y+h-cornerRadii.br+(Math.sin(angle+theta)*cornerRadii.br);
+				this.mc.curveTo(cx, cy, px, py);
+				angle += theta;
+				cx = x+w-cornerRadii.br+(Math.cos(angle+(theta/2))*cornerRadii.br/Math.cos(theta/2));
+				cy = y+h-cornerRadii.br+(Math.sin(angle+(theta/2))*cornerRadii.br/Math.cos(theta/2));
+				px = x+w-cornerRadii.br+(Math.cos(angle+theta)*cornerRadii.br);
+				py = y+h-cornerRadii.br+(Math.sin(angle+theta)*cornerRadii.br);
+				this.mc.curveTo(cx, cy, px, py);
+			} else {
+				this.mc.lineTo(x+w, y+h);
+				angle += theta;
+				angle += theta;				
+			}
+			if(cornerRadii.bl > 0) {
+				// draw bottom line
+				this.mc.lineTo(x+cornerRadii.bl, y+h);
+				// draw bl corner
+				angle += theta;
+				cx = x+cornerRadii.bl+(Math.cos(angle+(theta/2))*cornerRadii.bl/Math.cos(theta/2));
+				cy = y+h-cornerRadii.bl+(Math.sin(angle+(theta/2))*cornerRadii.bl/Math.cos(theta/2));
+				px = x+cornerRadii.bl+(Math.cos(angle+theta)*cornerRadii.bl);
+				py = y+h-cornerRadii.bl+(Math.sin(angle+theta)*cornerRadii.bl);
+				this.mc.curveTo(cx, cy, px, py);
+				angle += theta;
+				cx = x+cornerRadii.bl+(Math.cos(angle+(theta/2))*cornerRadii.bl/Math.cos(theta/2));
+				cy = y+h-cornerRadii.bl+(Math.sin(angle+(theta/2))*cornerRadii.bl/Math.cos(theta/2));
+				px = x+cornerRadii.bl+(Math.cos(angle+theta)*cornerRadii.bl);
+				py = y+h-cornerRadii.bl+(Math.sin(angle+theta)*cornerRadii.bl);
+				this.mc.curveTo(cx, cy, px, py);
+			} else {
+				this.mc.lineTo(x, y+h);
+				angle += theta;
+				angle += theta;
+			}
+			if(cornerRadii.tl > 0) {
+				// draw left line
+				this.mc.lineTo(x, y+cornerRadii.tl);
+				// draw tl corner
+				angle += theta;
+				cx = x+cornerRadii.tl+(Math.cos(angle+(theta/2))*cornerRadii.tl/Math.cos(theta/2));
+				cy = y+cornerRadii.tl+(Math.sin(angle+(theta/2))*cornerRadii.tl/Math.cos(theta/2));
+				px = x+cornerRadii.tl+(Math.cos(angle+theta)*cornerRadii.tl);
+				py = y+cornerRadii.tl+(Math.sin(angle+theta)*cornerRadii.tl);
+				this.mc.curveTo(cx, cy, px, py);
+				angle += theta;
+				cx = x+cornerRadii.tl+(Math.cos(angle+(theta/2))*cornerRadii.tl/Math.cos(theta/2));
+				cy = y+cornerRadii.tl+(Math.sin(angle+(theta/2))*cornerRadii.tl/Math.cos(theta/2));
+				px = x+cornerRadii.tl+(Math.cos(angle+theta)*cornerRadii.tl);
+				py = y+cornerRadii.tl+(Math.sin(angle+theta)*cornerRadii.tl);
+				this.mc.curveTo(cx, cy, px, py);
+			} else {
+				this.mc.lineTo(x, y);
+				angle += theta;
+				angle += theta;
+			}		
+		} else {
+			// cornerRadius was not defined or = 0. This makes it easy.
+			super.drawRect(x, y, w, h);
+		}
+	}
+	
+	/*inherited from Shape*/	
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myRoundRectangle.lineStyle();</pre>
+	* 		<pre>myRoundRectangle.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/	
+	
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.		
+	* 		
+	* @usage   <pre>myRoundRectangle.fillStyle();</pre>
+	* 		<pre>myRoundRectangle.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/	
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "RoundRectangle";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/RoundRectangle.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Shape.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Shape.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Shape.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,230 @@
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+
+/**
+* @class Shape
+* @author Alex Uhlmann
+* @description  All drawing classes inside de.alex_uhlmann.animationpackage.drawing inherit their 
+* 			lineStyle and fillStyle properties from Shape. If you don't specify 
+* 			the lineStyle or fillStyle properties either with lineStyle() and fillStyle() methods 
+* 			or directly via the properties, the default lineStyle and fillStyle properties are used.
+* 			Shape gives you the opportunity	to set and retrieve default properties 
+* 			for lineStyle and fillStyle properties. 
+* 			Here is how those default properties are defined by default:		
+* 			<pre><blockquote>
+* 			Shape.lineThickness_def = null;
+*			Shape.lineRGB_def = 0x000000;
+*			Shape.lineAlpha_def = 100;	
+*			Shape.fillRGB_def = 0x000000;
+*			Shape.fillAlpha_def = 100;
+* 			Shape.gradientFillType_def = null;
+* 			Shape.gradientColors_def = null;
+* 			Shape.gradientAlphas_def = null;
+* 			Shape.gradientRatios_def = null;
+* 			Shape.gradientMatrix_def = null;
+* 			</pre></blockquote>
+* 			Note that all default properties have the same name as their instance properties 
+* 			but the suffix "_def".
+* 			<p>
+* 			Example 1: <a href="Shape_01.html">(Example .swf)</a> Declare 6 variables to store the three points that define the curve 
+* 			for easy access. To visualize the points and the curve draw it with 
+* 			the classes of the de.alex_uhlmann.animationpackage.drawing package. Then, 
+*  			move the movieclip along the specified curve in 4 seconds using Bounce easing.	
+* 			<pre><blockquote>
+*			var x1:Number = 100;
+*			var y1:Number = 100;
+*			var x2:Number = 400;
+*			var y2:Number = 200;
+*			var x3:Number = 500;
+*			var y3:Number = 400;
+*			
+*			var myQuadCurve:QuadCurve = new QuadCurve(x1,y1,x2,y2,x3,y3);
+*			myQuadCurve.lineStyle(6);
+*			myQuadCurve.draw();
+*			
+* 			//Since we want to draw three circles with the same style, which is not the default style, it makes sense to define default properties.
+*			Shape.lineRGB_def = 0xff0000;
+*			Shape.fillRGB_def = 0xff0000;
+*			
+*			new Ellipse(x1,y1,5,5).draw();						
+*			new Ellipse(x2,y2,5,5).draw();
+*			new Ellipse(x3,y3,5,5).draw();			
+*			
+*			var myMOC:MoveOnQuadCurve = new MoveOnQuadCurve(mc);
+*			myMOC.animationStyle(4000,Bounce.easeOut);
+*			myMOC.run(x1,y1,x2,y2,x3,y3);
+* 			</pre></blockquote>
+* 			<p> 
+* 			Some classes have similarities to their equivalent in java.awt.geom.
+* @usage <tt>private class constructor</tt> 
+*/
+class de.alex_uhlmann.animationpackage.drawing.Shape extends AnimationCore {
+	
+	/*static default properties*/
+	/** 
+	* @property lineThickness_def (Number)(static) default property. Outline thickness.
+	* @property lineRGB_def (Number)(static) default property. Outline color of the drawing as hex number.
+	* @property lineAlpha_def (Number)(static) default property. Outline transparency (alpha).
+	* @property fillRGB_def (Number)(static) default property. Fill color of the drawing.
+	* @property fillAlpha_def (Number)(static) default property. Fill transparency.
+	* 
+	* @property gradientFillType_def (String)(static) Gradient property. See MovieClip.beginGradientFill().
+	* @property gradientColors_def (Array)(static) Gradient property. See MovieClip.beginGradientFill().
+	* @property gradientAlphas_def (Array)(static) Gradient property. See MovieClip.beginGradientFill().
+	* @property gradientRatios_def (Array)(static) Gradient property. See MovieClip.beginGradientFill().
+	* @property gradientMatrix_def (Object)(static) Gradient property. See MovieClip.beginGradientFill().
+	*/
+	public static var lineRGB_def:Number = 0x000000;
+	public static var lineAlpha_def:Number = 100;	
+	public static var fillRGB_def:Number = 0x000000;
+	public static var fillAlpha_def:Number = 100;
+	private static var m_lineThickness_def:Number = null;
+	private static var lineThickness_defModified:Boolean = false;	
+	private static var gradientFillType_def:String;
+	private static var gradientColors_def:Array;	
+	private static var gradientAlphas_def:Array;
+	private static var gradientRatios_def:Array;	
+	private static var gradientMatrix_def:Object;
+	private var penX:Number;
+	private var penY:Number;
+	private var initialized:Boolean = false;
+	private var lineStyleModified:Boolean = false;
+	
+	private var m_lineThickness:Number;
+	private var m_lineRGB:Number;
+	private var m_lineAlpha:Number;	
+	public var fillRGB:Number;
+	public var fillAlpha:Number;
+	
+	public var fillGradient:Boolean = false;	
+	public var gradientFillType:String;
+	public var gradientColors:Array;	
+	public var gradientAlphas:Array;
+	public var gradientRatios:Array;	
+	public var gradientMatrix:Object;	
+	
+	private function Shape(noEvents:Boolean) {		
+		super(noEvents);
+		if(Shape.lineThickness_defModified) {
+			this.prepareLineStyle(Shape.m_lineThickness_def, null, null);			
+		}
+	}
+	
+	public function getPenPosition(Void):Object {
+		return {x:this.penX, y:this.penY};
+	}
+	
+	public function setPenPosition(p:Object):Void {
+		this.penX = p.x;
+		this.penY = p.y;
+	}
+	
+	public function lineStyle(lineThickness:Number, lineRGB:Number, lineAlpha:Number):Void {		
+		this.lineStyleModified = true;
+		this.m_lineThickness = (lineThickness === null) ? Shape.lineThickness_def : lineThickness;	
+		this.m_lineRGB = (lineRGB == null) ? Shape.lineRGB_def : lineRGB;
+		this.m_lineAlpha = (lineAlpha == null) ? Shape.lineAlpha_def : lineAlpha;		
+	}
+	
+	private function prepareLineStyle(lineThickness:Number, lineRGB:Number, lineAlpha:Number):Void {		
+		if(lineThickness == null) {
+			lineThickness = this.lineThickness;
+		}
+		if(lineRGB == null) {
+			lineRGB = this.lineRGB;
+		}
+		if(lineAlpha == null) {
+			lineAlpha = this.lineAlpha;
+		}
+		this.lineStyle(lineThickness, lineRGB, lineAlpha);
+	}	
+	
+	public function fillStyle(fillRGB:Number, fillAlpha:Number):Void {
+		this.fillGradient = false;
+		this.fillRGB = (fillRGB === null) ? Shape.fillRGB_def : fillRGB;
+		this.fillAlpha = (fillAlpha == null) ? Shape.fillAlpha_def : fillAlpha;
+	}
+
+	public function gradientStyle(fillType:String, colors:Array, alphas:Array, ratios:Array, matrix:Object):Void {
+		this.fillGradient = true;
+		this.gradientFillType = fillType;
+		this.gradientColors = colors;
+		this.gradientAlphas = alphas;
+		this.gradientRatios = ratios;
+		this.gradientMatrix = matrix;
+	}
+	
+	private function clearDrawing(Void):Void {
+		this.mc.clear();
+		if(this.lineStyleModified) {
+			this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+		}
+	}
+	
+	public function clear(Void):Void {
+		this.mc.clear();
+	}	
+	
+	public function draw(Void):Void {
+		this.clearDrawing();
+		this.drawNew();
+	}
+	
+	public function drawBy(Void):Void {
+		if(this.lineStyleModified) {
+			this.mc.lineStyle(this.lineThickness, this.lineRGB, this.lineAlpha);
+		}
+		this.drawNew();
+	}
+	
+	//fails silently.
+	private function drawNew(Void):Void {}
+	
+	public function setInitialized(initialized:Boolean):Void {
+		this.initialized = initialized;
+	}
+	
+	public function getInitialized(Void):Boolean {
+		return this.initialized;
+	}	
+	
+	public static function get lineThickness_def():Number {
+		return Shape.m_lineThickness_def;
+	}
+	
+	public static function set lineThickness_def(lineThickness_def:Number):Void {
+		if(lineThickness_def == null) {
+			Shape.lineThickness_defModified = false;
+		} else {
+			Shape.lineThickness_defModified = true;
+		}
+		Shape.m_lineThickness_def = lineThickness_def;
+	}
+	
+	public function get lineRGB():Number {		
+		return this.m_lineRGB;
+	}
+	
+	public function set lineRGB(lineRGB:Number):Void {
+		this.prepareLineStyle(null, lineRGB, null);		
+	}
+	
+	public function get lineAlpha():Number {
+		return this.m_lineAlpha;
+	}
+	
+	public function set lineAlpha(lineAlpha:Number):Void {
+		this.prepareLineStyle(null, null, lineAlpha);		
+	}
+	
+	public function get lineThickness():Number {
+		return this.m_lineThickness;
+	}
+	
+	public function set lineThickness(lineThickness:Number):Void {
+		this.prepareLineStyle(lineThickness, null, null);		
+	}
+
+	public function toString(Void):String {
+		return "Shape";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Shape.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/ShapeComposite.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/ShapeComposite.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/ShapeComposite.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,277 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.utility.IVisitor;
+import de.alex_uhlmann.animationpackage.utility.IVisitorElement;
+import de.alex_uhlmann.animationpackage.utility.IComposite;
+
+/**
+* @class ShapeComposite
+* @author e2e4, Alex Uhlmann
+* @description  ShapeComposite allows you to treat the classes of 
+* 			de.alex_uhlmann.animationpackage.drawing in a uniform manner.
+* 			ShapeComposite uses the composite design pattern. [GoF]
+* 			<p>
+* 			Example 1: <a href="ShapeComposite_01.html">(Example .swf)</a> 	
+* 			<pre><blockquote> 
+*			//Draw standard rectangles. Primitives.
+*			var myRect1:IDrawable = new Rectangle(100,100,100,90);
+*			var myRect2:IDrawable = new Rectangle(100,200,100,90);
+*			var myRect3:IDrawable = new Rectangle(100,300,100,90);
+*			
+*			//add the rectangle (primitives, leafs) to the composite myRectangles. The identifier allows you to remove rectangles at a later time with removeChild().		
+*			var myRectangles:ShapeComposite = new ShapeComposite();
+*			myRectangles.addChild(myRect1,"myRect1");
+*			myRectangles.addChild(myRect2,"myRect2");
+*			myRectangles.addChild(myRect3,"myRect3");
+*			
+*			//draw different shapes
+*			var myStar:IDrawable = new Star(250,100,50,25,6);
+*			var myGear:IDrawable = new Gear(250,200,40,50,8,15,10);
+*			var myBurst:IDrawable = new Burst(250,300,40,50,10);
+*			var myPoly:IDrawable = new Poly(400,100,50,6);
+*			var myRoundRectangle:IDrawable = new RoundRectangle(400,200,50,50,10);
+*			var myEllipse:IDrawable = new Ellipse(400,300,80,40);
+*			var myArc:IDrawable = new Arc(525,100,40,0,270,"CHORD");
+*			var myOpenArc:IDrawable = new Arc(525,200,40,0,270,"OPEN");
+*			var myPie:IDrawable = new Arc(525,300,40,0,300,"PIE");
+*			
+*			//add the shapes (primitives, leafs) to the composite allMyShapes.
+*			var allMyShapes:ShapeComposite = new ShapeComposite();
+*			allMyShapes.addChild(myStar,"myStar");
+*			allMyShapes.addChild(myGear,"myGear");
+*			allMyShapes.addChild(myBurst,"myBurst");
+*			allMyShapes.addChild(myPoly,"myPoly");
+*			allMyShapes.addChild(myRoundRectangle,"myRoundRectangle");
+*			allMyShapes.addChild(myEllipse,"myEllipse");
+*			allMyShapes.addChild(myArc,"myArc");
+*			allMyShapes.addChild(myOpenArc,"myOpenArc");
+*			allMyShapes.addChild(myPie,"myPie");
+*			
+*			//add all the rectangles (composite) to the composite allMyShapes.
+*			allMyShapes.addChild(myRectangles,"myRectangles");
+*			
+*			//treat everything inside the composite allMyShapes in a uniform manner.
+*			allMyShapes.lineStyle(2,0x990000);
+*			allMyShapes.fillStyle(0xff0000,100);
+*			allMyShapes.draw();
+*			
+*			//animate everything in allMyShapes.
+*			var shapeArr:Array = allMyShapes.getChilds();
+*			for(var i = 0; i < shapeArr.length; i++) {	
+*				var mc:MovieClip = shapeArr[i].movieclip;
+*				new ColorTransform(mc).run(0x00ff00,50,10000);	
+*				new Rotation(mc).run(360,10000,Elastic.easeOut);
+*			}
+* 			</pre></blockquote>
+* 			<p> 			
+* @usage <tt>var myShapeComposite:ShapeComposite = new ShapeComposite();</tt> 
+*/
+class de.alex_uhlmann.animationpackage.drawing.ShapeComposite 
+											extends APCore 
+											implements IDrawable, 
+													IVisitorElement, 
+													IComposite {	
+	
+	private var childs:Object;
+	private var identifier:Number;
+	
+	public function ShapeComposite() {		
+		super.init(true);
+		this.childs = {};
+		this.identifier = 0;
+	}
+	
+	/**
+	* @method draw
+	* @description 	Draws all the shapes of the composite.		
+	* @usage <pre>myShapeComposite.draw();</pre>
+	*/
+	public function draw(Void):Void {
+		var identifier:String;
+		for (identifier in this.childs) {
+			this.childs[identifier].draw(); 
+		}
+	}
+	
+	/**
+	* @method drawBy
+	* @description 	draws all the shapes of the composite.		
+	* @usage <pre>myShapeComposite.draw();</pre>
+	*/
+	public function drawBy(Void):Void {
+		var identifier:String;
+		for (identifier in this.childs) {
+			this.childs[identifier].drawBy(); 
+		}
+	}	
+	
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myShapeComposite.lineStyle();</pre>
+	* 		<pre>myShapeComposite.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/	
+	public function lineStyle(lineThickness:Number, lineRGB:Number, lineAlpha:Number):Void {		
+		var identifier:String;
+		for (identifier in this.childs) {
+			this.childs[identifier].lineStyle(lineThickness, lineRGB, lineAlpha);
+		}
+	}
+	
+	/**
+	* @method fillStyle
+	* @description 	 define fill.		
+	* 		
+	* @usage   <pre>myShapeComposite.fillStyle();</pre>
+	* 		<pre>myShapeComposite.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	public function fillStyle(fillRGB:Number, fillAlpha:Number):Void {
+		var identifier:String;
+		for (identifier in this.childs) {			
+			this.childs[identifier].fillStyle(fillRGB, fillAlpha);
+		}
+	}
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/
+	public function gradientStyle(fillType:String, colors:Array, alphas:Array, ratios:Array, matrix:Object):Void {
+		var identifier:String;
+		for (identifier in this.childs) {			
+			this.childs[identifier].gradientStyle(fillType, colors, alphas, ratios, matrix);
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/
+	public function clear(Void):Void {
+		var identifier:String;
+		for (identifier in this.childs) {			
+			this.childs[identifier].clear();
+		}
+	}
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the composite.
+	* @usage <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		var identifier:String;
+		for (identifier in this.childs) {			
+			this.childs[identifier].setRegistrationPoint(registrationObj);
+		}
+	}	
+	
+	/**
+	* @method getChilds
+	* @description 	returns all stored composites and primitives as primitives. 
+	* 				Note that this method ignores hierarchies in your composite 
+	* 				for the sake of easy manipulation of all IDrawable shapes. See class description for an example.
+	* @usage  <pre>myShapeComposite.getChilds();</pre>		
+	* @return Array that returns the stored composites and primitives as primitves.
+	*/
+	public function getChilds(Void):Array {		
+		/*copy the childs object into an array for easy manipulation.*/		
+		var childArr:Array = new Array();
+		var identifier:String;
+		for (identifier in this.childs) {			
+			var child:Object = childs[identifier];
+			if(child instanceof ShapeComposite) {					
+				var innerChild:Array = child.getChilds();
+				var len:Number = innerChild.length;
+				while(len--) {					
+					childArr.push(innerChild[len]);
+				}				
+			} else {
+				childArr.push(child);
+			}			
+		}	
+		return childArr;		
+	}
+	
+	/**
+	* @method addChild
+	* @description 	adds a primitive or composite to the composite instance of ShapeComposite 
+	* See class description.
+	* @usage  <pre>myShapeComposite.addChild(shape, identifier);</pre>
+	* @param component (IDrawable) Must be compatible to IDrawable.
+	* @param identifier (String) String that identifies shape to the user.	
+	* @return IDrawable component that was added.
+	*/
+	public function addChild(component:IDrawable, identifier:String):IDrawable {		
+		if(!identifier) {
+			identifier = this.generateIdentifier();
+		}
+		this.childs[identifier] = component;
+		return component;
+	}
+	
+	/**
+	* @method removeChild
+	* @description 	removes a primitive or composite from the composite instance of ShapeComposite 
+	* See class description.
+	* @usage  <pre>myShapeComposite.removeChild(identifier);</pre>
+	* @param identifier (String) String that identifies shape to the user.	
+	*/
+	public function removeChild(identifier:String):Void {		
+		if(this.childs[identifier]) {
+			delete this.childs[identifier];
+		}
+	}
+	
+	/**
+	* @method accept
+	* @description 	Allow a visitor to visit its elements. See Visitor design pattern [GoF].
+	* @usage  <pre>myInstance.accept(visitor);</pre>
+	* @param visitor (IVisitor) Must be compatible to de.alex_uhlmann.animationpackage.utility.IVisitor.	
+	*/
+	public function accept(visitor:IVisitor):Void {
+		var identifier:String;
+		for (identifier in this.childs) {
+			visitor.visit(this.childs[identifier]);
+		}
+	}	
+	
+	private function generateIdentifier(Void):String {
+		return String(++this.identifier);
+	}
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/	
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "ShapeComposite";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/ShapeComposite.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Spiral.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Spiral.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Spiral.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,747 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class Spiral
+* @author Alex Uhlmann
+* @description Spiral is a class for drawing regular and elliptical spirals (non-logarithmic).	
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.			
+* 			<p>
+* 			Example 1: draw a spiral with 3 cycles and standars parameters.		
+* 			<blockquote><pre>
+*			var mySpiral:Spiral = new Spiral();
+*			mySpiral.setEndValue(3);
+* 			mySpiral.draw();
+*			</pre></blockquote> 
+* 			Example 2: do the same, just animate it.		
+* 			<blockquote><pre>
+*			var mySpiral:Spiral = new Spiral();
+*			mySpiral.setEndValue(3);
+*			mySpiral.animate(0,100);
+*			</pre></blockquote> 
+* 			Example 3: <a href="Spiral_03.html">(Example .swf)</a> draw an animated spiral with custom parameters, that 
+* 			continues to animated to full size and back.
+* 			<blockquote><pre>
+*			var mySpiral:Spiral = new Spiral(275,200,0,0,10,10);
+*			mySpiral.setStartValue(0);
+*			mySpiral.setEndValue(10);
+*			mySpiral.lineStyle(1,0xff0000,100);
+*			mySpiral.animationStyle(1000,Cubic.easeInOut,"onCallback");
+*			mySpiral.animate(0,100);
+*			myListener.onCallback = function(source, value)
+*			{				
+*				if(value == 10) {
+*					source.animate(100,0);
+*				} else {
+*					source.animate(0,100);
+*				}	
+*			}
+*			</pre></blockquote> 
+* @usage <pre>var mySpiral:Spiral = new Spiral();</pre> 
+*		<pre>var mySpiral:Spiral = new Spiral(x, y, xRadius, yRadius, xGrowth, yGrowth, startAngle);</pre>
+* 		<pre>var mySpiral:Spiral = new Spiral(mc, x, y, xRadius, yRadius, xGrowth, yGrowth, startAngle);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param xRadius (Number) Radius for x-axis in pixels.
+* @param yRadius (Number) Radius for y-axis in pixels.
+* @param xGrowth (Number) Number of pixels added to xRadius with each complete revolution.
+* @param yGrowth (Number) Number of pixels added to yRadius with each complete revolution.
+* @param startAngle (Number) Starting angle in degrees. A value of 0 starts rendering at (x,y).
+* @param revolutions (Number) Number of complete cycles in final spiral.
+*/
+class de.alex_uhlmann.animationpackage.drawing.Spiral 
+											extends Shape 
+											implements IDrawable, 
+												ISingleAnimatable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/	
+	/*animationStyle properties inherited from APCore*/
+	/**	
+	* @property xRadius_def (Number)(static) default property. Radius for x-axis in pixels.
+	* @property yRadius_def (Number)(static) default property. Radius for y-axis in pixels.
+	* @property xGrowth_def (Number)(static) default property. Number of pixels added to xRadius with each complete revolution.
+	* @property yGrowth_def (Number)(static) default property. Number of pixels added to yRadius with each complete revolution.
+	* @property startAngle_def (Number)(static) default property. Starting angle in degrees. A value of 0 starts rendering at (x,y).
+	* @property revolutions_def (Number)(static) default property. Number of complete cycles in final spiral. Defaults to 9.
+	*
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).	
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/	
+	public static var xRadius_def:Number = 0;
+	public static var yRadius_def:Number = 0;
+	public static var xGrowth_def:Number = 9;
+	public static var yGrowth_def:Number = 9;
+	public static var startAngle_def:Number = 0;
+	public static var revolutions_def:Number = 9;
+	private var x:Number = 0;
+	private var y:Number = 0;	
+	private var xRadius:Number;
+	private var xGrowth:Number;
+	private var yRadius:Number;
+	private var yGrowth:Number;
+	private var startAngle:Number;
+	private var revolutions:Number;	
+	
+	/*startAngle doesn't seem to have any effect on the spiral*/
+	public function Spiral() {
+		super();
+		this.init.apply(this,arguments);
+		this.lineStyle(null);
+		this.animationStyle();
+	}
+
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, xRadius:Number, yRadius:Number, 
+					xGrowth:Number, yGrowth:Number, startAngle:Number, revolutions:Number):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:x, y:y});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, xRadius:Number, yRadius:Number, 
+					xGrowth:Number, yGrowth:Number, startAngle:Number, revolutions:Number):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x:Number, y:Number, xRadius:Number, yRadius:Number, 
+					xGrowth:Number, yGrowth:Number, startAngle:Number, revolutions:Number):Void {
+	
+		this.xRadius = (xRadius == null) ? Spiral.xRadius_def : xRadius;
+		this.yRadius = (yRadius == null) ? Spiral.yRadius_def : yRadius;
+		this.xGrowth = (xGrowth == null) ? Spiral.xGrowth_def : xGrowth;
+		this.yGrowth = (yGrowth == null) ? Spiral.yGrowth_def : yGrowth;
+		this.startAngle = (startAngle == null) ? Spiral.startAngle_def : startAngle;
+		this.revolutions = (revolutions == null) ? Spiral.revolutions_def : revolutions;
+		this.setStartValue(this.startAngle);
+		this.setEndValue(this.revolutions);	
+	}
+	
+	/**
+	* @method draw
+	* @description 	Draws regular and elliptical spirals (non-logarithmic). 		
+	* @usage <pre>mySpiral.draw();</pre>
+	*/	
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/	
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		var goto:Boolean;
+		if(end == null) {
+			goto = true;
+			end = start;
+			start = 0;			
+		} else {
+			goto = false;
+		}
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [this.startValue];
+		this.myAnimator.end = [this.endValue];
+		this.myAnimator.setter = [[this, "drawShape"]];
+		if(goto == false) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(end);
+		}
+	}
+	
+	public function setStartValue(startValue:Number, optional:Boolean):Boolean {
+		this.startAngle = startValue;
+		return super.setStartValue(startValue);
+	}
+	
+	public function setEndValue(endValue:Number):Boolean {
+		this.revolutions = endValue;
+		return super.setEndValue(endValue);
+	}	
+	
+	/**
+	* @method animate
+	* @description 	Animates regular and elliptical spirals (non-logarithmic). 		
+	* @usage <pre>mySpiral.animate(start, end);</pre>
+	* @param start (Number) starting position of spiral.
+	* @param end (Number) Number of complete cycles in final spiral.
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>instance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/
+	
+	/**
+	* @method getRadius
+	* @description 	Returns the radii for the axes in pixels.
+	* @usage  <pre>mySpiral.getRadius();</pre>
+	* @return Object that contains x (xRadius) and y (yRadius) properties. 
+	*/	
+	public function getRadius(Void):Object {		
+		return { x:this.xRadius, y:this.yRadius };		
+	}
+		
+	/**
+	* @method setRadius
+	* @description 	Sets the radii for the axes in pixels.
+	* 		
+	* @usage   <pre>mySpiral.setRadius(xRadius, yRadius);</pre>
+	* 	  
+	* @param xRadius (Number) Radius for x-axis in pixels.
+	* @param yRadius (Number) Radius for y-axis in pixels.
+	*/	
+	public function setRadius(xRadius:Number, yRadius:Number):Void {	
+		this.xRadius = xRadius;
+		this.yRadius = yRadius;		
+	}
+	
+	/**
+	* @method getGrowth
+	* @description 	Returns the numbers of pixels added to the radii with each complete revolution.
+	* @usage  <pre>mySpiral.getGrowth();</pre>
+	* @return Object that contains x (xGrowth) and y (yGrowth) properties. 
+	*/	
+	public function getGrowth(Void):Object {		
+		return { x:this.xGrowth, y:this.yGrowth };	
+	}
+		
+	/**
+	* @method setGrowth
+	* @description 	Sets the numbers of pixels added to the radii with each complete revolution.	
+	* 		
+	* @usage   <pre>mySpiral.setGrowth(xGrowth, yGrowth);</pre>
+	* 	  
+	* @param xGrowth (Number) Number of pixels added to xRadius with each complete revolution.
+	* @param yGrowth (Number) Number of pixels added to yRadius with each complete revolution.
+	*/	
+	public function setGrowth(xGrowth:Number, yGrowth:Number):Void {	
+		this.xGrowth = xGrowth;
+		this.yGrowth = yGrowth;		
+	}
+	
+	/**
+	* @method getStartAngle
+	* @description deprecated. Use getStartValue instead.
+	* @usage  <pre>mySpiral.getStartAngle();</pre>
+	* @return Number
+	*/
+	public function getStartAngle(Void):Number {
+		return this.startAngle;		
+	}
+	
+	/**
+	* @method setStartAngle
+	* @description deprecated. Use setStartValue instead.
+	* @usage  <pre>mySpiral.setStartAngle(startAngle);</pre>
+	* @param startAngle Number
+	*/
+	public function setStartAngle(startAngle:Number):Void {
+		this.startAngle = startAngle;
+		this.setStartValue(startAngle);
+	}	
+	
+	/**
+	* @method getRevolutions
+	* @description 	deprecated. Use getEndValue instead. Returns the number of complete cycles in final spiral.
+	* @usage  <pre>mySpiral.getRevolutions();</pre>
+	* @return Number
+	*/
+	public function getRevolutions(Void):Number {
+		return this.revolutions;		
+	}
+	
+	/**
+	* @method setRevolutions
+	* @description 	deprecated. Use setEndValue instead. Sets the number of complete cycles in final spiral.
+	* @usage  <pre>mySpiral.setRevolutions(angExt);</pre>
+	* @param angExt Number
+	*/
+	public function setRevolutions(revolutions:Number):Void {
+		this.revolutions = revolutions;
+		this.setEndValue(revolutions);
+	}
+	
+	public function drawShape(v:Number):Void {
+		this.clearDrawing();
+		this.revolutions = v;
+		this.drawNew();
+	}
+	
+	private function drawNew(Void):Void {	
+		this.mc.moveTo(this.x, this.y);
+		this.drawSpiral(this.x, this.y, this.startAngle, this.revolutions, 
+						this.xRadius, this.xGrowth, this.yRadius, this.yGrowth);
+	}
+	
+	/* *** MovieClip.drawSpiral *********************************************************************************
+	 ************************************************************************************************************
+	 **  PURPOSE:	a method for drawing regular and elliptical spirals (non-logarithmic). This method was 
+	 **				inspired by an afternoon (ok, a whole freakin' day)	spent with a number of advanced 
+	 **				drawing API methods written by Ric Ewing (ric at ricewing.com). Ric's code is available here:
+	 **
+	 **						http://www.macromedia.com/devnet/mx/flash/articles/adv_draw_methods.html
+	 **
+	 **				I have changed my code somewhat so that it will blend in reasonably well with Ric's methods.
+	 **				Thanks to Ric for the inspiration.
+	 **
+	 **  NOTE:		I REALLY wanted to do this with fewer segments per revolution (e.g. the usual 8) using curveTo
+	 **				instead of lineTo, but I was unable to figure out how to determine the control points 
+	 **				correctly. If anyone can clue me in on the required math, I will update this method and give 
+	 **				you due credit and boundless gratitude. Enjoy.  ---jim
+	 **	
+	 **	 REQUIRED PARAMETERS:
+	 **
+	 **		x, y	    -- center point for the spiral
+	 **		startAngle  -- starting angle in degrees. a value of 0 starts rendering at (x,y)
+	 **		revolutions -- number of complete cycles in final spiral
+	 **		xRadius		-- radius for x-axis in pixels
+	 **		xGrowth	    -- number of pixels added to xRadius with each complete revolution
+	 **
+	 **	 OPTIONAL PARAMETERS: ( will be set identical to x-values if not included )
+	 **
+	 **		yRadius     -- radius for y-axis in pixels
+	 **		yGrowth	    -- number of pixels added to xRadius with each complete revolution
+	 **
+	 **
+	 **	 BY::::::::::::::::::::james w. bennett iii ( snowballs.chance at hell.com ) -- version 1.0 -- march2003
+	 **
+	 ******/
+	private function drawSpiral(x:Number, y:Number, startAngle:Number, revolutions:Number, 
+								xRadius:Number, xGrowth:Number, yRadius:Number, yGrowth:Number):Void {
+		
+		// drawing resolution. STEP_SIZE = 6 yields 60 linesegments per revolution
+		var STEP_SIZE:Number = 6; 	// in degrees
+		
+		// if y-axis information not included, set identical to x-axis
+		if ( yRadius == undefined )
+		{
+			yRadius = xRadius;
+			yGrowth = xGrowth;
+		}
+		else if ( yGrowth == undefined )
+		{
+			yGrowth = xGrowth;
+		}
+	
+	
+		// reverse the signs in order to reverse directions
+		if ( revolutions < 0 )
+		{
+			STEP_SIZE  = -STEP_SIZE;
+			startAngle = -startAngle;
+		}
+	
+		// initialize variables
+		var startRadians:Number, currentRadians:Number, endRadians:Number;
+		var xRadiusDelta:Number, yRadiusDelta:Number;
+		var stepsPerRevolution:Number;
+		var ax:Number, ay:Number;
+		var bx:Number, by:Number;		
+		// convert angles from degrees to radians
+		startRadians = -(startAngle / 180) * Math.PI;
+		endRadians   = -((revolutions * 360) / 180) * Math.PI;
+		var theta:Number        = -(STEP_SIZE   / 180) * Math.PI;
+		
+		// calculate step size
+		stepsPerRevolution = Math.abs((2 * Math.PI) / theta);
+		
+		// calculate pixel-growth per step
+		xRadiusDelta = xGrowth / stepsPerRevolution;
+		yRadiusDelta = yGrowth / stepsPerRevolution;
+		
+		// get the starting point and ... 
+		ax = x + xRadius * Math.cos( startRadians );
+		ay = y + yRadius * Math.sin( startRadians );
+		
+		// ... move there
+		this.mc.moveTo( ax, ay );
+		
+		// advance angle by one step (theta)
+		currentRadians = startRadians + theta;
+		
+		// draw it
+		while( Math.abs(currentRadians) < Math.abs(endRadians) )
+		{
+			// calculate the next point
+			bx = x + xRadius * Math.cos( currentRadians );
+			by = y + yRadius * Math.sin( currentRadians );
+			
+			// draw the line to it
+			this.mc.lineTo( bx, by );
+			
+			// advance the angle
+			currentRadians += theta;
+			
+			// increase the radius
+			xRadius += xRadiusDelta;
+			yRadius += yRadiusDelta;
+		}
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>mySpiral.lineStyle();</pre>
+	* 		<pre>mySpiral.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 		
+	* 		
+	* @usage   <pre>mySpiral.animationStyle(duration);</pre>
+	* 		<pre>mySpiral.animationStyle(duration, callback);</pre>
+	* 		<pre>mySpiral.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		if(registrationObj.position == "CENTER") {		
+			this.x = 0;
+			this.y = 0;
+		} else {	
+			this.x = (this.revolutions * this.xGrowth) + registrationObj.x;
+			this.y = (this.revolutions * this.yGrowth) + registrationObj.y;			
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/	
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. In revolutions.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. In revolutions.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/	
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In revolutions. 
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>mySpiral.addEventListener(event, listener);</pre>
+	* 		    <pre>mySpiral.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>mySpiral.removeEventListener(event, listener);</pre>
+	* 		    <pre>mySpiral.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>mySpiral.removeAllEventListeners();</pre>
+	* 		    <pre>mySpiral.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>mySpiral.eventListenerExists(event, listener);</pre>
+	* 			<pre>mySpiral.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Spiral";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Spiral.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Star.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Star.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Star.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,345 @@
+import de.alex_uhlmann.animationpackage.drawing.IDrawable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+
+/**
+* @class Star
+* @author Alex Uhlmann
+* @description Star is a class for drawing star shaped polygons. Note that the stars by default 
+* 			'point' to	the right. This is because the method starts drawing
+*			at 0 degrees by default, putting the first point to the right of center. 
+*			Negative values for sides	draws the star in reverse direction, allowing for
+*			knock-outs when used as part of a mask.
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip. 
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Example 1: draw a star with default parameters.		
+* 			<blockquote><pre>
+*			var myStar:Star = new Star();
+*			myStar.draw();
+*			</pre></blockquote> 
+* 			Example 2: draw a star with custom parameters.		
+* 			<blockquote><pre>
+*			var myStar:Star = new Star(275,200,100,25,6);
+*			myStar.lineStyle(2,0xff0000,100);
+*			myStar.fillStyle(0xff0000,100);
+*			myStar.draw();
+*			</pre></blockquote>
+* 			Example 3. <a href="Star_03.html">(Example .swf)</a> A star that only consists of straight lines.
+*			<blockquote><pre>
+* 			var myStar:Star = new Star(275,200,100,0,6);
+*			myStar.lineStyle(2,0xff0000,100);
+*			myStar.fillStyle(0xff0000,100);
+*			myStar.draw();
+* 			</pre></blockquote>			
+* @usage <pre>var myStar:Star = new Star();</pre>
+* 		<pre>var myStar:Star = new Star(x, y, innerRadius, outerRadius, sides);</pre>
+* 		<pre>var myStar:Star = new Star(mc, x, y, innerRadius, outerRadius, sides);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param innerRadius (Number) Radius of the indent of the sides.
+* @param outerRadius (Number) Radius of the tips of the sides.
+* @param sides (Number) Number of sides (must be > 2)	 
+*/
+class de.alex_uhlmann.animationpackage.drawing.Star 
+									extends Shape 
+									implements IDrawable {	
+	
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/
+	/** 
+	* @property innerRadius_def (Number)(static) default property. Radius of the indent of the sides.
+	* @property outerRadius_def (Number)(static) default property. Radius of the tips of the sides.
+	* @property sides_def (Number)(static) default property. Number of sides (must be > 2). Defaults to 4.
+	* 
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.	
+	*/	
+	public static var innerRadius_def:Number = 25;
+	public static var outerRadius_def:Number = 100;
+	public static var sides_def:Number = 4;
+	private var x:Number = 0;
+	private var y:Number = 0;
+	private var innerRadius:Number;
+	private var outerRadius:Number;
+	private var sides:Number;
+	private var angle:Number;
+	
+	public function Star() {
+		super(true);
+		this.init.apply(this,arguments);
+		this.fillStyle(null);
+	}
+	
+	private function init():Void {		
+		if(typeof(arguments[0]) == "movieclip") {					
+			this.initCustom.apply(this,arguments);
+		} else {			
+			this.initAuto.apply(this,arguments);
+		}			
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number, innerRadius:Number, outerRadius:Number, sides:Number):Void {		
+		
+		this.mc = this.createClip({mc:mc, x:x, y:y});		
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto(x:Number, y:Number, innerRadius:Number, outerRadius:Number, sides:Number):Void {		
+		
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});		
+		this.initShape.apply(this,arguments);
+	}
+		
+	private function initShape(x:Number, y:Number, innerRadius:Number, outerRadius:Number, sides:Number):Void {
+	
+		this.innerRadius = (innerRadius == null) ? Star.innerRadius_def : innerRadius;
+		this.outerRadius = (outerRadius == null) ? Star.outerRadius_def : outerRadius;
+		this.sides = (sides == null) ? Star.sides_def : sides;
+		this.angle = 0;
+	}
+	
+	/*inherited from Shape*/
+	/**
+	* @method draw
+	* @description 	Draws stars.		
+	* @usage <pre>myStar.draw();</pre>
+	*/
+	
+	/**
+	* @method drawBy
+	* @description 	Draws the shape without clearing the movieclip.
+	* @usage <pre>myInstance.drawBy();</pre>
+	*/
+	
+	/**
+	* @method getInnerRadius
+	* @description 	Return the radius of the indent of the sides.
+	* @usage  <pre>myStar.getInnerRadius();</pre>
+	* @return Number of the radius of the indent of the sides.
+	*/	
+	public function getInnerRadius(Void):Number {		
+		return this.innerRadius;		
+	}
+		
+	/**
+	* @method setInnerRadius
+	* @description 	Sets the radius of the indent of the sides.	
+	* 		
+	* @usage   <pre>myStar.setInnerRadius(innerRadius);</pre>
+	* 	  
+	* @param innerRadius (Number) radius of the indent of the sides.
+	*/	
+	public function setInnerRadius(innerRadius:Number):Void {	
+		this.innerRadius = innerRadius;		
+	}	
+	
+	/**
+	* @method getOuterRadius
+	* @description 	Return the radius of the tips of the sides.
+	* @usage  <pre>myStar.getOuterRadius();</pre>
+	* @return Number of the radius of the tips of the sides.
+	*/	
+	public function getOuterRadius(Void):Number {		
+		return this.outerRadius;		
+	}
+		
+	/**
+	* @method setOuterRadius
+	* @description 	Sets the radius of the tips of the sides.	
+	* 		
+	* @usage   <pre>myStar.setOuterRadius(outerRadius);</pre>
+	* 	  
+	* @param outerRadius (Number) radius of the tips of the sides.
+	*/	
+	public function setOuterRadius(outerRadius:Number):Void {	
+		this.outerRadius = outerRadius;		
+	}
+	
+	/**
+	* @method getSides
+	* @description 	Return the sides of the drawing.
+	* @usage  <pre>myStar.getSides();</pre>
+	* @return Number of sides. 
+	*/	
+	public function getSides(Void):Number {		
+		return this.sides;		
+	}
+	
+	/**
+	* @method setSides
+	* @description 	Sets the sides of the drawing.		
+	* 		
+	* @usage   <pre>myStar.setSides(sides);</pre>
+	* 	  
+	* @param sides (Number) the number of sides.
+	*/	
+	public function setSides(sides:Number):Void {	
+		this.sides = sides;		
+	}	
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.		
+	* 		
+	* @usage   <pre>myStar.lineStyle();</pre>
+	* 		<pre>myStar.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	* 	  
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.	
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+	
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.		
+	* 		
+	* @usage   <pre>myStar.fillStyle();</pre>
+	* 		<pre>myStar.fillStyle(fillRGB, fillAlpha);</pre>
+	* 	  
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>myShapeComposite.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/
+	
+	private function drawNew(Void):Void {
+		this.mc.moveTo(this.x, this.y);
+		if (this.fillRGB != null && this.fillGradient == false) {
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, 
+										this.gradientColors, 
+										this.gradientAlphas, 
+										this.gradientRatios, 
+										this.gradientMatrix);
+		}		
+		this.drawStar(this.x, 
+						this.y, 
+						this.sides, 
+						this.innerRadius, 
+						this.outerRadius, 
+						this.angle);
+		this.mc.endFill();
+	}	
+	
+	/*-------------------------------------------------------------
+		drawStar is a method for drawing star shaped
+		polygons. Note that the stars by default 'point' to
+		the right. This is because the method starts drawing
+		at 0 degrees by default, putting the first point to
+		the right of center. Negative values for points
+		draws the star in reverse direction, allowing for
+		knock-outs when used as part of a mask.
+	-------------------------------------------------------------*/
+	private function drawStar(x:Number, y:Number, points:Number, 
+							  innerRadius:Number, outerRadius:Number, angle:Number):Void {
+		
+		// ==============
+		// drawStar() - by Ric Ewing (ric at formequalsfunction.com) - version 1.4 - 4.7.2002
+		// 
+		// x, y = center of star
+		// points = number of points (Math.abs(points) must be > 2)
+		// innerRadius = radius of the indent of the points
+		// outerRadius = radius of the tips of the points
+		// angle = [optional] starting angle in degrees. (defaults to 0)
+		// ==============
+		var count:Number = Math.abs(points);
+		if (count>2) {
+			// init vars
+			var step:Number, halfStep:Number, start:Number, n:Number, dx:Number, dy:Number;
+			// calculate distance between points
+			step = (Math.PI*2)/points;
+			halfStep = step/2;
+			// calculate starting angle in radians
+			start = (angle/180)*Math.PI;
+			this.mc.moveTo(x+(Math.cos(start)*outerRadius), y-(Math.sin(start)*outerRadius));
+			// draw lines
+			for (n=1; n<=count; n++) {
+				dx = x+Math.cos(start+(step*n)-halfStep)*innerRadius;
+				dy = y-Math.sin(start+(step*n)-halfStep)*innerRadius;
+				this.mc.lineTo(dx, dy);
+				dx = x+Math.cos(start+(step*n))*outerRadius;
+				dy = y-Math.sin(start+(step*n))*outerRadius;
+				this.mc.lineTo(dx, dy);
+			}
+		}
+	}
+	
+	/**
+	* @method setRegistrationPoint
+	* @description 	Sets the registration point of the shape. Defaults to center. Top left is 0,0. 
+	* 					The parameter object accepts either a position property with the value of "CENTER" 
+	* 					or x and y properties of with coordinates as values of the registration point.
+	* 			<p>
+	* 			Example 1: Set the registration point of an ellipse to the upper left corner (0,0) instead of center.
+	* 			<blockquote><pre>
+	*			var myEllipse:Ellipse = new Ellipse(275,200,100,50);
+	*			myEllipse.setRegistrationPoint( {x:0,y:0} );
+	*			myEllipse.draw();
+	*			</pre></blockquote>
+	* 			<p>
+	* 			internally AnimationPackage centers all shapes with
+	* 			<blockquote><pre>
+	*			myInstance.setRegistrationPoint( {position:"CENTER"} );
+	*			</pre></blockquote>	
+	* @usage   <pre>myInstance.setRegistrationPoint(registrationObj);</pre>
+	* 	  
+	* @param registrationObj (Object)
+	*/
+	public function setRegistrationPoint(registrationObj:Object):Void {
+		if(registrationObj.position == "CENTER") {		
+			this.x = 0;
+			this.y = 0;
+		} else {			
+			if(this.innerRadius > this.outerRadius) {
+				this.x = this.innerRadius + registrationObj.x;
+				this.y = this.innerRadius + registrationObj.y;
+			} else {
+				this.x = this.outerRadius + registrationObj.x;
+				this.y = this.outerRadius + registrationObj.y;
+			}
+		}
+	}
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Star";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/Star.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/SuperShape.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/SuperShape.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/SuperShape.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,1083 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.drawing.Shape;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class SuperShape
+* @author Alex Uhlmann
+* @description SuperShape allows you to draw many different shapes based on the Superformula developed by 
+* 			<a href="http://www.genicap.com/">Johan Gielis</a>.
+* 			The Superformula used by SuperShape is one simple equation that can generate a vast diversity of natural shapes.
+*			 It produces everything from simple triangles and pentagons, to stars, spirals and petals.
+* 			More information on the Superformula: <a href="http://astronomy.swin.edu.au/~pbourke/curves/supershape">Paul Bourke</a>.
+* 			Based on the first Flash implementations of <a href="http://www.flashforum.de/forum/showthread.php?s=&threadid=120213">Flashforum members</a>,
+* 			Especially based on e2e4 and i++ contributions. 
+* 			If you specify a movieclip as first parameter, the shape will be drawn inside this movieclip.
+* 			If you omit the mc parameter, the class will create a new movieclip in _root.apContainer_mc.
+* 			<p>
+* 			Here is an application that may help you testing different parameters of SuperShape: <a href="SuperShape_preview.html">(Testing application)</a>
+* 			<p>
+* 			Example 1: Some shape manipulations. <a href="SuperShape_01.html">(Example .swf)</a> 
+* 			<blockquote><pre>
+*			var mySuperShape:SuperShape = new SuperShape(300,300);
+*			//like the MovieClip lineStyle(), lineStyle in AnimationPackage also omits the line if you call it without a parameter.
+*			mySuperShape.lineStyle();
+*			mySuperShape.fillStyle(0xff0000);
+*			
+*			mySuperShape.animationStyle(3000,Sine.easeInOut,"onStart");
+*			mySuperShape.setPreset("burst");
+*			
+*			mySuperShape.addPreset({label:"rounded Polygon", data:{m:5, n1:1, n2:1.7, n3:1.7, range:2, scaling:2, detail:1000}});
+*			
+*			mySuperShape.morph("burst","rounded Polygon");
+*			
+*			myListener.onStart = function() {	
+*				mySuperShape.callback = "onRoundStar";
+*				mySuperShape.animateProps(["n1"],[0.09]);
+*			}
+*			myListener.onRoundStar = function() {	
+*				mySuperShape.callback = "onN1Out";
+*				mySuperShape.animateProps(["n1"],[1]);
+*			}
+*			myListener.onN1Out = function() {	
+*				mySuperShape.callback = "onN2In";
+*				mySuperShape.animateProps(["n2"],[6]);
+*			}
+*			myListener.onN2In = function() {	
+*				mySuperShape.callback = "onN2Out";
+*				mySuperShape.animateProps(["n2"],[1]);
+*			}
+*			myListener.onN2Out = function() {		
+*				mySuperShape.callback = "onN3In";
+*				mySuperShape.animateProps(["n2","n3"],[6,6]);
+*			}
+*			myListener.onN3In = function() {
+*				mySuperShape.callback = null;
+*				mySuperShape.animateProps(["n2","n3"],[1,1]);
+*			}
+* 			</pre></blockquote>
+* 			<p>
+* 			Example 2: Some other shape manipulations. <a href="SuperShape_02.html">(Example .swf)</a>
+* 			<blockquote><pre>
+* 			var mySuperShape:SuperShape = new SuperShape(300,300);
+*			mySuperShape.lineStyle(3,0xff0000);
+*			mySuperShape.fillStyle();
+*			mySuperShape.animationStyle(3000,Sine.easeInOut,"on01");
+*			mySuperShape.addPreset({label:"0", data:{m:10, n1:0, n2:1.7, n3:0, range:2, scaling:2, detail:1000}});
+*			mySuperShape.addPreset({label:"1", data:{m:10, n1:1, n2:1.7, n3:1.7, range:2, scaling:2, detail:1000}});
+*			mySuperShape.morph("0","1");
+*			myListener.on01 = function() {	
+*				mySuperShape.callback = "on23";
+*				mySuperShape.addPreset({label:"2", data:{m:10, n1:3, n2:1.3, n3:8, range:2, scaling:2, detail:1000}});
+*				mySuperShape.morph("1","2");
+*			}
+*			myListener.on23 = function() {	
+*				mySuperShape.callback = "on34";
+*				mySuperShape.addPreset({label:"3", data:{m:10, n1:.2, n2:1.3, n3:8, range:2, scaling:2, detail:1000}});
+*				mySuperShape.morph("2","3");
+*			}
+*			myListener.on34 = function() {	
+*				mySuperShape.callback = "on45";
+*				mySuperShape.addPreset({label:"4", data:{m:10, n1:1.1, n2:0.5, n3:8, range:2, scaling:2, detail:1000}});
+*				mySuperShape.morph("3","4");
+*			}
+*			myListener.on45 = function() {	
+*				mySuperShape.callback = "on56";
+*				mySuperShape.addPreset({label:"5", data:{m:10, n1:0.5, n2:0.1, n3:16.4, range:2, scaling:2, detail:1000}});
+*				mySuperShape.morph("4","5");
+*			}
+*			myListener.on56 = function() {		
+*				mySuperShape.callback = "on67";
+*				mySuperShape.addPreset({label:"6", data:{m:10, n1:0.5, n2:0.1, n3:1, range:2, scaling:2, detail:1000}});
+*				mySuperShape.morph("5","6");
+*			}
+*			myListener.on67 = function() {
+*				mySuperShape.callback = null;
+*				mySuperShape.addPreset({label:"7", data:{m:10, n1:0.5, n2:0.1, n3:.1, range:2, scaling:2, detail:2000}});
+*				mySuperShape.morph("6","7");
+*			}
+* 			</pre></blockquote>
+* 			Reader Exercise: Do some shape manipulations via the gradientStyle method.
+* @usage  <pre>var mySuperShape:SuperShape = SuperShape();</pre>
+* 		<pre>var mySuperShape:SuperShape = SuperShape(x, y, m, n1, n2, n3, range, scaling, detail);</pre>
+* 		<pre>var mySuperShape:SuperShape = SuperShape(mc, x, y, m, n1, n2, n3, range, scaling, detail);</pre>
+* @param mc (MovieClip) existing movieclip to draw in.
+* @param x (Number) X position of the drawing. Center point.
+* @param y (Number) Y position of the drawing. Center point.
+* @param m (Number) 0 - 20. Defaults to 4.
+* @param n1 (Number) 0 - 10000. Defaults to 1.
+* @param n2 (Number) 0 - 10000. Defaults to 1.
+* @param n3 (Number) 0 - 10000. Defaults to 1.
+* @param range (Number) 0.5 - 20*PI. Defaults to 12.
+* @param scaling (Number) 1 - 5. Defaults to 200.
+* @param detail (Number) 1000 - 50000. Defaults to 10000.
+*/
+class de.alex_uhlmann.animationpackage.drawing.SuperShape 
+											extends Shape 
+											implements ISingleAnimatable, 
+														IMultiAnimatable {
+
+	/*static default properties*/
+	/*lineStyle properties inherited from Shape*/
+	/*fillStyle properties inherited from Shape*/
+	/**
+	* @property m_def (Number)(static) default property. Defaults to 4.
+	* @property n1_def (Number)(static) default property. Defaults to 1.
+	* @property n2_def (Number)(static) default property. Defaults to 1.
+	* @property n3_def (Number)(static) default property. Defaults to 1.
+	* @property range_def (Number)(static) default property. Defaults to 12.
+	* @property scaling_def (Number)(static) default property. Defaults to 200.
+	* @property detail_def (Number)(static) default property. Defaults to 10000.
+	*
+	* @property m (Number) Property of Superformula.
+	* @property n1 (Number) Property of Superformula.
+	* @property n2 (Number) Property of Superformula.
+	* @property n3 (Number) Property of Superformula.
+	* @property range (Number) Property of Superformula.
+	* @property scaling (Number) Property of Superformula.
+	* @property detail (Number) Property of Superformula.
+	* @property animateFromCenter (Boolean) Causes the shape to be animated from the center. Default is set to false.
+	*
+	* @property movieclip (MovieClip)(read only) Movieclip that contains the drawing.
+	* @property lineThickness (Number) Outline thickness.
+	* @property lineRGB (Number) Outline color of the drawing as hex number.
+	* @property lineAlpha (Number) Outline transparency (alpha).
+	* @property fillRGB (Number) Fill color of the drawing.
+	* @property fillAlpha (Number) Fill transparency.
+	*/
+	public static var m_def:Number = 4;
+	public static var n1_def:Number = 1;
+	public static var n2_def:Number = 1;
+	public static var n3_def:Number = 1;
+	public static var range_def:Number = 12;
+	public static var scaling_def:Number = 200;
+	public static var detail_def:Number = 10000;
+	private var x:Number = 0;
+	private var y:Number = 0;
+	private var m_m:Number;
+	private var m_n1:Number;
+	private var m_n2:Number;
+	private var m_n3:Number;
+	private var m_range:Number;
+	private var m_scaling:Number;
+	private var m_detail:Number;
+	private var presets:Object;
+	private var forward:Boolean = true;
+	private var redrawBool:Boolean = true;
+	private var counter:Number;
+	private var counterMax:Number;
+	private var multipleValues:Boolean = false;
+	/* if true, shape gets drawn from the center.*/
+	private var m_animateFromCenter:Boolean = false;
+	/*points already calculated by getPointsOnCurve*/
+	private var calculatedPoints:Array;
+
+	public function SuperShape() {
+		super();
+		this.init.apply(this,arguments);
+		this.fillStyle(null);
+	}
+
+	private function init():Void {
+		if(typeof(arguments[0]) == "movieclip") {
+			this.initCustom.apply(this,arguments);
+		} else {
+			this.initAuto.apply(this,arguments);
+		}
+	}
+
+	private function initCustom(mc:MovieClip, x:Number, y:Number,
+						m:Number, n1:Number, n2:Number, n3:Number,
+						range:Number, scaling:Number, detail:Number):Void {
+
+		this.mc = this.createClip({mc:mc, x:x, y:y});
+		this.initShape.apply(this,arguments.slice(1));
+	}
+
+	private function initAuto( x:Number, y:Number,
+						m:Number, n1:Number, n2:Number, n3:Number,
+						range:Number, scaling:Number, detail:Number):Void {
+
+		this.mc = this.createClip({name:"apDraw", x:x, y:y});
+		this.initShape.apply(this,arguments);
+	}
+
+	private function initShape( x:Number, y:Number,
+						m:Number, n1:Number, n2:Number, n3:Number,
+						range:Number, scaling:Number, detail:Number):Void {
+
+		this.initPresets();
+		this.initParams.apply(this,arguments.slice(2));
+	}
+
+	private function initPresets(Void):Void {
+		this.presets = new Object();
+		this.addPreset({label:"circle", data:{m:0, n1:1, n2:1, n3:1, range:2, scaling:2, detail:1000}});
+		this.addPreset({label:"square", data:{m:4, n1:1, n2:1, n3:1, range:2, scaling:2, detail:1000}});
+		this.addPreset({label:"triangle", data:{m:3, n1:1, n2:1, n3:1, range:2, scaling:2, detail:1000}});
+		this.addPreset({label:"burst", data:{m:5, n1:1, n2:1, n3:1, range:2, scaling:2, detail:1000}});
+		this.addPreset({label:"radioactive", data:{m:3, n1:10000, n2:9999, n3:9999, range:2, scaling:2, detail:1000}});
+		this.addPreset({label:"windmill", data:{m:15, n1:10000, n2:9000, n3:9000, range:2, scaling:2, detail:1000}});
+		this.addPreset({label:"drop", data:{m:1 / 6, n1:.3, n2:.3, n3:.3, range:12, scaling:2, detail:1000}});
+		this.addPreset({label:"star3peaks", data:{m:3, n1:.3, n2:.3, n3:.3, range:12, scaling:2, detail:1000}});
+		this.addPreset({label:"star4peaks", data:{m:4, n1:.3, n2:.3, n3:.3, range:12, scaling:2, detail:1000}});
+		this.addPreset({label:"star5peaks", data:{m:5, n1:.3, n2:.3, n3:.3, range:12, scaling:2, detail:1000}});
+	}
+
+	private function initParams(m:Number, n1:Number, n2:Number, n3:Number,
+					range:Number, scaling:Number, detail:Number):Void {
+
+		this.m_m = (m == null) ? SuperShape.m_def : m;
+		this.m_n1 = (n1 == null) ?SuperShape.n1_def : n1;
+		this.m_n2 = (n2 == null) ? SuperShape.n2_def : n2;
+		this.m_n3 = (n3 == null) ? SuperShape.n3_def : n3;
+		this.m_range = (range == null) ? SuperShape.range_def : range;
+		this.m_scaling = (scaling == null) ? SuperShape.scaling_def : scaling *= 100;
+		this.m_detail = (detail == null) ? SuperShape.detail_def : detail;
+	}
+	
+	/**
+	* @method draw
+	* @description 	Draws supershape.
+	* @usage <pre>mySuperShape.draw();</pre>
+	* 		<pre>mySuperShape.draw(start, end);</pre>
+	* @param start (Number) optional. value to beginn the drawing.
+	* @param end (Number) optional. value to end the drawing.
+	*/
+	public function draw(Void):Void {
+		var start:Number = arguments[0];
+		var end:Number = arguments[1];
+		this.redrawBool = false;
+		if(start == null && end == null) {
+			start = 0;
+			end = 100;
+		}
+		var endDetail:Number = end / 100 * this.m_detail;
+		if(start > end) {
+			this.forward = false;
+		} else {
+			this.forward = true;
+		}
+		this.drawNewShape(endDetail);
+	}
+
+	/*
+	* redraws the shape in each iteration like every animated shape in AnimationPackage.
+	* Bounce, Elastic and Back Easing is possible. Due to the complex operations for the superformula
+	* this can be very slow.
+	*/
+	/**
+	* @method animate
+	* @description 	Draws an animated supershape.
+	*			<p>
+	* 			Example 1: <a href="SuperShape_animate_01.html">(Example .swf)</a> draw a circle backwards with default parameters.
+	*			<blockquote><pre>
+	* 			var mySuperShape:SuperShape = new SuperShape(275,200);
+	*			mySuperShape.setPreset("circle");
+	* 			mySuperShape.fillStyle(0xff0000);	
+	*			mySuperShape.animate(100,0);
+	*			</pre></blockquote>
+	* 			Example 2: <a href="SuperShape_animate_02.html">(Example .swf)</a> draw a more complex star with custom parameters.
+	*			<blockquote><pre>
+	* 			var mySuperShape:SuperShape = new SuperShape(200, 200, 19/6, .3, .3, .3, 12, 2, 5000);
+	*			mySuperShape.fillStyle();
+	*			mySuperShape.animationStyle(10000);
+	*			mySuperShape.animate(0,100);
+	*			</pre></blockquote>
+	*
+	* @usage  <pre>mySuperShape.animate(start, end);</pre>
+	* @param start (Number) Value to beginn the drawing.
+	* @param end (Number) Value to end the drawing.
+	*/
+	public function animate(start:Number, end:Number):Void {
+		this.redrawBool = true;
+		this.invokeAnimation(start, end);
+	}	
+	
+	/**
+	* @method animateProps
+	* @description 	Animates a property or properies specified as a String in propArr to the specified number value or values in endArr.
+	* 				<p>
+	* 				Example 1: <a href="SuperShape_animateProps_01.html">(Example .swf)</a> manipulate the border of a circle.
+	* 				<blockquote><pre>
+	* 				var mySuperShape:SuperShape = new SuperShape(275,200);
+	*				mySuperShape.lineStyle(6);
+	*				mySuperShape.fillStyle(0xff0000);
+	*				mySuperShape.animationStyle(6000,Circ.easeOut,"onDetailOut");
+	*				mySuperShape.setPreset("circle");
+	*				mySuperShape.animateProps(["detail"],[3]);
+	*				myListener.onDetailOut = function() {
+	*					mySuperShape.animationStyle(6000,Circ.easeIn,null);
+	*					mySuperShape.animateProps(["detail"],[1000]);
+	*				}
+	* 				</pre></blockquote><p>
+	* 				See class documentation for another example.
+	* @usage <pre>mySuperShape.animateProps(propArr, endArr);</pre>
+	* @param propArr (Array) Array of Strings. See class properties for available properties.
+	* @param endArr (Array) Array of Numbers.
+	*/
+	public function animateProps(propArr:Array, endArr:Array):Void {
+		this.myAnimator = new Animator();
+		this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+		this.myAnimator.caller = this;
+		var startArr:Array = new Array();
+		var setterArr:Array = new Array();
+		var i:Number = propArr.length;
+		while(--i>-1) {
+			startArr.push(this["m_"+propArr[i]]);
+			setterArr.push(new Array(this,"a_"+propArr[i]));
+		}
+		this.counter = 0;
+		this.counterMax = startArr.length;
+		if(this.counterMax > 1) {
+			this.multipleValues = true;
+			this.startValues = startArr;
+			this.endValues = endArr;
+		} else {
+			this.multipleValues = false;
+			this.startValue = startArr[0];
+			this.endValue = endArr[0];
+		}
+		this.myAnimator.start = startArr;
+		this.myAnimator.end = endArr;
+		this.myAnimator.setter = setterArr;
+		this.myAnimator.run();
+	}
+
+	private function a_m(v:Number):Void {
+		this.m_m = v;
+		this.collect();
+	}
+	private function a_n1(v:Number):Void {
+		this.m_n1 = v;
+		this.collect();
+	}
+	private function a_n2(v:Number):Void {
+		this.m_n2 = v;
+		this.collect();
+	}
+	private function a_n3(v:Number):Void {
+		this.m_n3 = v;
+		this.collect();
+	}
+	private function a_range(v:Number):Void {
+		this.m_range = v;
+		this.collect();
+	}
+	private function a_scaling(v:Number):Void {
+		this.m_scaling = v;
+		this.collect();
+	}
+	private function a_detail(v:Number):Void {
+		this.m_detail = v;
+		this.collect();
+	}
+
+	private function collect(Void):Void {
+		this.counter++;
+		if(this.counter == this.counterMax) {
+			this.counter = 0;			
+			this.drawNewShape(this.m_detail);
+		}
+	}	
+
+	/**
+	* @method morph
+	* @description 	Morphs a shape from a specified preset to another.
+	* 				To read about presets, take a look at addPreset() and setPreset().
+	* 				See class documentation for an example.
+	* @usage <pre>mySuperShape.morph(presetStart, presetEnd);</pre>
+	* @param presetStart (String) preset label to start mophing.
+	* @param presetEnd (String) preset label to moph to.
+	*/
+	public function morph(presetStart:String, presetEnd:String):Void {
+		var p1:Object = this.presets[presetStart];
+		var p2:Object = this.presets[presetEnd];
+		this.initParams(p1.m, p1.n1, p1.n2, p1.n3, p1.range, p1.scaling, p1.detail);
+		this.myAnimator = new Animator();
+		this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+		this.myAnimator.caller = this;
+		var startArr:Array = new Array();
+		var endArr:Array = new Array();
+		var setterArr:Array = new Array();
+		/*determine difference between preset shapes and animate with Animator.*/
+		if(p1.m != p2.m) {
+			startArr.push(p1.m);
+			endArr.push(p2.m);
+			setterArr.push(new Array(this,"a_m"));
+		}
+		if(p1.n1 != p2.n1) {
+			startArr.push(p1.n1);
+			endArr.push(p2.n1);
+			setterArr.push(new Array(this,"a_n1"));
+		}
+		if(p1.n2 != p2.n2) {
+			startArr.push(p1.n2);
+			endArr.push(p2.n2);
+			setterArr.push(new Array(this,"a_n2"));
+		}
+		if(p1.n3 != p2.n3) {
+			startArr.push(p1.n3);
+			endArr.push(p2.n3);
+			setterArr.push(new Array(this,"a_n3"));
+		}
+		if(p1.range != p2.range) {
+			startArr.push(p1.range);
+			endArr.push(p2.range);
+			setterArr.push([this,"a_range"]);
+		}
+		if(p1.scaling != p2.scaling) {
+			startArr.push(p1.scaling);
+			endArr.push(p2.scaling);
+			setterArr.push([this,"a_scaling"]);
+		}
+		if(p1.detail != p2.detail) {
+			startArr.push(p1.detail);
+			endArr.push(p2.detail);
+			setterArr.push([this,"a_detail"]);
+		}
+		this.counter = 0;
+		this.counterMax = startArr.length;
+		if(this.counterMax > 1) {
+			this.multipleValues = true;
+			this.startValues = startArr;
+			this.endValues = endArr;
+		} else {
+			this.multipleValues = false;
+			this.startValue = startArr[0];
+			this.endValue = endArr[0];
+		}
+		this.myAnimator.start = startArr;
+		this.myAnimator.end = endArr;
+		this.myAnimator.setter = setterArr;
+		this.myAnimator.run();
+	}
+
+	/**
+	* @method addPreset
+	* @description 	Adds a new preset object to SuperShape. Overwrites an existing preset with the same label.
+	*			A preset is an object that contains parameters that represent a shape.
+	*			<p>
+	* 			Example 1: <a href="SuperShape_addPreset_01.html">(Example .swf)</a> Add the the german military logo as a preset
+	* 			and draw it with default parameters.
+	*			<blockquote><pre>
+	* 			var mySuperShape:SuperShape = new SuperShape(275,200);
+	*			mySuperShape.addPreset({label:"Bundeswehr", data:{m:4, n1:10000, n2:8000, n3:8000, range:2, scaling:2, detail:1000}});
+	*			mySuperShape.setPreset("Bundeswehr");
+	*			mySuperShape.draw();
+	*			</pre></blockquote>
+	*
+	* @usage  <pre>mySuperShape.addPreset(item);</pre>
+	* @param item (Object) the object that defines the preset. Like an item of the Macromedia DataProvider, item needs to have another label and data object inside.
+	*/
+	public function addPreset(item:Object):Void {
+		if(this.presets[item.label] != null) {
+			trace("Preset "+this.presets[item.label]+" overwritten!");
+		}
+		this.presets[item.label] = item.data;
+	}
+
+	/**
+	* @method getPreset
+	* @description 	Returns the preset object.
+	* 			A preset is an object that contains parameters that represent a shape.
+	* 			If you specify the label of an available preset as a parameter, only
+	* 			the chosen preset is return. If you don't send a parameter,
+	* 			all presets will be returned.
+	* @usage  <pre>mySuperShape.getPreset();</pre>
+	* 		<pre>mySuperShape.getPreset(preset);</pre>
+	* @param preset (String) the label of an available preset.
+	* @return Object that contains the preset.
+	*/
+	public function getPreset(preset:String):Object {
+		if(preset != null) {
+			return this.presets[preset];
+		}
+		return this.presets;
+	}
+
+	/**
+	* @method setPreset
+	* @description 	Sets the preset object.
+	*			A preset is an object that contains parameters that represent a shape. There are predefined presets available.
+	* 			You can add further presets with addPreset().
+	*			<p>
+	* 			Example 1: <a href="SuperShape_setPreset_01.html">(Example .swf)</a> draw a circle with default parameters.
+	*			<blockquote><pre>
+	* 			var mySuperShape:SuperShape = new SuperShape(275,200);
+	*			mySuperShape.setPreset("circle");
+	*			mySuperShape.draw();
+	*			</pre></blockquote>
+	* 			Example 2: <a href="SuperShape_setPreset_02.html">(Example .swf)</a> draw an animated square with custom parameters.
+	*			<blockquote><pre>
+	* 			var mySuperShape:SuperShape = new SuperShape(275,200);
+	* 			mySuperShape.lineStyle(0);
+	*			mySuperShape.fillStyle(0xff0000);
+	*			mySuperShape.animationStyle(10000,Sine.easeOut);
+	*			mySuperShape.setPreset("square");
+	*			mySuperShape.animate(0,100);
+	*			</pre></blockquote>
+	*
+	* @usage  <pre>mySuperShape.setPreset(preset);</pre>
+	* @param preset (String) the label of an available preset.
+	*/
+	public function setPreset(preset:String):Void {
+		var p:Object = this.presets[preset];
+		this.initParams(p.m, p.n1, p.n2, p.n3, p.range, p.scaling, p.detail);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {
+		this.startInitialized = false;
+		
+		this.calculatedPoints = new Array();
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		var startDetail:Number = 0;
+		this.myAnimator.start = [startDetail];
+		this.setStartValue(startDetail);
+		this.multipleValues = false;
+		var endDetail:Number = this.m_detail;
+		if(start > end) {
+			this.forward = false;
+		} else {
+			this.forward = true;
+		}
+		this.myAnimator.end = [endDetail];
+		this.setEndValue(endDetail);
+		this.myAnimator.setter = [[this,"drawNewShape"]];
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+	
+	private function drawNewShape(s:Number):Void {
+		this.clearDrawing();
+		if (this.fillRGB != null && this.fillGradient == false) {
+			this.mc.beginFill(this.fillRGB, this.fillAlpha);
+		} else if (this.fillGradient == true){
+			this.mc.beginGradientFill(this.gradientFillType, this.gradientColors, this.gradientAlphas, this.gradientRatios, this.gradientMatrix);
+		}
+		this.drawShape(s);
+		this.mc.endFill();
+	}
+	
+	/* Optimized, less readable code.*/
+	private function drawShape(s:Number):Void {
+		var mc:MovieClip = this.mc;
+		var m:Number = this.m_m;
+		var n1:Number = this.m_n1;
+		var n2:Number = this.m_n2;
+		var n3:Number = this.m_n3;
+		var ra:Number = this.m_range;
+		var sc:Number = this.m_scaling;
+		var d:Number = this.m_detail;
+		if(s == null) {
+			s = d;
+		}
+		var phi:Number;
+		var pi:Number = Math.PI;
+		/*
+		* getPoint() variables. To improve performance, 
+		* the implementation of getPoint() is also included in drawShape, 
+		* saving another function call in loops.
+		*/
+		var r:Number;
+		var x:Number, y:Number;
+		var cos:Function = Math.cos;
+		var sin:Function = Math.sin;
+		var pow:Function = Math.pow;
+		var abs:Function = Math.abs;		
+		var p:Number;
+		var q:Object;
+		//cache
+		var calc:Array = this.calculatedPoints;
+		/*calculate starting point if not animated from center*/				
+		if(this.animateFromCenter == false) {			
+			var pos1:Object = this.getPoint(m, n1, n2, n3, 0);
+			mc.moveTo(pos1.x * sc, pos1.y * sc);
+		}
+		var i:Number;
+		if(this.forward) {
+			for(i = 0; i <= s; i++) {
+				if(calc[i] == null) {
+					phi = ra * pi * (i / d);				
+					p = m * phi / 4;		
+					r = pow(pow(abs(cos(p) / 1), n2) -(-pow(abs(sin(p) / 1), n3)), 1 / n1);
+					if (r == 0) {
+						x = y = 0;
+					}
+					else {
+						r = 1 / r;
+						x = r * cos(phi) * sc;
+						y = r * sin(phi) * sc;
+					}
+					q = calc[i] = {x:x, y:y};
+				} else {
+					q = calc[i];
+				}
+				mc.lineTo(q.x, q.y);
+			}
+		} else {
+			i = s;
+			while(--i>-1) {
+				if(calc[i] == null) {
+					phi = ra * pi * (i / d);				
+					p = m * phi / 4;		
+					r = pow(pow(abs(cos(p) / 1), n2) -(-pow(abs(sin(p) / 1), n3)), 1 / n1);
+					if (r == 0) {
+						x = y = 0;			
+					}
+					else {
+						r = 1 / r;
+						x = r * cos(phi) * sc;
+						y = r * sin(phi) * sc;
+					}
+					q = calc[i] = {x:x, y:y};
+				} else {
+					q = calc[i];
+				}		
+				mc.lineTo(q.x, q.y);
+			}
+		}	
+	}
+	
+	/* Optimized, less readable code.*/
+	private function getPoint(m:Number, n1:Number, n2:Number, n3:Number, phi:Number):Object {		
+		var r:Number;		
+		var x:Number, y:Number;
+		var cos:Function = Math.cos;
+		var sin:Function = Math.sin;
+		var pow:Function = Math.pow;
+		var abs:Function = Math.abs;		
+		var p:Number;
+		p = m * phi / 4;		
+		r = pow(pow(abs(cos(p) / 1), n2) -(-pow(abs(sin(p) / 1), n3)), 1 / n1);
+		if (r == 0) {
+			x = y = 0;			
+		}
+		else {
+			r = 1 / r;
+			x = r * cos(phi);
+			y = r * sin(phi);
+		}		
+		return {x:x, y:y};
+	}
+	
+	/*getter / setter*/
+	public function get m():Number {
+		return this.m_m;
+	}
+
+	public function set m(m:Number):Void {
+		this.m_m = m;
+	}
+
+	public function get n1():Number {
+		return this.m_n1;
+	}
+
+	public function set n1(n1:Number):Void {
+		this.m_n1 = n1;
+	}
+
+	public function get n2():Number {
+		return this.m_n2;
+	}
+
+	public function set n2(n2:Number):Void {
+		this.m_n2 = n2;
+	}
+
+	public function get n3():Number {
+		return this.m_n3;
+	}
+
+	public function set n3(n3:Number):Void {
+		this.m_n3 = n3;
+	}
+
+	public function get range():Number {
+		return this.m_range;
+	}
+
+	public function set range(range:Number):Void {
+		this.m_range = range;
+	}
+
+	public function get scaling():Number {
+		return this.m_scaling;
+	}
+
+	public function set scaling(scaling:Number):Void {
+		this.m_scaling = scaling;
+	}
+
+	public function get detail():Number {
+		return this.m_detail;
+	}
+
+	public function set detail(detail:Number):Void {
+		this.m_detail = detail;
+	}	
+	
+	public function get animateFromCenter():Boolean {
+		return this.m_animateFromCenter;
+	}
+
+	public function set animateFromCenter(bool:Boolean):Void {
+		this.m_animateFromCenter = bool;
+	}	
+	
+	public function getStartValue(Void):Number {		
+		return 0;
+	}
+	
+	public function getEndValue(Void):Number {		
+		return 100;
+	}
+	
+	public function getCurrentValue(Void):Number {
+		var start:Number;
+		var end:Number;
+		var current:Number;		
+		var multipleValues:Boolean;
+		
+		if(this.multipleValues) {
+			start = this.startValues[0];
+			end = this.endValues[0];
+			current = this.currentValues[0];
+		} else {
+			start = this.startValue;
+			end = this.endValue;
+			current = this.currentValue;
+		}
+		if(start < end) {				
+			return (current - start) / (end - start) * 100;
+		} else {
+			return 100 - ((current - end) / (start - end) * 100);
+		}
+	}	
+	
+	/*inherited from Shape*/
+	/**
+	* @method lineStyle
+	* @description 	define outline.
+	*
+	* @usage   <pre>mySuperShape.lineStyle();</pre>
+	* 		<pre>mySuperShape.lineStyle(lineThickness, lineRGB, lineAlpha);</pre>
+	*
+	* @param lineThickness (Number) Outline thickness.
+	* @param lineRGB (Number) Outline color of the drawing as hex number.
+	* @param lineAlpha (Number) Outline transparency (alpha).
+	*/
+
+	/*inherited from Shape*/
+	/**
+	* @method fillStyle
+	* @description 	define fill.
+	*
+	* @usage   <pre>mySuperShape.fillStyle();</pre>
+	* 		<pre>mySuperShape.fillStyle(fillRGB, fillAlpha);</pre>
+	*
+	* @param fillRGB (Number) Fill color of the drawing.
+	* @param fillAlpha (Number) Fill transparency.
+	*/
+	
+	/**
+	* @method gradientStyle
+	* @description	 Same interface as MovieClip.beginGradientFill(). See manual.
+	* 		
+	* @usage   <pre>mySuperShape.gradientStyle(fillType, colors, alphas, ratios, matrix);</pre>
+	* 	  
+	* @param fillType (String)  Gradient property. See MovieClip.beginGradientFill().
+	* @param colors (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param alphas (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param ratios (Array)  Gradient property. See MovieClip.beginGradientFill().
+	* @param matrix (Object)  Gradient property. See MovieClip.beginGradientFill().
+	*/
+
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 
+	* @usage   <pre>mySuperShape.animationStyle(duration);</pre>
+	* 		<pre>mySuperShape.animationStyle(duration, callback);</pre>
+	* 		<pre>mySuperShape.animationStyle(duration, easing, callback);</pre>
+	*
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method clear
+	* @description 	removes all drawings. Identical to myInstance.movieclip.clear();
+	* @usage <pre>myInstance.clear();</pre>
+	*/	
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/	
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. Percentage. 
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. Percentage.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	*
+	* @usage   <pre>mySuperShape.addEventListener(event, listener);</pre>
+	* 		    <pre>mySuperShape.addEventListener(event, listener, handler);</pre>
+	*
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed.
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.
+	*
+	* @usage   <pre>mySuperShape.removeEventListener(event, listener);</pre>
+	* 		    <pre>mySuperShape.removeEventListener(event, listener, handler);</pre>
+	*
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	*
+	* @usage   <pre>mySuperShape.removeAllEventListeners();</pre>
+	* 		    <pre>mySuperShape.removeAllEventListeners(event);</pre>
+	*
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	*
+	* @usage   <pre>mySuperShape.eventListenerExists(event, listener);</pre>
+	* 			<pre>mySuperShape.eventListenerExists(event, listener, handler);</pre>
+	*
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.
+	*@returns <code>true</code> if event exists on listener.
+	*                  <code>false</code> if event doesn't exist on listener.
+	*/
+
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "SuperShape";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/drawing/SuperShape.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Animator.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Animator.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Animator.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,1120 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.IAnimatable;
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.IMultiAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.TweenAction;
+import de.alex_uhlmann.animationpackage.utility.Tween;
+import de.alex_uhlmann.animationpackage.utility.TimeTween;
+import de.alex_uhlmann.animationpackage.utility.FrameTween;
+import de.andre_michelle.events.FrameBasedInterval;
+
+/**
+* @class Animator
+* @author Alex Uhlmann
+* @description  Animator combines user defined property(ies) or method(s), tween-engines and 
+* 			AnimationPackage. It allows to create custom animations easily.
+* 			Animator is used by most classes in AnimationPackage that use animations.
+* 			The tween engine used is either de.alex_uhlmann.animationpackage.utility.TimeTween or de.alex_uhlmann.animationpackage.utility.FrameTween 
+* 			based on Andre Michelle's FrameBasedInterval and ImpulsDispatcher.	 
+* 			Animator can handle single and multiple properties and single and multiple methods.
+* 			<p>
+* 			Example 1: To emulate the ColorBrightness class. 		
+* 			<blockquote><pre>
+*			var myAnimator:Animator = new Animator();
+*			myAnimator.animationStyle(5000, Elastic.easeOut, "onCallback");
+*			var myColorFX:ColorFX = new ColorFX(mc);
+*			myAnimator.caller = this;
+*			myAnimator.start = [myColorFX.getBrightness()];
+*			myAnimator.end = [50];
+*			myAnimator.setter = [[myColorFX,"setBrightness"]];
+*			myAnimator.run();	
+*			</pre></blockquote>
+* 			Take a look at some other classes of AnimationPackage, most of them use 
+* 			Animator internally. ColorTransform and ColorDodge i.e.<p>
+* 			Animator also might come in handy to animate different properties of shapes 
+* 			offered by the drawing package. Take a look at the 
+* 			Rectangle class documentation for an example. 
+* 			<p>	
+* 			Example 1: <a href="Animator_01.html">(Example .swf)</a> If the start and end arrays 
+* 			are longer than the setter array than Animator figures that you want all the properties 
+* 			send to one function. Do crazy shape manipulations.
+* 			<blockquote><pre>
+*			var myStar:Star = new Star(330,200,50,60,6)
+*			myStar.lineStyle();
+*			myStar.fillStyle(0x9C3031);
+*			myStar.draw();
+*			
+*			var myAnimator:Animator = new Animator();
+*			myAnimator.animationStyle(5000,Circ.easeInOut);
+*			myAnimator.start = [50,60];
+*			myAnimator.end = [0,200];
+*			//Try this one for yourself. A negative innerRadius parameter results in more complex star. 
+*			//This Bug of the Star class is actually a feature and will not be fixed. ( ;
+*			//myAnimator.end = [-125,200];
+*			myAnimator.setter = [[this,"morph"]];
+*			myAnimator.run();
+*			
+*			function morph(innerRadius:Number,outerRadius:Number) {
+*				myStar.setInnerRadius(innerRadius);
+*				myStar.setOuterRadius(outerRadius);	
+*				myStar.draw();
+*			}	
+*			</pre></blockquote>
+* 			<p>
+* 			Example 1: <a href="Animator_02.html">(Example .swf)</a> This examples illustrates how 
+* 			you can animate more complex drawing created with the Drawer class. If you create a 
+* 			more imaginary drawing, which might even make some sense, please let me know. 
+* 			I would be happy to replace it with my ugly one here. ( ;
+* 			<blockquote><pre>
+*			var myCubicCurve:CubicCurve = new CubicCurve(0,0,60,100,260,80,320,0);
+*			var myLine:Line = new Line(320,0,0,0);
+*			
+*			var myDraw_mc:MovieClip = this.createEmptyMovieClip("draw_mc",999);
+*			var myDrawer:Drawer = new Drawer(myDraw_mc);
+*			myDrawer.addChild(myLine);
+*			myDrawer.addChild(myCubicCurve);
+*			myDrawer.drawBy();
+*			myDrawer.fillStyle(0xff0000);
+*			myDrawer.fill();
+*			
+*			var myAnimator:Animator = new Animator();
+*			myAnimator.animationStyle(4000,Elastic.easeInOut);
+*			myAnimator.start = [100,260,80];
+*			myAnimator.end = [310,450,150];
+*			myAnimator.setter = [[this,"morph"]];
+*			myAnimator.run();
+*			
+*			function morph(y2:Number,x3:Number,y3:Number) {
+*				myCubicCurve.setY2(y2);
+*				myCubicCurve.setX3(x3);
+*				myCubicCurve.setY3(y3);
+*				myDrawer.clear();
+*				myDrawer.drawBy();
+*				myDrawer.fill();
+*			}
+*			</pre></blockquote>
+* 			<p>
+* 			Under the hood, to assign values to method(s) and/or property(ies), Animator 
+* 			uses the optimized TweenAction class.
+* 
+* @usage <tt>var myAnimator:Animator = new Animator();</tt> 
+*/
+class de.alex_uhlmann.animationpackage.utility.Animator 
+											extends AnimationCore 
+											implements ISingleAnimatable, 
+													IMultiAnimatable {		
+	
+	/** 
+	* @property caller (Object) Object that calls the Animator. 
+	* 					Used in first return value of callback.
+	* @property start (Array) Array of value or values to start animation with.
+	* @property end (Array) Targeted amount or amounts to animate to.
+	* @property setter (Array) 2 dimensional array. First dimension holds an object as the first element and the corresponding function or property as the second element as a String. See run().
+	* @property multiStart (Array) Same API as start. When multiple animation targets (i.e. movieclips) are animated, multiStart makes sure different start values are considered. It replaces start. See other IAnimatable classes for examples on implementation. i.e. the Move class.
+	* @property multiSetter (Array) Same API as setter. When multiple animation targets (i.e. movieclips) are animated, multiSetter replaces setter. See other IAnimatable classes for examples on implementation. i.e. the Move class.
+	*
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See APCore class. 
+	*/
+	public static var animations:Object;
+	public var caller:Object;
+	public var start:Array;
+	public var end:Array;
+	public var setter:Array;
+	public var multiStart:Array;
+	public var multiSetter:Array;
+	public var myTween:Tween;
+	private var startPause:Number;
+	private var pausedTime:Number = 0;
+	private var elapsedDuration:Number = 0;
+	public var paused:Boolean = false;
+	public var stopped:Boolean = false;
+	public var finished:Boolean = false;
+	private var arrayMode:Boolean;
+	private var arrayLength:Number;
+	/*relaxed type to accommodate numbers or arrays*/
+	private var initVal;
+	private var endVal;
+	private var identifierToken:Number = 2;
+	private var startPerc:Number;
+	private var endPerc:Number;
+	private var hiddenCaller:Object;
+	private var perc:Number;	
+	
+	public function Animator() {
+		super();
+		this.animationStyle();
+	}
+	
+	/**
+	* @method run
+	* @description 	send a custom method or methods to animate in a specified time 
+	* 			and easing equation.			
+	* 			
+	* 		
+	* @usage   <pre>myAnimator.run();</pre>
+	* 		<pre>myAnimator.run(duration);</pre>
+	*		<pre>myAnimator.run(duration, callback);</pre>
+	* 		<pre>myAnimator.run(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after Animator
+	* @return void
+	*/
+	public function run():Void {
+				
+		if (arguments.length > 0) {
+			this.animationStyle(arguments[0], arguments[1], arguments[2]);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}		
+		if(this.initAnimator() == false) {
+			return;
+		}
+		this.initAnimation(0, 100);
+	}
+
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/	
+	public function animate(start:Number, end:Number):Void {
+		
+		if(this.initAnimator() == false) {
+			return;
+		}
+		
+		this.initAnimation(start, end);
+	}
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	public function goto(percentage:Number):Void {
+		
+		if(this.initAnimator() == false) {
+			return;
+		}
+		
+		//percentage = Math.round(percentage);
+		this.perc = percentage;
+		
+		/*
+		* goto would usually only dispatch onUpdate events. The 
+		* following is done to dispatch all events depending on 
+		* the state of the animation.
+		* Prevent event dispatching of TweenAction 
+		* with temporalily overwriting the caller property 
+		* with a clone object of Animator. Fetch onUpdate events 
+		* of the clone, modify them accordingly and dispatch them to the caller.
+		*/
+		this.hiddenCaller = this.caller;
+		var hiddenAnimator:Animator = this.cloneAnimator(this);
+		if(!this.caller.omitEvent) {
+			hiddenAnimator.addEventListener("onUpdate", this);
+		}
+		this.caller = hiddenAnimator;
+
+		this.initStartEndValues(percentage);		
+		var myTweenAction:TweenAction = this.initTweenAction();
+		/*this is usually done in TweenAction*/
+		if(!this.arrayMode) {
+			this.hiddenCaller.currentValue = this.initVal;
+		} else {
+			this.hiddenCaller.currentValues = this.initVal;
+		}
+			
+		myTweenAction[this.retrieveSetters().update](this.initVal);	
+		this.caller = this.hiddenCaller;
+	}
+	
+	/*
+	private function between(num:Number, min:Number, max:Number):Boolean {
+		return (num > min && num < max);
+	}
+	*/
+	
+	private function cloneAnimator(animator:Animator):Animator {
+		var cloneObj:Animator = new Animator();
+		cloneObj.omitEvent = animator.omitEvent;
+		cloneObj.caller = animator.caller;
+		cloneObj.start = animator.start;	
+		cloneObj.end = animator.end;
+		cloneObj.setter = animator.setter;
+		cloneObj.multiStart = animator.multiStart;
+		cloneObj.multiSetter = animator.multiSetter;
+		cloneObj.roundResult(animator.caller.rounded);
+		return cloneObj;
+	}	
+
+	private function onUpdate(e:Object) {		
+		e.target = this.hiddenCaller;
+		if(this.perc == 0) {
+			e.type = "onStart";
+			this.dispatch(e);
+		} else if(this.perc == 100) {
+			e.type = "onEnd";
+			this.dispatch(e);
+		} else {
+			this.dispatch(e);				
+		}	
+	}
+
+	private function dispatchOnStart() {
+		if(!this.arrayMode) {
+			this.caller.currentValue = this.initVal;
+		} else {
+			this.caller.currentValues = this.initVal;
+		}
+		
+		this.caller.dispatchEvent.apply(this.caller, [ {type:"onStart", 
+															target: this.caller, 
+															value: this.initVal} ]);													
+	}
+	
+	private function dispatch(e:Object) {		
+		this.hiddenCaller.dispatchEvent.apply(this.hiddenCaller, [ e ]);		
+	}	
+	
+	private function initAnimator(Void):Boolean {
+		
+		//initialize caller.
+		if(this.caller == null) {
+			this.caller = this;
+		}
+		
+		//check if multiple animation targets have been supplied
+		if(this.multiSetter != null) {
+			this.createMultiSetter(this.multiSetter);
+		}
+		
+		//deletion of equivalent values.
+		if(this.caller.equivalentsRemoved == true) {			
+			if(this.splitEquivalents() == "ALL") {
+				return false;
+			}
+		}
+		if(AnimationCore.equivalentsRemoved_static == true 
+						&& this.caller.equivalentsRemoved == null) {
+		
+			if(this.splitEquivalents() == "ALL") {
+				return false;
+			}
+		}
+		
+		saveAnimation();
+		
+		//initialize start/end values.
+		var len:Number = this.end.length;
+		if(this.start.length != len) {
+			return false;
+		}
+		this.startInitialized = false;
+		if(len > 1) {
+			this.arrayMode = true;
+			this.initVal = this.start;
+			this.endVal = this.end;
+			this.setStartValues(this.initVal);
+			this.setEndValues(this.endVal);
+		} else {
+			this.arrayMode = false;
+			this.initVal = this.start[0];
+			this.endVal = this.end[0];
+			this.setStartValue(this.initVal);
+			this.setEndValue(this.endVal);	
+		}
+		
+		this.arrayLength = len;
+		return true;
+	}
+	
+	private function saveAnimation(Void):Void {
+		if(AnimationCore.getOverwriteModes()) {
+			var i:Number = this.setter.length;
+			while(--i>-1) {
+				var key:String = makeKey(this.setter[i]);
+				if(key == "0")return;
+				if(Animator.animations == null) {
+					Animator.animations = new Object();
+				}
+				if(Animator.animations[key] != null) {
+					var animation:IAnimatable = Animator.animations[key];
+					animation.stop();
+				}
+				Animator.animations[key] = this.caller;
+			}
+		}
+	}
+	
+	private function makeKey(setter:Array):String {
+		var o:String;
+		if(typeof(setter[0]) == "movieclip") {
+			o = String(setter[0]);
+		} else {
+			if(this.caller.overwriteProperty == null) {
+				return "0";
+			} else {
+				o = setter[0][this.caller.overwriteProperty]; 
+			}
+		}
+		return (o + setter[1]);
+	}
+	
+	public function deleteAnimation(Void):Void {		
+		if(Animator.animations == null) {
+			return;
+		}
+		var i:Number = this.setter.length;
+		while(--i>-1) {
+			var key:String = makeKey(this.setter[i]);
+			if(key == "0")return;
+			delete Animator.animations[key];
+		}
+	}
+	
+	/*
+	* deletion of equivalent values. Returns "NONE" to indicate 
+	* that zero values have been removed. "SOME" that some have been 
+	* removed and "ALL" that all have been removed.
+	*/
+	private function splitEquivalents(Void):String {
+		/*extract values that won't animate*/
+		var len:Number = this.end.length;
+		var i:Number = len;		
+		while(--i>-1) {
+			if(this.start[i] == this.end[i]) {
+				this.start.splice(i,1);
+				this.end.splice(i,1);
+				this.setter.splice(i,1);
+			}
+		}
+		if(this.start.length == 0) {
+			this.caller["dispatchEvent"]({type:"onEnd", target:this.caller, value: null});
+			return "ALL";
+		} else if(this.end.length == len) {
+			return "NONE";
+		} else if(this.end.length < len) {
+			return "SOME";
+		}
+	}	
+
+	public function hasEquivalents(Void):Boolean {
+		var hasEquivalentsBool:Boolean;
+
+		var splitResult:String = simulateSplitEquivalents();
+		if(splitResult == "NONE") {
+			hasEquivalentsBool = false;
+		} else {
+			hasEquivalentsBool = true;
+		}
+		
+		return hasEquivalentsBool;
+	}
+	
+	private function simulateSplitEquivalents(Void):String {
+		var startLen:Number = this.start.length;
+		var endLen:Number = this.end.length;
+		var setterLen:Number = this.setter.length;
+		var len:Number = this.end.length;
+		var i:Number = len;		
+		while(--i>-1) {
+			if(this.start[i] == this.end[i]) {
+				startLen--;
+				endLen--;
+				setterLen--;
+			}
+		}
+		if(startLen == 0) {
+			return "ALL";
+		} else if(endLen == len) {
+			return "NONE";
+		} else if(endLen < len) {
+			return "SOME";
+		}
+	}
+	
+	private function initAnimation(start:Number, end:Number):Void {
+		
+		this.startPerc = start;
+		this.endPerc = end;
+		if(this.caller.getTweenMode() == AnimationCore.INTERVAL) {
+			this.invokeAnimation(start, end);
+		} else if(this.caller.getTweenMode() == AnimationCore.FRAMES) {
+			prepareForDurationMode(start, end);
+		}
+	}
+	
+	private function prepareForDurationMode(start:Number, end:Number):Void {		
+		if(this.caller.getDurationMode() == AnimationCore.MS) {
+			prepareForDurationModeMS();
+		} else if(this.caller.getDurationMode() == AnimationCore.FRAMES) {
+			prepareForDurationModeFRAMES(start, end);
+		}
+	}
+	
+	private function prepareForDurationModeMS():Void {		
+		var fps:Number = APCore.getFPS();
+		if(fps == 0) {
+			APCore.calculateFPS();
+			APCore.addListener(this);					
+		} else {
+			this.onFPSCalculated(fps);					
+		}
+	}	
+	
+	private function prepareForDurationModeFRAMES(start:Number, end:Number):Void {		
+		this.durationInFrames = this.duration;
+		this.invokeAnimation(start, end);
+	}	
+	
+	private function onFPSCalculated(fps:Number):Void {		
+		/*calculate frames with fps.*/
+		APCore.removeListener(this);
+		this.durationInFrames = APCore.milliseconds2frames(this.duration);		
+		this.invokeAnimation(this.startPerc, this.endPerc);
+	}
+
+	private function invokeAnimation(start:Number, end:Number):Void {
+			
+		this.finished = false;		
+		/*important for pause/resume/stop*/
+		if(this.caller == this) {
+			this.myAnimator = this;
+		}		
+		this.caller.tweening = true;
+		
+		this.initStartEndValues(start, end);
+		var myTweenAction:TweenAction = this.initTweenAction();
+		
+		if(this.caller.getTweenMode() == AnimationCore.INTERVAL) {
+			initializeTimeTween(myTweenAction);
+		} else if(this.caller.getTweenMode() == AnimationCore.FRAMES) {
+			initializeFrameTween(myTweenAction);
+		}
+		
+		var setterObj:Object = this.retrieveSetters();
+		
+		this.myTween.setTweenHandlers(setterObj.update, 
+								setterObj.end);
+		this.myTween.easingEquation = this.easing;
+		this.myTween.start();
+		this.dispatchOnStart();
+	}
+	
+	private function initializeTimeTween(myTweenAction:TweenAction):Void {
+		this.myTween = new TimeTween(myTweenAction, 
+								this.initVal, 
+								this.endVal, 
+								this.duration, 
+								this.caller.easingParams);	
+	}
+	
+	private function initializeFrameTween(myTweenAction:TweenAction):Void {
+		this.myTween = new FrameTween(myTweenAction, 
+								this.initVal, 
+								this.endVal, 
+								this.durationInFrames, 
+								this.caller.easingParams);
+	}	
+	
+	private function initStartEndValues(start:Number, end:Number):Void {
+
+		if(this.arrayLength > 1) {
+			
+			var startRelArr:Array = [];
+			var endRelArr:Array = [];
+			var i:Number;
+			var len:Number = this.arrayLength;
+			for(i = 0; i < len; i++) {				
+				startRelArr.push(start / 100 * (this.endValues[i] - this.startValues[i]) + this.startValues[i]);
+				endRelArr.push(end / 100 * (this.endValues[i] - this.startValues[i]) + this.startValues[i]);
+			}
+			this.initVal = startRelArr;
+			this.endVal = endRelArr;			
+
+		} else {			
+			var dif:Number = this.endValue - this.startValue;
+			var startRel:Number = start / 100 * dif + this.startValue;		
+			var endRel:Number = end / 100 * dif + this.startValue;
+			this.initVal = startRel;
+			this.endVal = endRel;
+		}
+	}
+	
+	private function initTweenAction(Void):TweenAction {
+		var scope:Object = this.setter[0][0];
+		var targetStr:String = this.setter[0][1];
+		var identifier:Function = scope[targetStr];
+		var myTweenAction:TweenAction = new TweenAction(this, 
+												this.initVal, 
+												this.endVal);
+		if(this.arrayMode == false) {
+			myTweenAction.initSingleMode(scope, targetStr, identifier);
+		} else {
+			myTweenAction.initMultiMode(this.arrayLength);
+		}
+		return myTweenAction;
+	}
+	
+	private function retrieveSetters(Void):Object {
+		
+		/* 
+		* Choose the most suitable callback method of TweenAction.
+		* Optimized, less readable code.
+		* o = onTweenUpdateOnce
+		* m = onTweenUpdateMulitple
+		* e = onTweenEnd
+		* 2 = rounds the result
+		* p = only properties
+		* m = only methods
+		* mu = multiple parameters
+		* mu2 = rounded multiple parameters
+		*/
+		/*first compute identifierTokens for another abstration*/
+		this.computeSetters();
+		
+		var setterObj:Object = new Object();
+		
+		if(this.arrayMode == false) {			
+			if(!this.caller.rounded) {
+				if(this.identifierToken == 0) {
+					setterObj.update = "op";
+				} else if(this.identifierToken == 1) {
+					setterObj.update = "om";
+				} else {
+					setterObj.update = "o";
+				}
+			} else {
+				if(this.identifierToken == 0) {
+					setterObj.update = "o2p";
+				} else if(this.identifierToken == 1) {
+					setterObj.update = "o2m";
+				} else {
+					setterObj.update = "o2";
+				}
+			}			
+		} else {
+			if(!this.caller.rounded) {				
+				if(this.identifierToken == 0) {
+					setterObj.update = "mp";
+				} else if(this.identifierToken == 1) {
+					setterObj.update = "mm";
+				} else if(this.identifierToken == 2) {
+					setterObj.update = "m";
+				} else {
+					setterObj.update = "mu";
+				}
+			} else {
+				if(this.identifierToken == 0) {
+					setterObj.update = "m2p";
+				} else if(this.identifierToken == 1) {					
+					setterObj.update = "m2m";
+				} else if(this.identifierToken == 2) {
+					setterObj.update = "m2";
+				}else {
+					setterObj.update = "mu2";
+				}
+			}
+		}
+		setterObj.end = "e";
+		return setterObj;
+	}
+	
+	private function computeSetters(Void):Void {
+		var scope:Object = this.setter[0][0];
+		var targetStr:String = this.setter[0][1];
+		var identifier:Function = scope[targetStr];
+		/*
+		* initialize TweenAction and check if either only properties, only methods or both are used. 
+		* Needed for optimisation. The corresponding callback method of TweenAction 
+		* will be chosen later in retrieveSetters.
+		*/
+		if(this.arrayMode == false) {
+			this.checkIfFunction(identifier);			
+		} else {
+			/*
+			* if there are more values to animate than setters, Animator assigns a 
+			* special callback method of TweenAction, 
+			* which sends all animated values to the first setter.
+			*/
+			if(this.setter.length < this.arrayLength) {
+				this.identifierToken = 3;
+			} else {		
+				var i:Number = this.setter.length-1;
+				var result:Boolean = this.checkIfFunction(this.setter[i][0][this.setter[i][1]]);
+				while(--i>-1) {
+					if(this.checkIfFunction(this.setter[i][0][this.setter[i][1]]) != result) {
+						this.identifierToken = 2;
+						break;
+					}
+				}
+			}	
+		}
+	}
+	
+	/*
+	* 0 = Property
+	* 1 = Method
+	* 2 = Both
+	* 3 = multiple parameters
+	*/
+	private function checkIfFunction(identifier:Function):Boolean {		
+		if(typeof(identifier) != "number") {
+			this.identifierToken = 1;
+			return true;
+		} else {
+			this.identifierToken = 0;
+			return false;
+		}
+	}	
+
+	private function createMultiSetter(setter:Array):Void {
+		/*
+		* if the multiStart property is defined, Animator fills 
+		* the start parameter with the return values of the methods or
+		* properties of the multiStart Array.
+		* This way each IAnimatable user class can present different 
+		* start values to Animator for each animation target with setting 
+		* the multiStart and multiSetter properties.
+		*/
+		var init:Boolean;
+		var startVal:Array;
+		var startValue:Number;
+		var startTargetStr:String;
+		if(this.multiStart == null) {
+			init = false;
+			startVal = this.start;
+		} else {			
+			init = true;
+		}
+		var s:Array = this.start = [];
+		var endVal:Array = this.end;
+		var endValue:Number;
+		var e:Array = this.end = [];
+		var se:Array = this.setter = [];
+		var scopes:Array;
+		var len1:Number = setter.length;	
+		var i:Number = len1;
+		while(--i>-1) {
+			if(init) {
+				startTargetStr = this.multiStart[i];
+			} else {
+				startValue = startVal[i];
+			}
+			endValue = endVal[i];
+			scopes = setter[i][0];
+			var targetStr:String = setter[i][1];
+			var len2:Number = scopes.length;	
+			var j:Number = len2;
+			while(--j>-1) {
+				var scope:Object = scopes[j];				
+				if(init) {
+					if(this.checkIfFunction(scope[startTargetStr])) {
+						s.unshift(scope[startTargetStr]());
+					} else {
+						s.unshift(scope[startTargetStr]);
+					}
+				} else {
+					s.unshift(startValue);					
+				}
+				e.unshift(endValue);
+				se.unshift([scope,targetStr]);
+			}			
+		}	
+		if(scopes.length == 0) {			
+			this.caller.setStartValue(s);
+			this.caller.setEndValue(e);
+			this.caller.setStartValues(undefined);
+			this.caller.setEndValues(undefined);
+			this.caller.setCurrentValues(undefined);
+		} else {
+			this.caller.setStartValues(s);
+			this.caller.setEndValues(e);
+			this.caller.setStartValue(undefined);
+			this.caller.setEndValue(undefined);
+			this.caller.setCurrentValue(undefined);
+		}
+	}
+	
+	public function getDurationElapsed(Void):Number {		
+		if(this.paused == true || this.stopped == true) {
+			return this.elapsedDuration;
+		} else {
+			return this.computeElapsedDuration();
+		}
+	}
+	
+	public function getDurationRemaining(Void):Number {
+		var r:Number;
+		if(this.stopped == false) {
+			if(this.caller.getTweenMode() == AnimationCore.INTERVAL) {
+				r = this.duration - this.getDurationElapsed();
+			} else if(this.caller.getTweenMode() == AnimationCore.FRAMES) {
+				if(this.caller.getDurationMode() == AnimationCore.MS) {	
+					r = this.duration - this.getDurationElapsed();
+					if(this.finished == true) {
+						r = 0;
+					}
+				} else {
+					r = this.durationInFrames - this.getDurationElapsed();
+				}
+			}
+			if(r < 0) {
+				r = 0;
+			}
+		} else {
+			r = 0;
+		}
+		if(isNaN(r)) {
+			return undefined;
+		} else {
+			return r;
+		}
+	}
+	
+	private function computeElapsedDuration(Void):Number {
+		var r:Number;
+		if(this.finished == true) {
+			r = this.duration;
+		} else {
+			if(this.caller.getTweenMode() == AnimationCore.INTERVAL) {
+				r = getTimer() - this.myTween.startTime;
+			} else if(this.caller.getTweenMode() == AnimationCore.FRAMES) {
+				if(this.caller.getDurationMode() == AnimationCore.MS) {
+					r = APCore.fps * (FrameBasedInterval.frame - this.myTween.startTime);			
+				} else {
+					r = FrameBasedInterval.frame - this.myTween.startTime;
+				}		
+			}
+		}
+		if(isNaN(r)) {
+			return undefined;
+		} else {
+			return r;
+		}
+	}
+
+	public function stopMe(Void):Void {		
+		this.elapsedDuration = this.computeElapsedDuration();
+		this.myTween.stop();
+		deleteAnimation();
+		this.stopped = true;
+	}
+	
+	public function pauseMe(Void):Void {	
+		this.elapsedDuration = this.computeElapsedDuration();
+		this.myTween.pause();
+	}
+	
+	public function resumeMe(Void):Void {		
+		this.myTween.resume();
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 		
+	* 		
+	* @usage   <pre>myAnimator.animationStyle(duration);</pre>
+	* 		<pre>myAnimator.animationStyle(duration, callback);</pre>
+	* 		<pre>myAnimator.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(event, listener);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy.
+	*                  				<code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.		
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween. 
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getStartValues
+	* @description 	returns the original, starting values of the current tween.
+	* @usage   <tt>myInstance.getStartValues();</tt>
+	* @return (Array)
+	*/
+
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween. 
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getEndValues
+	* @description 	returns the targeted values of the current tween.
+	* @usage   <tt>myInstance.getEndValues();</tt>
+	* @return (Array)
+	*/	
+	
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. 
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentValues
+	* @description 	returns the current values of the current tween.
+	* @usage   <tt>myInstance.getCurrentValues();</tt>
+	* @return (Array)
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+	
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/	
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myAnimator.addEventListener(event, listener);</pre>
+	* 		    <pre>myAnimator.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myAnimator.removeEventListener(event, listener);</pre>
+	* 		    <pre>myAnimator.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myAnimator.removeAllEventListeners();</pre>
+	* 		    <pre>myAnimator.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myAnimator.eventListenerExists(event, listener);</pre>
+	* 			<pre>myAnimator.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Animator";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Animator.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/BezierToolkit.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/BezierToolkit.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/BezierToolkit.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,122 @@
+
+/**
+* @class BezierToolkit
+* @author Alex Uhlmann
+* @description  Offers common used methods for bezier curves. 
+* 				Used by QuadCurve, CubicCurve, MoveOnQuadCurve, MoveOnCubicCurve
+* @usage <tt>var myBezierToolkit:BezierToolkit = new BezierToolkit();</tt> 
+*/
+class de.alex_uhlmann.animationpackage.utility.BezierToolkit {			
+	
+	public function BezierToolkit() {}	
+	
+	/**
+	* @method getPointsOnQuadCurve
+	* @description Returns a point on a quadratic bezier curve with Robert Penner's optimization 
+	*				of the standard equation:
+	*				{x:p1.x * (1-t) * (1-t) + 2 * p2.x * t * (1-t) + p3.x * t * t,
+	*		         y:p1.y * (1-t) * (1-t) + 2 * p2.y * t * (1-t) + p3.y * t * t }
+	* @usage   <tt>myInstance.getPointsOnQuadCurve(targ, p1, p2, p3);</tt>
+	* @param targ (Number)
+	* @param p1 (Object)
+	* @param p2 (Object)
+	* @param p3 (Object)
+	* @return Object
+	*/
+	/*Adapted from Robert Penner.*/
+	public function getPointsOnQuadCurve(t:Number, p1:Object, p2:Object, p3:Object):Object {
+		var v:Number = t / 100;
+		var p:Object = {};
+		p.x = p1.x + v*(2*(1-v)*(p2.x-p1.x) + v*(p3.x - p1.x));
+		p.y = p1.y + v*(2*(1-v)*(p2.y-p1.y) + v*(p3.y - p1.y));	
+		return p;
+	}
+	
+	/**
+	* @method getPointsOnCubicCurve
+	* @description
+	* @usage   <tt>myInstance.getPointsOnCubicCurve(targ, p1, p2, p3, p4);</tt>
+	* @param targ (Number)
+	* @param p1 (Object)
+	* @param p2 (Object)
+	* @param p3 (Object)
+	* @param p4 (Object)
+	* @return Object
+	*/	
+	/*Adapted from Paul Bourke.*/
+	public function getPointsOnCubicCurve(targ:Number, p1:Object, p2:Object, p3:Object, p4:Object):Object {
+		var a:Number,b:Number,c:Number;	
+		var v:Number = targ / 100;	
+		a = 1 - v;
+		b = a * a * a;
+		c = v * v * v;
+		var p:Object = {};
+		p.x = b * p1.x + 3 * v * a * a * p2.x + 3 * v * v * a * p3.x + c * p4.x;
+		p.y = b * p1.y + 3 * v * a * a * p2.y + 3 * v * v * a * p3.y + c * p4.y;		
+		return p;
+	}
+	
+	/**
+	* @method getQuadControlPoints
+	* @description
+	* @usage   <tt>myInstance.getQuadControlPoints(startX, startY, x2, y2, endX, endY);</tt>
+	* @param targ (Number)
+	* @param startX (Number)
+	* @param startY (Number)
+	* @param x2 (Number)
+	* @param y2 (Number)
+	* @param endX (Number)
+	* @param endY (Number)
+	* @return Object
+	*/
+	/*Adapted from Robert Penner's drawCurve3Pts() method*/
+	public function getQuadControlPoints(startX:Number, startY:Number, 
+						        x2:Number, y2:Number, 
+						        endX:Number, endY:Number):Object {
+							        
+		var c:Object = new Object();
+		c.x = (2 * x2) - .5 * (startX + endX);
+		c.y = (2 * y2) - .5 * (startY + endY);        
+		return c;
+	}	
+	
+	/**
+	* @method getCubicControlPoints
+	* @description 	if anybody finds a generic method to compute control points 
+	* 				for bezier curves with n control points, 
+	* 				if only the points on the curve are given, please let me know!
+	* @usage   <tt>myInstance.getCubicControlPoints(startX, startY, throughX1, throughY1, throughX2, throughY2, endX, endY);</tt>
+	* @param targ (Number)
+	* @param startX (Number)
+	* @param startY (Number)
+	* @param throughX1 (Number)
+	* @param throughY1 (Number)
+	* @param throughX2 (Number)
+	* @param throughY2 (Number)
+	* @param endX (Number)
+	* @param endY (Number)
+	* @return Object
+	*/	
+	public function getCubicControlPoints(startX:Number, startY:Number, 
+						        throughX1:Number, throughY1:Number, 
+							throughX2:Number, throughY2:Number, 
+						        endX:Number, endY:Number):Object {
+		
+		var c:Object = new Object();
+		c.x1 = -(10 * startX - 3 * endX - 8 * (3 * throughX1 - throughX2)) / 9;
+		c.y1 = -(10 * startY - 3 * endY - 8 * (3 * throughY1 - throughY2)) / 9;
+		c.x2 = (3 * startX - 10 * endX - 8 * throughX1 + 24 * throughX2) / 9;
+		c.y2 = (3 * startY - 10 * endY - 8 * throughY1 + 24 * throughY2) / 9;
+		return c;
+	}
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "BezierToolkit";
+	}	
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/BezierToolkit.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Clip.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Clip.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Clip.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,41 @@
+import de.alex_uhlmann.animationpackage.APCore;
+
+class de.alex_uhlmann.animationpackage.utility.Clip extends APCore {	
+	
+	public function Clip() {
+		super.init(true);
+	}
+	
+	public function attach(id:String, x:Number, y:Number, 
+						   initObj:Object):MovieClip {
+		
+		/*Flash Player 7 feature disabled*/
+		//var depth:Number = this.animationClip.getNextHighestDepth();			
+		var containerClip:MovieClip = APCore.getAnimationClip();
+		var depth:Number = this.getNextDepth(containerClip);			
+		var mc:MovieClip;
+		if(initObj == null)
+			mc = containerClip.attachMovie(id,"apAttached_mc"+depth, depth);
+		else
+			mc = containerClip.attachMovie(id,"apAttached_mc"+depth, depth, initObj);	
+		mc._x = x;
+		mc._y = y;
+		return mc;			
+	}	
+				
+	public function remove(mc:MovieClip):Void {
+		mc.removeMovieClip();	
+	}		
+		
+	public function create(name:String):MovieClip {
+		return this.createClip({name:name});		
+	}
+	
+	public function getNextDepth(mc:MovieClip):Number {
+		return super.getNextDepth(mc);
+	}	
+
+	public function toString(Void):String {
+		return "Clip";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Clip.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorCore.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorCore.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorCore.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,39 @@
+/*
+* @class ColorCore
+* @author Alex Uhlmann
+* @description  Base class of color related classes in AnimationPackage. 
+* 			(ColorFX and ColorToolkit) It offers common used methods 
+* 			and subclasses from build-in Color. Handles movieclip registration.
+*/
+class de.alex_uhlmann.animationpackage.utility.ColorCore extends Color {			
+	
+	public var movieclip:MovieClip;
+	
+	public function ColorCore(mc:MovieClip) {
+		super(mc);	
+		movieclip = mc;
+	}
+	
+	//Adapted from Colin Moock, ASDG2
+	public function hexrgb2rgb(hexrgb:Number):Object {
+		var red:Number = (hexrgb >> 16) & 0xff;
+		var green:Number = (hexrgb >> 8) & 0xff;
+		var blue:Number = hexrgb & 0xff;
+		return {r:red, g:green, b:blue};
+	}
+	
+	//Adapted from Colin Moock, ASDG2
+	public function rgb2hexrgb(r:Number, g:Number, b:Number):Number {
+		/*combine the color values into a single number.*/
+		return ((r<<16) | (g<<8) | b);		
+	}
+	
+	// reset the color object to normal
+	public function reset(Void):Void {
+		this.setTransform ({ra:100, ga:100, ba:100, rb:0, gb:0, bb:0});
+	}
+	
+	public function toString(Void):String {
+		return "ColorCore";
+	}	
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorCore.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorFX.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorFX.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorFX.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,203 @@
+import de.alex_uhlmann.animationpackage.utility.ColorCore;
+
+/**
+* @class ColorFX
+* @author Alex Uhlmann, Marcel Fahle
+* @description  Offers some color effect methods. Used by ColorNegative, ColorBrightness and 
+* 				ColorDodge classes.
+* 			<p>
+* 			Example 1: Sets the movieclip mc to a negative color value.	
+* 			<blockquote><pre>
+*			var myColorFX:ColorFX = new ColorFX(mc);
+*			myColorFX.setNegative(255);	
+*			</pre></blockquote>
+* 			<p>
+* 
+* @usage <pre>var myColorFX:ColorFX = new ColorFX(mc);</pre> 
+* @param mc (MovieClip) Movieclip to animate. 
+*/
+class de.alex_uhlmann.animationpackage.utility.ColorFX extends ColorCore {			
+	
+	public function ColorFX(mc:MovieClip) {		
+		super(mc);	
+	}
+	
+	/**
+	* @method getColorDodge
+	* @description
+	* @usage   <tt>myInstance.getColorDodge();</tt>
+	* @return Object
+	*/
+	public function getColorDodge(Void):Object {		
+		return {r:this.getRedDodge(), 
+				g:this.getGreenDodge(), 
+				b:this.getBlueDodge()};		
+	}
+	
+	/**
+	* @method setColorDodge
+	* @description
+	* @usage   <tt>myInstance.setColorDodge(rgb);</tt>
+	* @param rgb (Object)	
+	*/	
+	public function setColorDodge(rgb:Object):Void {		
+		this.setRedDodge(rgb.r);
+		this.setGreenDodge(rgb.g);
+		this.setBlueDodge(rgb.b);
+	}
+	
+	/**
+	* @method getRedDodge
+	* @description
+	* @usage   <tt>myInstance.getRedDodge();</tt>
+	* @return Number
+	*/
+	//Marcel Fahle's Color Dodge methods - www.marcelfahle.com	
+	public function getRedDodge(Void):Number {
+		var trans:Object = this.getTransform();
+		return ((25600-(258*trans.ra))/trans.ra);		
+	}
+	
+	/**
+	* @method setRedDodge
+	* @description
+	* @usage   <tt>myInstance.setRedDodge(value);</tt>
+	* @param value (Number)	
+	*/	
+	public function setRedDodge(value:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.ra=100/((258-value)/256);
+		this.setTransform(trans);
+	}
+	
+	/**
+	* @method getGreenDodge
+	* @description
+	* @usage   <tt>myInstance.getGreenDodge();</tt>
+	* @return Number
+	*/	
+	public function getGreenDodge(Void):Number{
+		var trans:Object = this.getTransform();
+		return ((25600-(258*trans.ga))/trans.ga);		
+	}
+	
+	/**
+	* @method setGreenDodge
+	* @description
+	* @usage   <tt>myInstance.setGreenDodge(value);</tt>
+	* @param value (Number)	
+	*/	
+	public function setGreenDodge(value:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.ga=100/((258-value)/256);
+		this.setTransform(trans);
+	}
+	
+	/**
+	* @method getBlueDodge
+	* @description
+	* @usage   <tt>myInstance.getBlueDodge();</tt>
+	* @return Number
+	*/	
+	public function getBlueDodge(Void):Number{
+		var trans:Object = this.getTransform();
+		return ((25600-(258*trans.ba))/trans.ba);		
+	}	
+	
+	/**
+	* @method setBlueDodge
+	* @description
+	* @usage   <tt>myInstance.setBlueDodge(value);</tt>
+	* @param value (Number)	
+	*/	
+	public function setBlueDodge(value:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.ba=100/((258-value)/256);
+		this.setTransform(trans);
+	}
+	
+	/**
+	* @method getBrightness
+	* @description
+	* @usage   <tt>myInstance.getBrightness();</tt>
+	* @return Number
+	*/	
+	//adapted color_toolkit.as by Robert Penner
+	public function getBrightness(Void):Number {
+		var trans:Object = this.getTransform();
+		return trans.rb ? 100 - trans.ra : trans.ra - 100;		
+	}	
+	
+	/**
+	* @method setBrightness
+	* @description
+	* @usage   <tt>myInstance.setBrightness(bright);</tt>
+	* @param bright (Number)	
+	*/	
+	// brighten just like Property Inspector
+	// bright between -100 and 100
+	public function setBrightness(bright:Number):Void {			
+		var trans:Object = this.getTransform();		
+		trans.ra = trans.ga = trans.ba = 100 - Math.abs (bright); // color percent
+		trans.rb = trans.gb = trans.bb = (bright > 0) ? bright * (256/100) : 0; // color offset
+		this.setTransform (trans);		
+	}
+	
+	/**
+	* @method getNegative
+	* @description
+	* @usage   <tt>myInstance.getNegative();</tt>
+	* @return Number
+	*/	
+	public function getNegative(Void):Number {		
+		return this.getTransform().rb * (100/255);
+	}
+	
+	/**
+	* @method setNegative
+	* @description
+	* @usage   <tt>myInstance.setNegative(percent);</tt>
+	* @param percent (Number)	
+	*/	
+	// produce a negative image of the normal appearance
+	public function setNegative(percent:Number):Void {
+		var t:Object = {};
+		t.ra = t.ga = t.ba = 100 - 2 * percent;
+		t.rb = t.gb = t.bb = percent * (255/100);
+		this.setTransform (t);
+	}
+	
+	/**
+	* @method hexrgb2rgb
+	* @description
+	* @usage   <tt>myInstance.hexrgb2rgb(hexrgb);</tt>
+	* @param hexrgb (Number)
+	* @return Object
+	*/	
+	
+	/**
+	* @method rgb2hexrgb
+	* @description
+	* @usage   <tt>myInstance.rgb2hexrgb(r,g,b);</tt>
+	* @param r (Number)
+	* @param g (Number)
+	* @param b (Number)
+	* @return Number
+	*/
+	
+	/**
+	* @method reset
+	* @description reset the color object to normal.
+	* @usage   <tt>myInstance.reset();</tt>
+	*/	
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/		
+	public function toString(Void):String {
+		return "ColorFX";
+	}	
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorFX.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorToolkit.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorToolkit.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorToolkit.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,314 @@
+import de.alex_uhlmann.animationpackage.utility.ColorCore;
+
+/**
+* @class ColorToolkit
+* @author Alex Uhlmann
+* @description  Offers easy access to properties of the Color transform object. 
+* 				Used by ColorTransform and ColorDodge classes.
+* 			<p>
+* 			Example 1: Sets the movieclip mc to a solid write color.	
+* 			<blockquote><pre>
+*			var myColorToolkit:ColorToolkit = new ColorToolkit(mc);
+*			myColorToolkit.setColorOffsetHex(0xffffff);
+*			</pre></blockquote>
+* 			<p>
+* 
+* @usage <pre>var myColorToolkit:ColorToolkit = new ColorToolkit(mc);</pre> 
+* @param mc (MovieClip) Movieclip to animate. 
+*/
+//adapted color_toolkit.as by Robert Penner
+class de.alex_uhlmann.animationpackage.utility.ColorToolkit extends ColorCore {			
+		
+	public function ColorToolkit(mc:MovieClip) {
+		super(mc);		
+	}
+	
+	/**
+	* @method getColorOffsetHex
+	* @description
+	* @usage   <tt>myInstance.getColorOffsetHex();</tt>
+	* @return Number
+	*/	
+	public function getColorOffsetHex(Void):Number {		
+		return this.rgb2hexrgb(this.getRedOffset(), 
+								this.getGreenOffset(), 
+								this.getBlueOffset());		
+	}
+	
+	/**
+	* @method setColorOffsetHex
+	* @description
+	* @usage   <tt>myInstance.setColorOffsetHex(rgb);</tt>
+	* @param rgb (Number)	
+	*/
+	public function setColorOffsetHex(rgb:Number):Void {		
+		var rgbObj:Object = this.hexrgb2rgb(rgb);		
+		this.setRedOffset(rgbObj.r);
+		this.setGreenOffset(rgbObj.g);
+		this.setBlueOffset(rgbObj.b);		
+	}
+	
+	/**
+	* @method getColorOffset
+	* @description
+	* @usage   <tt>myInstance.getColorOffset();</tt>
+	* @return Object
+	*/	
+	public function getColorOffset(Void):Object {		
+		return {r:this.getRedOffset(), 
+				g:this.getGreenOffset(), 
+				b:this.getBlueOffset(), 
+				a:this.getAlphaOffset()};		
+	}
+	
+	/**
+	* @method setColorOffset
+	* @description
+	* @usage   <tt>myInstance.setColorOffset(rgb);</tt>
+	* @param rgb (Object)	
+	*/	
+	public function setColorOffset(rgb:Object):Void {		
+		this.setRedOffset(rgb.r);
+		this.setGreenOffset(rgb.g);
+		this.setBlueOffset(rgb.b);
+		this.setAlphaOffset(rgb.a);
+	}
+	
+	/**
+	* @method getColorPercent
+	* @description
+	* @usage   <tt>myInstance.getColorPercent();</tt>
+	* @return Object
+	*/	
+	public function getColorPercent(Void):Object {		
+		return {r:this.getRedPercent(), 
+				g:this.getGreenPercent(), 
+				b:this.getBluePercent(), 
+				a:this.getAlphaPercent()};
+	}
+	
+	/**
+	* @method setColorPercent
+	* @description
+	* @usage   <tt>myInstance.setColorPercent(percent);</tt>
+	* @param percent (Number)	
+	*/	
+	public function setColorPercent(percent:Number):Void {			
+		this.setRedPercent(percent);
+		this.setGreenPercent(percent);
+		this.setBluePercent(percent);
+		this.setAlphaPercent(percent);
+	}	
+	
+	/**
+	* @method getRedOffset
+	* @description
+	* @usage   <tt>myInstance.getRedOffset();</tt>
+	* @return Number
+	*/	
+	//color offset
+	public function getRedOffset(Void):Number {		
+		return this.getTransform().rb;
+	}	
+	
+	/**
+	* @method setRedOffset
+	* @description
+	* @usage   <tt>myInstance.setRedOffset(offset);</tt>
+	* @param offset (Number)	
+	*/	
+	public function setRedOffset(offset:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.rb = offset;
+		this.setTransform (trans);
+	}
+	
+	/**
+	* @method getGreenOffset
+	* @description
+	* @usage   <tt>myInstance.getGreenOffset();</tt>
+	* @return Number
+	*/	
+	public function getGreenOffset(Void):Number {		
+		return this.getTransform().gb;
+	}	
+	
+	/**
+	* @method setGreenOffset
+	* @description
+	* @usage   <tt>myInstance.setGreenOffset(offset);</tt>
+	* @param offset (Number)	
+	*/	
+	public function setGreenOffset(offset:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.gb = offset;
+		this.setTransform(trans);
+	}
+
+	/**
+	* @method getBlueOffset
+	* @description
+	* @usage   <tt>myInstance.getBlueOffset();</tt>
+	* @return Number
+	*/
+	public function getBlueOffset(Void):Number {		
+		return this.getTransform().bb;
+	}	
+	
+	/**
+	* @method setBlueOffset
+	* @description
+	* @usage   <tt>myInstance.setBlueOffset(offset);</tt>
+	* @param offset (Number)	
+	*/	
+	public function setBlueOffset(offset:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.bb = offset;
+		this.setTransform (trans);
+	}
+	
+	/**
+	* @method getAlphaOffset
+	* @description
+	* @usage   <tt>myInstance.getAlphaOffset();</tt>
+	* @return Number
+	*/	
+	public function getAlphaOffset(Void):Number {		
+		return this.getTransform().ab;
+	}	
+	
+	/**
+	* @method setAlphaOffset
+	* @description
+	* @usage   <tt>myInstance.setAlphaOffset(offset);</tt>
+	* @param offset (Number)	
+	*/	
+	public function setAlphaOffset(offset:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.ab = offset;		
+		this.setTransform(trans);
+	}	
+	
+	/**
+	* @method getRedPercent
+	* @description
+	* @usage   <tt>myInstance.getRedPercent();</tt>
+	* @return Number
+	*/	
+	//color percent
+	public function getRedPercent(Void):Number {		
+		return this.getTransform().ra;
+	}	
+	
+	/**
+	* @method setRedPercent
+	* @description
+	* @usage   <tt>myInstance.setRedPercent(percent);</tt>
+	* @param percent (Number)	
+	*/	
+	public function setRedPercent(percent:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.ra = percent;
+		this.setTransform(trans);
+	}
+	
+	/**
+	* @method getGreenPercent
+	* @description
+	* @usage   <tt>myInstance.getGreenPercent();</tt>
+	* @return Number
+	*/	
+	public function getGreenPercent(Void):Number {		
+		return this.getTransform().ga;
+	}	
+	
+	/**
+	* @method setGreenPercent
+	* @description
+	* @usage   <tt>myInstance.setGreenPercent(percent);</tt>
+	* @param percent (Number)	
+	*/	
+	public function setGreenPercent(percent:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.ga = percent;
+		this.setTransform(trans);
+	}
+	
+	/**
+	* @method getBluePercent
+	* @description
+	* @usage   <tt>myInstance.getBluePercent();</tt>
+	* @return Number
+	*/	
+	public function getBluePercent(Void):Number {		
+		return this.getTransform().ba;
+	}	
+	
+	/**
+	* @method setBluePercent
+	* @description
+	* @usage   <tt>myInstance.setBluePercent(percent);</tt>
+	* @param percent (Number)	
+	*/	
+	public function setBluePercent(percent:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.ba = percent;
+		this.setTransform(trans);
+	}
+	
+	/**
+	* @method getAlphaPercent
+	* @description
+	* @usage   <tt>myInstance.getAlphaPercent();</tt>
+	* @return Number
+	*/	
+	public function getAlphaPercent(Void):Number {		
+		return this.getTransform().aa;
+	}	
+	
+	/**
+	* @method setAlphaPercent
+	* @description
+	* @usage   <tt>myInstance.setAlphaPercent(percent);</tt>
+	* @param percent (Number)	
+	*/	
+	public function setAlphaPercent(percent:Number):Void {
+		var trans:Object = this.getTransform();
+		trans.aa = percent;
+		this.setTransform(trans);
+	}
+	
+	/**
+	* @method hexrgb2rgb
+	* @description
+	* @usage   <tt>myInstance.hexrgb2rgb(hexrgb);</tt>
+	* @param hexrgb (Number)
+	* @return Object
+	*/	
+	
+	/**
+	* @method rgb2hexrgb
+	* @description
+	* @usage   <tt>myInstance.rgb2hexrgb(r,g,b);</tt>
+	* @param r (Number)
+	* @param g (Number)
+	* @param b (Number)
+	* @return Number
+	*/
+	
+	/**
+	* @method reset
+	* @description reset the color object to normal.
+	* @usage   <tt>myInstance.reset();</tt>
+	*/	
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/		
+	public function toString(Void):String {
+		return "ColorToolkit";
+	}	
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/ColorToolkit.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/FrameTween.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/FrameTween.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/FrameTween.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,143 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.utility.Tween;
+import de.andre_michelle.events.FrameBasedInterval;
+import de.andre_michelle.events.ImpulsDispatcher;
+
+/*
+* @class FrameTween
+* @author Alex Uhlmann
+* @description  Frame-based tween engine. 
+* 				FrameTween uses André Michelle's FrameBasedInterval and ImpulsDispatcher classes 
+* 				for efficient frame tweening. Frame based tweening is faster and more accurate than time based tweening.
+*/
+class de.alex_uhlmann.animationpackage.utility.FrameTween extends Tween {		
+	
+	private static var activeTweens:Array = new Array();
+	private static var interval:Number = 10;
+	private static var startPauseAll:Number;	
+	private static var intervalID : Number;
+	private static var dispatcher : Object = new Object();
+	
+	private static function addTween(tween:FrameTween):Void {
+		tween.id = activeTweens.length;
+		activeTweens.push(tween);	
+		if (intervalID == null) {
+			if(!ImpulsDispatcher._timeline) {						
+				ImpulsDispatcher.initialize(APCore.getCentralMC());				
+			}
+			dispatcher.dispatchTweens = dispatch;
+			ImpulsDispatcher.addImpulsListener(dispatcher, "dispatchTweens");
+			intervalID = 1;
+		}
+	}
+	
+	private static function removeTweenAt(index:Number):Void {
+		var tweens:Array = FrameTween.activeTweens;
+
+		if(index >= tweens.length || index < 0 || index == null) {				
+			return;
+		}
+		
+		FrameBasedInterval.removeInterval(tweens[index].frameIntervalToken);
+		tweens.splice(index, 1);
+		var i:Number;
+		var len:Number = tweens.length;
+		for (i = index; i < len; i++) {
+			tweens[i].id--;
+		}
+		if (len == 0) {
+			intervalID = null;
+		}
+	}
+	
+	private static function dispatch(Void):Void {
+		var tweens:Array = FrameTween.activeTweens;
+		var i:Number;
+		var len:Number = tweens.length;		
+		for (i = 0; i < len; i++) { 
+			tweens[i].doInterval();
+		}
+	}
+	
+	private var frameIntervalToken:Object;
+	
+	public function FrameTween(listener:Object, 
+							  start:Object, end:Object, duration:Number, 
+							  easingParams:Array) {			
+		
+		super(listener, start, end, duration, easingParams);
+	}
+	
+	public function start():Void {			
+		if(easingEquation == null) {
+			easingEquation = defaultEasingEquation;
+		}
+		if (this.duration == 0) {
+			endTween();
+		} else {				
+			FrameTween.addTween(this);
+			this.frameIntervalToken = FrameBasedInterval.addInterval(this, "onFrameEnd", duration);			
+		}
+		this.startTime = this.frameIntervalToken.startFrame;
+		this.isTweening = true;
+	}
+	
+	public function stop():Void {
+		FrameTween.removeTweenAt(this.id);
+		this.isTweening = false;
+	}
+	
+	public function pause():Void {
+		startPause = FrameBasedInterval.frame;
+		delete FrameTween.activeTweens[this.id];
+		this.isTweening = false;
+	}
+	
+	public function resume():Void {
+		var pausedTime:Number = FrameBasedInterval.frame - this.startPause;
+		this.startTime += pausedTime;
+		FrameTween.activeTweens[this.id] = this;
+		this.isTweening = true;
+	}		
+
+	public static function pauseAll():Void {
+		ImpulsDispatcher.pause();
+		var tweens:Array = FrameTween.activeTweens;
+		var i:Number = tweens.length;
+		while(--i > -1) {
+			tweens[i].isTweening = false;
+		}
+	}
+	
+	public static function resumeAll():Void {
+		ImpulsDispatcher.resume();
+		var tweens:Array = FrameTween.activeTweens;
+		var i:Number = tweens.length;
+		while(--i > -1) {
+			tweens[i].isTweening = true;
+		}
+	}
+	
+	private function doInterval():Void {
+		var curTime:Number = FrameBasedInterval.frame - startTime;			
+		var curVal:Object;
+		if(easingParams == null) {
+			curVal = getCurVal(curTime);
+		} else {
+			curVal = getCurVal2(curTime);
+		}
+		if (curTime >= duration) {			
+			endTween(curVal);
+		} else {
+			if (updateMethod != null) {
+				listener[updateMethod](curVal);
+			} else {
+				listener.onTweenUpdate(curVal);
+			}
+		}
+	}
+
+	public function toString(Void):String {
+		return "FrameTween";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/FrameTween.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IComposite.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IComposite.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IComposite.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,4 @@
+
+interface de.alex_uhlmann.animationpackage.utility.IComposite {
+
+}


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IComposite.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitor.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitor.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitor.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,4 @@
+import de.alex_uhlmann.animationpackage.utility.IVisitorElement;
+interface de.alex_uhlmann.animationpackage.utility.IVisitor {
+	public function visit(visitorElement:IVisitorElement):Void;
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitor.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitorElement.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitorElement.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitorElement.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,4 @@
+import de.alex_uhlmann.animationpackage.utility.IVisitor;
+interface de.alex_uhlmann.animationpackage.utility.IVisitorElement {
+	public function accept(visitor:IVisitor):Void;
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/IVisitorElement.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Pause.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Pause.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Pause.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,607 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.andre_michelle.events.FrameBasedInterval;
+import de.andre_michelle.events.ImpulsDispatcher;
+
+/**
+* @class Pause
+* @author Alex Uhlmann
+* @description Take a break and do something afterwards. <p>		
+* 			You can invoke any function if you specify the scope param. If you don't specify 
+* 			it, then Pause will invoke the callback to all listeners of APCore.	
+* 			If no listener was specified, Pause will invoke	the callback on itself. 
+* 			Pause implements the IAnimatable interface and therefore can be used just 
+* 			like any other IAnimatable class (i.e. in composite classes like Sequence or 
+* 			with constructor initialization, animate and run methods). Nevertheless, 
+* 			the examples below use the waitMS and waitFrames methods to pause with Pause.
+* 			<p>
+*			Use waitMS to wait a certain amount of time (in milliseconds)
+* 			and call a function afterwards.
+* 			<p>
+* 			Example 1: subscribe a listener to all events from AnimationPackage (APCore), 
+* 			and setup the onStart and onCallback functions. Use the Pause class 
+* 			to wait one second and send the onStart event. Inside onStart 
+* 			use Pause to wait again and send the onCallback event, 
+* 			this time with two specified parameters. Inside onCallback, wait again. 
+* 			Then, invoke a custom function (fooFunc) in _root scope. Send two parameters.
+* 			<blockquote><pre>	
+* 			APCore.initialize();
+*			var myListener:Object = new Object();
+*			APCore.addListener(myListener);
+* 			new Pause().waitMS(1000,"onStart");
+*			myListener.onStart = function() {	
+*				trace("onStart "+arguments);
+*				new Pause().waitMS(1000, "onCallback", ["foo", "bar"]);
+*			}
+*			
+*			myListener.onCallback = function(source, params) {
+*				trace("onCallback "+arguments);	
+*				new Pause().waitMS(1000, _root, "fooFunc", ["foo", "bar"]);
+*			}
+*			
+*			function fooFunc(bar:String, foo:String) {
+*				trace("fooFunc "+arguments);
+*			}
+*			</pre></blockquote>	
+* 			
+*			Example 2: Do the same like above, just with frames. 
+* 			Use waitFrames to wait a certain amount of time (in frames)
+*			and call a function afterwards.
+* 			<blockquote><pre>
+* 			APCore.initialize();
+*			var myListener:Object = new Object();
+*			APCore.addListener(myListener);
+*			new Pause().waitFrames(10,"onStart");
+*			myListener.onStart = function() {	
+*				trace("onStart "+arguments);
+*				new Pause().waitFrames(10, "onCallback", ["foo", "bar"]);
+*			}
+*			myListener.onCallback = function(source, params) {
+*				trace("onCallback "+arguments);	
+*				new Pause().waitFrames(10, _root, "fooFunc", ["foo", "bar"]);
+*			}
+*			function fooFunc(bar:String, foo:String) {
+*				trace("fooFunc "+arguments);
+*			}
+*			</pre></blockquote> 
+* 
+* 
+* 
+* @usage 
+* 		<pre>var myPause:Pause = new Pause();</pre>
+*		<pre>var myPause:Pause = new Pause(type, duration, callbackParam);</pre>
+* 		<pre>var myPause:Pause = new Pause(type, duration, callbackParam, param);</pre>
+*		<pre>var myPause:Pause = new Pause(type, duration, scope, callbackParam);</pre>
+* 		<pre>var myPause:Pause = new Pause(type, duration, scope, callbackParam, param);</pre>
+* @param type (String) Type of Pause. Either MS for time based pausing or FRAME for frame based pausing.
+* @param duration (Number) The duration to be paused. 
+* @param scope (Object) scope of callbackParam.
+* @param callbackParam (String) Function to invoke after animation.
+* @param param (Array) Parameters to send to callbackParam.
+*/
+class de.alex_uhlmann.animationpackage.utility.Pause 
+										extends AnimationCore
+										implements ISingleAnimatable {		
+	
+	
+	/** 
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	*/
+	
+	private static var refs:Object;
+	private var type:String;
+	private var scope:Object;
+	private var param:Array;
+	private var interval_ID:Object;
+	private var pauseMode:String;
+	private var startTime:Number;
+	
+	private var elapsedDuration:Number = 0;
+	private var stopped:Boolean = false;
+	private var finished:Boolean = false;
+	private var startPause:Number;
+	private var durationPaused:Number = 0;
+	private var durationOrig:Number;
+	//used for invoking an onUpdate event.
+	private var elapsedDurationSaved:Number;
+	
+	public function Pause() {
+		super();
+		/*
+		* don't let the garbage collector delete the instance 
+		* if invoked only via constructor. Save a reference.
+		*/
+		if(Pause.refs == null) {
+			Pause.refs = new Object();
+		}
+		Pause.refs[this.getID()] = this;
+		
+		if(arguments.length > 0) {			
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function init():Void {		
+		
+		if(arguments.length == 0) {
+			return;
+		}
+		this.type = arguments[0];
+		var duration:Number = arguments[1];
+		var scope:Object = arguments[2];
+		var callbackParam:Object = arguments[3];
+		var param:Array = arguments[4];
+		/*handles APCore call with and without parameters*/
+		if(typeof(scope) == "string") {
+			var temp = callbackParam;			
+			param = temp;
+			temp = scope;
+			this.callback = temp;
+			delete scope;	
+		} else {
+			this.scope = scope;
+			var temp = callbackParam;			
+			this.callback = temp;
+			this.param = param;			
+		}
+		
+		if(this.type == AnimationCore.MS) {				
+			this.duration = this.durationOrig = duration;		
+		} else if(this.type == AnimationCore.FRAMES) {				
+			this.duration = this.durationOrig = Math.round(duration);		
+		}
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		
+		if(this.type == AnimationCore.MS) {				
+			if(end != null) {
+				start = start / 100 * this.duration;
+				this.startTime = getTimer() + start;
+				end = end / 100 * this.duration;
+				this.duration = end;
+				this.paused = false;				
+				this.initMSInterval();
+				ImpulsDispatcher.addImpulsListener(this, "dispatchUpdate");
+			} else {
+				start = start / 100 * this.duration;
+				this.paused = true;
+				this.elapsedDuration = start;
+				this.dispatchUpdate();
+			}			
+			
+		} else if(this.type == AnimationCore.FRAMES) {				
+			if(end != null) {
+				start = start / 100 * this.duration;
+				this.startTime = FrameBasedInterval.frame + start;
+				end = end / 100 * this.duration;
+				this.duration = end;
+				this.paused = false;				
+				this.initFramesInterval();
+				ImpulsDispatcher.addImpulsListener(this, "dispatchUpdate");
+			} else {
+				start = start / 100 * this.duration;
+				this.paused = true;
+				this.elapsedDuration = start;
+				this.dispatchUpdate();
+			}
+		}
+	}
+	
+	public function dispatchUpdate(Void):Void {
+		var durationElapsed:Number = this.getDurationElapsed();
+		if(this.elapsedDurationSaved != durationElapsed) {
+			if(durationElapsed == 0) {
+				this.dispatchEvent.apply(this, [ {type:"onStart"} ]);
+			} else if(this.finished) {
+				this.dispatchEvent.apply(this, [ {type:"onEnd"} ]);
+			} else {
+				this.dispatchEvent.apply(this, [ {type:"onUpdate"} ]);
+			}
+		}
+		this.elapsedDurationSaved = durationElapsed;
+	}
+	
+	/**
+	* @method run
+	* @description 	Rotates a movieclip from its the current _rotation property value 
+	* 			to a specified amount in a specified time and easing equation.
+	* 		
+	* @usage   
+	* 		<pre>myInstance.run();</pre>
+	*		<pre>myInstance.(type, duration, callbackParam);</pre>
+	* 		<pre>myInstance.(type, duration, callbackParam, param);</pre>
+	*		<pre>myInstance.(type, duration, scope, callbackParam);</pre>
+	* 		<pre>myInstance.(type, duration, scope, callbackParam, param);</pre>
+	* 	  
+	* @param type (String) Type of Pause. Either MS for time based pausing or FRAME for frame based pausing.
+	* @param duration (Number) The duration to be paused. 
+	* @param scope (Object) scope of callbackParam.
+	* @param callbackParam (String) Function to invoke after animation.
+	* @param param (Array) Parameters to send to callbackParam.
+	* @return void
+	*/
+	
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	/**
+	* @method waitMS
+	* @description	
+	* 		
+	* @usage   <pre>myPause.waitMS(milliseconds, callbackParam);</pre>
+	* 		<pre>myPause.waitMS(milliseconds, callbackParam, param);</pre>
+	*		<pre>myPause.waitMS(milliseconds, scope, callbackParam);</pre>
+	* 		<pre>myPause.waitMS(milliseconds, scope, callbackParam, param);</pre>
+	* 	  
+	* @param milliseconds (Number) milliseconds to wait
+	* @param scope (Object) scope of callbackParam.
+	* @param callbackParam (String) Function to invoke after animation.
+	* @param param (Array) Parameters to send to callbackParam.
+	* @return void
+	*/
+	public function waitMS(milliseconds:Number, scope:Object, 
+							callbackParam:Object, param:Array):Void {
+		this.init(AnimationCore.MS, 
+					milliseconds, 
+					scope, 
+					callbackParam, 
+					param);
+					
+		this.invokeAnimation(0,100);
+	}
+	
+	private function initMSInterval(Void):Void {		
+		this.pauseMode = "INTERVAL";		
+		this.tweening = true;
+		this.finished = false;
+		clearInterval(Number(this.interval_ID));
+		this.interval_ID = setInterval(this, "clearPause", this.duration);
+		this.dispatchEvent.apply(this, [ {type:"onStart"} ]);
+	}
+	
+	/**
+	* @method waitFrames
+	* @description
+	* 		
+	* @usage   <pre>myPause.waitFrames(milliseconds, callbackParam);</pre>
+	* 		<pre>myPause.waitFrames(milliseconds, callbackParam, param);</pre>
+	*		<pre>myPause.waitFrames(milliseconds, scope, callbackParam);</pre>
+	* 		<pre>myPause.waitFrames(milliseconds, scope, callbackParam, param);</pre>
+	* 	  
+	* @param milliseconds (Number) milliseconds to wait
+	* @param scope (Object) scope of callbackParam.
+	* @param callbackParam (String) Function to invoke after animation.
+	* @param param (Array) Parameters to send to callbackParam.
+	* @return void
+	*/
+	public function waitFrames(frames:Number, scope:Object, 
+								callbackParam:Object, param:Array):Void {
+		this.init("FRAMES", 
+					frames, 
+					scope, 
+					callbackParam, 
+					param);
+					
+		this.invokeAnimation(0,100);
+	}
+	
+	private function initFramesInterval(Void):Void {		
+		this.pauseMode = "FRAMES";		
+		this.tweening = true;
+		this.finished = false;
+		this.interval_ID = FrameBasedInterval.addInterval(this, 
+													"clearPause", 
+													this.duration);
+		this.dispatchEvent.apply(this, [ {type:"onStart"} ]);	
+	}
+	
+	private function clearPause(Void):Void {
+		this.tweening = false;
+		this.finished = true;		
+		clearInterval(Number(this.interval_ID));
+		FrameBasedInterval.removeInterval(this.interval_ID);
+		this.switchCallback(this.scope, this.callback, this.param);
+	}	
+	
+	private function switchCallback(scope:Object, 
+									callback:String, 
+									param:Array):Void {		
+		if(scope == null) {			
+			this.invokeAPCallback(callback, param);
+		} else {
+			this.invokeCallback(scope, callback, param);
+		}
+	}
+	
+	private function invokeAPCallback(callback:String, param:Array):Void {		
+		if(param == null) {		
+			APCore.broadcastMessage(callback, this);
+			this.dispatchEvent.apply(this, [ {type:"onEnd"} ]);
+		} else {				
+			APCore.broadcastMessage(callback, this, param);
+			this.dispatchEvent.apply(this, [ {type:"onEnd", parameters:param} ]);
+		}
+		delete Pause.refs[this.getID()];
+	}
+		
+	private function invokeCallback(scope:Object, 
+									callback:String, 
+									param:Array):Void {		
+		scope[callback].apply(scope, param);
+		this.dispatchEvent.apply(this, [ {type:"onEnd", parameters:param} ]);
+		delete Pause.refs[this.getID()];
+		ImpulsDispatcher.removeImpulsListener(this);
+	}
+	
+	public function stop(Void):Boolean {		
+		if(super.stop() == true) {
+			this.stopped = true;
+			this.elapsedDuration = this.computeElapsedDuration();
+			if(this.pauseMode == "INTERVAL") {				
+				clearInterval(Number(this.interval_ID));
+			} else if(this.pauseMode == "FRAMES") {				
+				FrameBasedInterval.removeInterval(this.interval_ID);	
+			}
+			ImpulsDispatcher.removeImpulsListener(this);
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+	/*
+	* pause would be an illegal identifier, 
+	* because Pause is the class and Flash Player 6 
+	* cannot differ lower and upper cases at runtime.
+	*/
+	public function pauseMe(duration:Number):Boolean {
+		if(super.pause(duration) == false) {			
+			return false;
+		}
+		this.paused = true;
+		this.elapsedDuration = this.computeElapsedDuration();	
+		if(this.pauseMode == "INTERVAL") {
+			this.startPause = getTimer();
+			clearInterval(Number(this.interval_ID));
+		} else if(this.pauseMode == "FRAMES") {			
+			this.startPause = FrameBasedInterval.frame;
+			FrameBasedInterval.removeInterval(this.interval_ID);	
+		}
+		ImpulsDispatcher.removeImpulsListener(this);
+		return true;
+	}
+	
+	public function resume(Void):Boolean {
+		if(this.locked == true) {
+			return false;
+		} else {
+			this.tweening = true;
+			this.paused = false;
+			this.duration -= this.elapsedDuration;
+			if(this.getTweenMode() == AnimationCore.INTERVAL) {				
+				this.durationPaused += getTimer() - this.startPause;
+				this.initMSInterval();
+			} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+				this.durationPaused += FrameBasedInterval.frame 
+										- this.startPause;
+				this.initFramesInterval();
+			}
+			ImpulsDispatcher.addImpulsListener(this, "dispatchUpdate");
+			return true;
+		}
+	}
+	
+	public function getDurationElapsed(Void):Number {		
+		if(this.paused == true || this.stopped == true) {			
+			return this.elapsedDuration;
+		} else {
+			return this.computeElapsedDuration();
+		}
+	}
+	
+	public function getDurationRemaining(Void):Number {
+		var r:Number;
+		if(this.stopped == false) {
+			if(this.getTweenMode() == AnimationCore.INTERVAL) {
+				r = this.durationOrig - this.getDurationElapsed();
+			} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+				if(this.getDurationMode() == AnimationCore.MS) {	
+					r = this.durationOrig - this.getDurationElapsed();
+					if(this.finished == true) {
+						r = 0;
+					}
+				} else {
+					r = this.durationOrig - this.getDurationElapsed();
+				}
+			}			
+			if(r < 0) {
+				r = 0;
+			}
+		} else {
+			r = 0;
+		}
+		return r;
+	}
+	
+	private function computeElapsedDuration(Void):Number {
+		if(this.finished == true) {
+			return this.durationOrig;
+		} else {		
+			if(this.getTweenMode() == AnimationCore.INTERVAL) {
+				return getTimer() - this.startTime - this.durationPaused;
+			} else if(this.getTweenMode() == AnimationCore.FRAMES) {
+				if(this.getDurationMode() == AnimationCore.MS) {
+					return APCore.fps * (FrameBasedInterval.frame - this.startTime - this.durationPaused);			
+				} else {
+					return FrameBasedInterval.frame - this.startTime - this.durationPaused;
+				}		
+			}
+		}
+	}
+	
+	public function getStartValue(Void):Number {		
+		return 0;
+	}	
+	
+	public function getEndValue(Void):Number {		
+		return this.durationOrig;
+	}	
+	
+	public function getCurrentValue(Void):Number {		
+		return this.getDurationElapsed();
+	}
+	
+	public function getCurrentPercentage(Void):Number {		
+		return this.getDurationElapsed() / this.durationOrig * 100;
+	}
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pauseMe
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pauseMe();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/	
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/
+	
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/	
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	* 		
+	* @usage   <pre>myPause.addEventListener(event, listener);</pre>
+	* 		    <pre>myPause.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myPause.removeEventListener(event, listener);</pre>
+	* 		    <pre>myPause.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myPause.removeAllEventListeners();</pre>
+	* 		    <pre>myPause.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myPause.eventListenerExists(event, listener);</pre>
+	* 			<pre>myPause.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/
+	public function toString(Void):String {
+		return "Pause";
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Pause.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/SingleAnimator.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/SingleAnimator.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/SingleAnimator.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,468 @@
+import de.alex_uhlmann.animationpackage.animation.ISingleAnimatable;
+import de.alex_uhlmann.animationpackage.animation.AnimationCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/**
+* @class SingleAnimator
+* @author Ralf Bokelberg, Alex Uhlmann
+* @description  SingleAnimator allows to animate a single property or method in a more intuitive way than via Animator. 
+* 			You can animate a property or method on a specified object. Specify the object via the construtor 
+* 			or the property animationTarget. The identifier parameter accepts either a function as a String 
+* 			or a property as a String.<p>
+* 			Example 1: fade out a sound. You could have used the Volume class, too.
+* 			<blockquote><pre>
+*			var mySound:Sound = new Sound(this);
+*			mySound.attachSound("mySoundID");
+*			mySound.start();
+* 
+*			var mySingleAnimator:SingleAnimator = new SingleAnimator(mySound,"setVolume",[100,0],3000);
+*			mySingleAnimator.run();
+*			</pre></blockquote>
+* 			<p> 
+* 			There are many ways to use this class. One way is to specify 
+* 			the duration, easing equation and callback properties outside 
+* 			the current method, either with setting the properies directly 
+* 			or with the animationStyle() method like it is used in 
+* 			de.alex_uhlmann.animationpackage.drawing.
+* 			<p>
+* 			Example 2: 
+* 			<blockquote><pre>			
+*			var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget);
+*			mySingleAnimator.animationStyle(2000,Circ.easeIn,"onCallback");
+*			mySingleAnimator.run("myProperty",50);
+*			</pre></blockquote>  			
+* 			Example 3: The alternative way is shorter. The same like above in one line.
+* 			<blockquote><pre>	
+* 			new SingleAnimator(animationTarget).run("myProperty",50,2000,Circ.easeInOut,"onCallback");
+* 			</pre></blockquote>
+* 			Example 4: You can also specify the properties via the constructor. 
+* 			This might come in handy if you're using the Sequence or Parallel class.  
+* 			Take a look at their class documentations for more information. 
+* 			The animate() method and its start and end percentage parameters might also be useful. 			
+* 			<blockquote><pre>
+* 			var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget,"myProperty",50,2000,Circ.easeInOut);
+* 			mySingleAnimator.animate(50,100);
+* 			</pre></blockquote>
+* 			Example 5: By default, the start value of your animation is 0. 
+* 			You can explicitly define the start values either via the setStartValue 
+* 			or run method or via the constructor. Here is one example for the constructor solution. 
+* 			This also might come in handy using composite classes, like Sequence.
+* 			<blockquote><pre>
+*			var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget,"myProperty",[0,50],2000,Circ.easeIn);
+*			mySingleAnimator.run();
+* 			</pre></blockquote>		
+* @usage      <pre>var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget);</pre> 
+* 			<pre>var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget, identifier, amount, duration, callback);</pre> 
+* 			<pre>var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget, identifier, amount, duration, easing, callback);</pre>
+*			<pre>var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget, identifier, values);</pre> 
+* 			<pre>var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget, identifier, values, duration, callback);</pre> 
+* 			<pre>var mySingleAnimator:SingleAnimator = new SingleAnimator(animationTarget, identifier, values, duration, easing, callback);</pre> 
+* @param animationTarget (Object) object to animate.
+* @param identifier (String) Function or property to animate on animationTarget.
+* @param amount (Number) Targeted amount to animate to.
+* @param values (Array) optional start and end values.
+* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+* @param callback (String) Function to invoke after animation. See AnimationCore class.
+*/
+class de.alex_uhlmann.animationpackage.utility.SingleAnimator 
+										extends AnimationCore 
+										implements ISingleAnimatable {	
+
+	/*animationStyle properties inherited from AnimationCore*/
+	/**
+	* @property animationTarget (Object) Object to animate.
+	* @property duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @property easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @property callback (String) Function to invoke after animation. See AnimationCore class. 
+	*/
+	private var identifier:String;
+	private var m_animationTarget:Object;
+	
+	public function SingleAnimator() {
+		super();
+		this.m_animationTarget = arguments[0];
+		if(arguments.length > 1) {
+			arguments.shift();
+			this.init.apply(this, arguments);
+		}
+	}
+	
+	private function init():Void {		
+		if(arguments[1] instanceof Array) {				
+			var values:Array = arguments[1];
+			var endValue:Number = values.slice(-1)[0];				
+			arguments.splice(1, 1, endValue);
+			this.initAnimation.apply(this, arguments);				
+			this.setStartValue(values[0]);				
+		} else if(arguments.length > 1) {				
+			this.initAnimation.apply(this, arguments);
+		}
+	}
+	
+	private function initAnimation(identifier:String, amount:Number, duration:Number, easing:Object, callback:String):Void {		
+		if (arguments.length > 2) {			
+			this.animationStyle(duration, easing, callback);
+		} else {
+			this.animationStyle(this.duration, this.easing, this.callback);
+		}
+		this.identifier = identifier;
+		this.setStartValue(0, true);		
+		this.setEndValue(amount);
+	}
+	
+	private function invokeAnimation(start:Number, end:Number):Void {		
+		this.startInitialized = false;
+		
+		this.myAnimator = new Animator();
+		this.myAnimator.caller = this;
+		this.myAnimator.start = [this.startValue];
+		this.myAnimator.end = [this.endValue];
+		this.myAnimator.setter = [[this.m_animationTarget, this.identifier]];	
+		if(end != null) {
+			this.myAnimator.animationStyle(this.duration, this.easing, this.callback);
+			this.myAnimator.animate(start, end);
+		} else {
+			this.myAnimator.goto(start);
+		}
+	}
+
+	/**
+	* @method run
+	* @description 		
+	* @usage   
+	* 		<pre>myInstance.run();</pre>
+	* 		<pre>myInstance.run(identifier, amount);</pre>
+	* 		<pre>myInstance.run(identifier, amount, duration);</pre>
+	*		<pre>myInstance.run(identifier, amount, duration, callback);</pre>
+	* 		<pre>myInstance.run(identifier, amount, duration, easing, callback);</pre>
+	* 		<pre>myInstance.run(identifier, values, duration);</pre>
+	* 		<pre>myInstance.run(identifier, values, duration, callback);</pre>
+	*		<pre>myInstance.run(identifier, values, duration, easing, callback);</pre>
+	* 	  
+	* @param amount (Number) Targeted frames to animate to.
+	* @param identifier (String) Function or property to animate on animationTarget.
+	* @param values (Array) optional start and end values.
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	* @return void
+	*/	
+
+	/**
+	* @method animate
+	* @description 	similar to the run() method. Offers start and end parameters.
+	* @usage   <pre>myInstance.animate(start, end);</pre> 	  
+	* @param start (Number) start value. Percentage.
+	* @param end (Number) end value. Percentage.
+	* @return void
+	*/
+	
+	/**
+	* @method goto
+	* @description 	jumps to a specific step of the animation and stays there.
+	* @usage   <pre>myInstance.goto(percentage);</pre>
+	* @param percentage (Number) Percentage value of the animation.
+	* @return void
+	*/	
+	
+	public function get animationTarget():Object {
+		return this.m_animationTarget;
+	}
+	
+	public function set animationTarget(animationTarget:Object):Void {
+		this.m_animationTarget = animationTarget;
+	}
+	
+	/*inherited from AnimationCore*/
+	/**
+	* @method animationStyle
+	* @description 	set the animation style properties for your animation.
+	* 			Notice that if your easing equation supports additional parameters you 
+	* 			can send those parameters with the easing parameter in animationStyle.
+	* 			You have to send an Array as easing parameter. The first 
+	* 			element has to be the easing equation in Robert Penner style. The 
+	* 			following parameters can be your additional parameters. i.e.:
+	* 			<blockquote><pre>
+	*			var myRotation:Rotation = new Rotation(mc);
+	*			myRotation.animationStyle(2000,[Back.easeOut,4]);
+	*			myRotation.run(360);
+	*			</pre></blockquote>
+	* 			See also "Customizable easing equations" in readme for more information.
+	* 	
+	* 		
+	* @usage   <pre>myInstance.animationStyle(duration);</pre>
+	* 		<pre>myInstance.animationStyle(duration, callback);</pre>
+	* 		<pre>myInstance.animationStyle(duration, easing, callback);</pre>
+	* 	  
+	* @param duration (Number) Duration of animation in milliseconds or frames. Default is milliseconds.
+	* @param easing (Object) Easing equation in Robert Penner style. Default equation is Linear.easeNone. www.robertpenner.com/easing/
+	* @param callback (String) Function to invoke after animation. See APCore class.
+	*/
+	
+	/**
+	* @method roundResult
+	* @description 	rounds animation results to integers. (might be usefull for animating pixelfonts). Default is false.		
+	* @usage   <pre>myInstance.roundResult(rounded);</pre>
+	*@param rounded (Boolean) <code>true</code> rounds the result. Animates with integers. Less accuracy. <code>false</code> animates with floating point numbers.
+	*/
+	
+	/**
+	* @method forceEnd
+	* @description 	Flash does not guaranteed that time-based tweening will reach 
+	* 			the end value(s) of your animation. By default AnimationPackage 
+	* 			guarantees that the end value(s) will be reached. The forceEnd 
+	* 			method allows you to disable this guarantee and only accept 
+	* 			the values from your easing equation. In certain situations this can 
+	* 			lead to a smoother ending of the animation. Notice that in frame-based 
+	* 			tweening the end value(s) will always be reached.	
+	* @usage   <pre>myInstance.forceEnd(forceEndVal);</pre>
+	*@param forceEndVal (Boolean) <code>true</code> or <code>false</code>.
+	*/
+	
+	/**
+	* @method getOptimizationMode
+	* @description 	returns the optimization mode. See setOptimizationMode for more information. 
+	* @usage   <tt>getOptimizationMode();</tt>
+	* @return Boolean
+	*/	
+	
+	/**
+	* @method setOptimizationMode
+	* @description 	Allows to explicitly remove parts of the animation that don't change during 
+	* 				the animation. 
+	* 				This can add additional performance to your animation. Note that 
+	* 				setting this method to true has side effects. If all start and end values match, 
+	* 				the animation won't start and will immediatly invoke an onEnd event. 
+	* 				The order of values returned by getStartValue(s), getCurrentValue(s), 
+	* 				getEndValue(s) and the value property of the eventObject returned 
+	* 				by EventDispatcher might change if you set this method to true. You can 
+	* 				still retrieve the parts of the animation that are actually animated 
+	* 				if you access the Animator instance of your animation class via 
+	* 				myAnimator. Ask <code>myInstance.myAnimator.setter</code> to retrieve 
+	* 				all currently animated parts of the animation. See Animator 
+	* 				documentation. Of cource, if you know your input values you would 
+	* 				probably look at them.<p>
+	* 				Note that the AnimationCore class offers a static setOptimizationModes method 
+	* 				(note the last "s" at the end) that allows you to remove parts of 
+	* 				'all' your animations that don't change during the animation.
+	* @usage   <pre>myInstance.setOptimizationMode(optimize);</pre>
+	* @param optimize (Boolean)
+	*/
+	
+	/**
+	* @method getTweenMode
+	* @description 	returns the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getTweenMode();</tt>
+	* @return String that specifies the tween mode. Either AnimationCore.INTERVAL or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setTweenMode
+	* @description 	sets the current tween mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setTweenMode();</tt> 	
+	* @param t (String) Either AnimationCore.INTERVAL for time-based tweening or AnimationCore.FRAMES for frame-based tweening.
+	* @returns   <code>true</code> if setting tween mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method getDurationMode
+	* @description 	returns the current duration mode used by the instance.
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>getDurationMode();</tt>
+	* @return String that specifies the duration mode. Either AnimationCore.MS or AnimationCore.FRAMES.
+	*/
+	
+	/**
+	* @method setDurationMode
+	* @description 	sets the current duration mode used by the instance. 
+	* 				Please check with AnimationCore.setTweenModes for more information.
+	* @usage   <tt>setDurationMode();</tt> 	
+	* @param d (String) Either AnimationCore.MS for milliseconds or AnimationCore.FRAMES.
+	* @returns   <code>true</code> if setting duration mode was successful, 
+	*                  <code>false</code> if not successful.
+	*/
+	
+	/**
+	* @method stop
+	* @description 	stops the animation if not locked..
+	* @usage   <tt>myInstance.stop();</tt> 
+	* @returns <code>true</code> if instance was successfully stopped. 
+	*                  <code>false</code> if instance could not be stopped, because it was locked.
+	*/	
+	
+	/**
+	* @method pause
+	* @description 	pauses the animation if not locked. Call resume() to continue animation.
+	* @usage   <tt>myInstance.pause();</tt> 	  
+	* @param duration (Number) optional property. Number of milliseconds or frames to pause before continuing animation.
+	* @returns <code>true</code> if instance was successfully paused. 
+	*                  <code>false</code> if instance could not be paused, because it was locked.
+	*/	
+	
+	/**
+	* @method resume
+	* @description 	continues the animation if not locked. 
+	* @usage   <tt>myInstance.resume();</tt> 	
+	* @returns <code>true</code> if instance was successfully resumed. 
+	*                  <code>false</code> if instance could not be resumed, because it was locked.
+	*/
+	
+	/**
+	* @method lock
+	* @description 	locks the animation to prevent pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.lock();</tt> 	  
+	*/	
+	
+	/**
+	* @method unlock
+	* @description 	unlocks the animation to allow pausing, resuming and stopping. Default is unlocked.
+	* @usage   <tt>myInstance.unlock();</tt> 	  
+	*/
+	
+	/**
+	* @method isTweening
+	* @description 	checks if the instance is currently animated.
+	* @usage   <tt>myInstance.isTweening();</tt> 	
+	* @returns   <code>true</code> if instance is tweening, 
+	*                  <code>false</code> if instance is not tweening.
+	*/	
+	
+	/**
+	* @method getStartValue
+	* @description 	returns the original, starting value of the current tween.
+	* @usage   <tt>myInstance.getStartValue();</tt>
+	* @return Number
+	*/
+
+	/**
+	* @method setStartValue
+	* @description 	sets the original, starting value of the current tween.
+	* @usage   <tt>myInstance.setStartValue(startValue);</tt>
+	* @param startValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+	
+	/**
+	* @method getEndValue
+	* @description 	returns the targeted value of the current tween.
+	* @usage   <tt>myInstance.getEndValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method setEndValue
+	* @description 	sets the targeted value of the current tween.
+	* @usage   <tt>myInstance.setEndValue(endValue);</tt>
+	* @param endValue (Number)	
+	* @return Boolean, indicates if the assignment was performed.
+	*/
+
+	/**
+	* @method getCurrentValue
+	* @description 	returns the current value of the current tween. In degrees.
+	* @usage   <tt>myInstance.getCurrentValue();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getCurrentPercentage
+	* @description 	returns the current state of the animation in percentage. 
+	* 				Especially usefull in combination with goto().
+	* @usage   <tt>myInstance.getCurrentPercentage();</tt>
+	* @return Number
+	*/	
+
+	/**
+	* @method getDurationElapsed
+	* @description 	returns the elapsed time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationElapsed();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method getDurationRemaining
+	* @description 	returns the remaining time or frames since the current tween started tweening.
+	* @usage   <tt>myInstance.getDurationRemaining();</tt>
+	* @return Number
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method addEventListener
+	* @description 	Subscribe to a predefined event. The following standard EventDispatcher events are broadcasted<p>
+	* 			<b>onStart</b>, broadcasted when animation starts.<br>
+	*			<b>onUpdate</b>, broadcasted when animation updates.<br>
+	*			<b>onEnd</b>, broadcasted when animation ends.<p>
+	* 			The even object returned, contains the following properties:<p>
+	* 			<b>type</b> (String) event broadcasted.<br>
+	*			<b>target</b> (Object) event source.<br>
+	*			<b>value</b> (Number) value to animate.<p>
+	* 		
+	* @usage   <pre>myInstance.addEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.addEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to subscribe listener to. GDispatcher specific feature allows to subscribe to all events from an event source if the string "ALL" is passed. 
+	*@param listener (Object) The listener object to subscribe to the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. The name of a function to call. This function will be called within the scope of the object specified in the second parameter.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeEventListener
+	* @description 	Removes a listener from a subscribed event.	
+	* 		
+	* @usage   <pre>myInstance.removeEventListener(event, listener);</pre>
+	* 		    <pre>myInstance.removeEventListener(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to remove subscribed listener from. GDispatcher specific feature allows to remove subscribtion to all events if the string "ALL" is passed. Works only if listener has been subscribed via the "ALL" string in addEventListener.
+	*@param listener (Object) The listener object to unsubscribe from the specified event.
+	*@param handler (String) Optional. GDispatcher specific feature. Only needed if the listener has been subscribed with a handler function.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method removeAllEventListeners
+	* @description 	GDispatcher specific feature. Removes all listeners for a specific event, or for all events.
+	* 		
+	* @usage   <pre>myInstance.removeAllEventListeners();</pre>
+	* 		    <pre>myInstance.removeAllEventListeners(event);</pre>
+	* 	  
+	*@param event (String) Event to remove all subscribed listeners from. If not specified, all listeners to any event will be removed.
+	*/
+	
+	/*inherited from APCore*/
+	/**
+	* @method eventListenerExists
+	* @description 	GDispatcher specific feature. Checks if a listener is already subscribed to a certain event.
+	* 		
+	* @usage   <pre>myInstance.eventListenerExists(event, listener);</pre>
+	* 			<pre>myInstance.eventListenerExists(event, listener, handler);</pre>
+	* 	  
+	*@param event (String) Event to check subscription.
+	*@param listener (Object) The listener object to check subscription.
+	*@param handler (String) The handler function to check subscription.	
+	*@returns <code>true</code> if event exists on listener. 
+	*                  <code>false</code> if event doesn't exist on listener. 
+	*/	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "SingleAnimator";
+	}	
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/SingleAnimator.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Text.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Text.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Text.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,199 @@
+import de.alex_uhlmann.animationpackage.APCore;
+
+/**
+* @class Text
+* @author Alex Uhlmann
+* @description  Easy way to setup textfield movieclips. Besides the examples of the Text class, there are 
+* 				more examples using Text in the class documentation of Sequence and MoveOnCurve.
+* @usage <tt>var myText:Text = new Text();</tt> 
+*/
+class de.alex_uhlmann.animationpackage.utility.Text extends APCore {	
+	
+	/** 
+	* @property movieclip (MovieClip) Movieclip that contains the textfield.
+	* @property style (TextFormat) Instance of TextFormat object. See Flash docs for further information.
+	*/
+	private var m_style:TextFormat;
+	private var mc:MovieClip;
+	
+	public function Text() {		
+		super.init(true);
+	}
+		
+	/**
+	* @method getText
+	* @description 	returns the textfield instance of a textfield movieclip.
+	* 			<p>
+	* 			Example 1: outputs by default apContainer_mc location: 
+	* 						"_level0.apContainer_mc.apText0_mc.apText0_txt"
+	* 			<blockquote><pre>			
+	*			var myText:Text = new Text();
+	*			txt_mc = myText.setText("Hello World");
+	*			trace(myText.getText());
+	* 			</pre></blockquote>
+	* 			Example 2: You can also send a textfield movieclip as a parameter to output 
+	* 			the containing textfield. 
+	* 			<blockquote><pre>
+	*			myText.getText(someOtherText_mc)
+	* 			</pre></blockquote>
+	* 
+	* @usage   <pre>myText.getText();</pre>
+	*		<pre>myText.getText(text_mc);</pre>
+	* 	  
+	* @param text_mc (MovieClip) Textfield movieclip made with AnimationPackage.	
+	* @return TextField
+	*/	
+	public function getText(mc:MovieClip):TextField {		
+		if(mc == null) {
+			mc = this.mc;
+		}
+		return mc.txtfield;
+	}
+		
+	/**
+	* @method setText
+	* @description 	create a textfield movieclip. You can easily animate textfield movieclips 
+	* 			since they are only textfields inside movieclips. All textfields will be centered 
+	* 			inside their movieclip.
+	* 			<p>
+	* 			Example 1: Create a textfield, positioned at 0,0.
+	* 			<blockquote><pre>			
+	*			var myText:Text = new Text();
+	*			myText.setText("Hello World");
+	*			</pre></blockquote>
+	* 			Example 2: create and format a textfield, using an embeded font. Note: you need to 
+	* 			create a font symbol in your library and name the identifier to "arialblack".
+	* 			<blockquote><pre>
+	* 			var myTF:TextFormat = new TextFormat();
+	*			myTF.font = "arialblack";
+	*			myTF.color = 0xff0000;
+	*			myTF.size = 20;
+	*			var myText:Text = new Text();
+	*			myText.setText("Hello World", 100, 100, myTF);
+	* 			</pre></blockquote>
+	* 			Example 3: Same like above, just using the setter properties.
+	* 			<blockquote><pre>
+	* 			var myTF:TextFormat = new TextFormat();
+	*			myTF.font = "arialblack";
+	*			myTF.color = 0xff0000;
+	*			myTF.size = 20;
+	*			var myText:Text = new Text();
+	*			myText.style = myTF;
+	*			myText.setText("Hello World",100,100);
+	* 			</pre></blockquote>
+	* 
+	* @usage   <pre>myText.setText(txt);</pre>
+	*		<pre>myText.setText(txt, x, y);</pre>
+	* 		<pre>myText.setText(txt, x, y, style);</pre>
+	* 	  
+	* @param txt (String) Text to be displayed in the textfield.
+	* @param x (Number) Coordinate point. Defaults to 0.
+	* @param y (Number) Coordinate point. Defaults to 0.
+	* @param style (TextFormat) Instance of TextFormat object. See Flash docs for further information.
+	* @return MovieClip
+	*/
+	public function setText(txt:String, x:Number, y:Number, style:TextFormat):MovieClip {
+		if(txt == null) {
+			txt = "";
+		}
+		if(x == null) {
+			x = 0;
+		}
+		if(y == null) {
+			y = 0;
+		}
+		if(style != null) {
+			this.style = style;
+		}		
+		this.mc = this.createClip({name:"apDraw"});
+		/*Flash Player 7 feature disabled*/
+		//var depth:Number = this.mc.getNextHighestDepth();			
+		var depth:Number = this.getNextDepth(this.mc);	
+		this.mc.createTextField("apText"+depth+"_txt", depth, 0, 0, 0, 0);
+		this.mc.txtfield = this.mc["apText"+depth+"_txt"];	
+		this.mc.txtfield.autoSize = "left";
+		this.mc.txtfield.selectable = false;	
+		this.mc.txtfield.text = txt;
+		if (this.style != null) {			
+			this.mc.txtfield.setTextFormat(this.style);
+			this.mc.txtfield.embedFonts = true;
+		}
+		var halfWidth:Number = this.mc._width / 2;
+		var halfHeight:Number = this.mc._height / 2;	
+		this.mc.txtfield._x -= halfWidth;
+		this.mc.txtfield._y -= halfHeight;		
+		this.mc._x = x + halfWidth;
+		this.mc._y = y + halfHeight;
+		return this.mc;
+	}
+	
+	/**
+	* @method updateText
+	* @description 	updates the text inside an already via setText() created textfield 
+	* 			movieclip. (like yourTextfield.text = txt)
+	* 
+	* @usage   <pre>myText.updateText(txt);</pre>
+	* 	  
+	* @param txt (String) Text to be displayed in the textfield.
+	*/	
+	public function updateText(txt:String):Void {
+		this.mc.txtfield.text = txt;
+	}
+	
+	/**
+	* @method addText
+	* @description 	adds a text inside an already via setText() created textfield 
+	* 			movieclip. (like yourTextfield.text += txt)
+	* 
+	* @usage   <pre>myText.addText(txt);</pre>
+	* 	  
+	* @param txt (String) Text to be displayed in the textfield.
+	*/	
+	public function addText(txt:String):Void {
+		this.mc.txtfield.text += txt;
+	}
+	
+	/**
+	* @method clearText
+	* @description 	clears a text inside an already via setText() created textfield 
+	* 			movieclip. (like yourTextfield.text = "")
+	* 
+	* @usage   <pre>myText.clearText();</pre>
+	*/	
+	public function clearText(Void):Void {
+		this.mc.txtfield.text = "";
+	}	
+	
+	public function get movieclip():MovieClip {
+		return this.mc;
+	}
+	
+	public function set movieclip(mc:MovieClip):Void {
+		this.mc = mc;
+	}	
+	
+	public function get style():TextFormat {
+                return this.m_style;
+	}
+        
+	public function set style(style:TextFormat):Void {
+                this.m_style = style;
+	}	
+	
+	/**
+	* @method getID
+	* @description 	returns a unique ID of the instance. Usefull for associative arrays.
+	* @usage   <tt>myInstance.getID();</tt>
+	* @return Number
+	*/
+	
+	/**
+	* @method toString
+	* @description 	returns the name of the class.
+	* @usage   <tt>myInstance.toString();</tt>
+	* @return String
+	*/	
+	public function toString(Void):String {
+		return "Text";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Text.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TimeTween.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TimeTween.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TimeTween.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,138 @@
+import de.alex_uhlmann.animationpackage.utility.Tween;
+
+/*
+* @class TimeTween
+* @author Alex Uhlmann
+* @description  Time-based tween engine. 
+* 				
+*/
+class de.alex_uhlmann.animationpackage.utility.TimeTween extends Tween {		
+	
+	private static var activeTweens:Array = new Array();
+	private static var interval:Number = 10;
+	private static var startPauseAll:Number;	
+	private static var intervalID : Number;
+	private static var dispatcher : Object = new Object();
+	
+	private static function addTween(tween:TimeTween):Void {
+		tween.id = activeTweens.length;
+		activeTweens.push(tween);	
+		if (intervalID == null) {
+			dispatcher.dispatchTweens = dispatch;
+			TimeTween.intervalID = setInterval(TimeTween.dispatcher, "dispatchTweens", TimeTween.interval);
+		}		
+	}
+	
+	private static function removeTweenAt(index:Number):Void {
+		var tweens:Array = TimeTween.activeTweens;
+
+		if(index >= tweens.length || index < 0 || index == null) {				
+			return;
+		}
+		
+		tweens.splice(index, 1);
+		var i:Number;
+		var len:Number = tweens.length;
+		for (i = index; i < len; i++) {
+			tweens[i].id--;
+		}
+		if (len == 0) {
+			clearInterval(intervalID);
+			delete intervalID;
+		}
+	}
+	
+	private static function dispatch(Void):Void {
+		var tweens:Array = TimeTween.activeTweens;
+		var i:Number;
+		var len:Number = tweens.length;		
+		for (i = 0; i < len; i++) { 
+			tweens[i].doInterval();
+		}
+		updateAfterEvent();
+	}
+	
+	public static function pauseAll():Void {
+		TimeTween.startPauseAll = getTimer();
+		clearInterval(TimeTween.intervalID);
+		var tweens:Array = TimeTween.activeTweens;
+		var i:Number = tweens.length;
+		while(--i > -1) {
+			tweens[i].isTweening = false;
+		}
+	}
+	
+	public static function resumeAll():Void {		
+		TimeTween.intervalID = setInterval(TimeTween.dispatcher, "dispatchTweens", TimeTween.interval);
+		var tweens:Array = TimeTween.activeTweens;
+		var i:Number;
+		var len:Number = tweens.length;
+		for (i = 0; i < len; i++) {
+			var myTween:TimeTween = tweens[i];
+			if( !myTween.isTweening ) {
+				myTween.startTime += (getTimer() - TimeTween.startPauseAll);
+			}
+			myTween.isTweening = true;
+		}
+	}
+	
+	public function TimeTween(listener:Object, 
+							  start:Object, end:Object, duration:Number, 
+							  easingParams:Array) {
+		
+		super(listener, start, end, duration, easingParams);		
+	}	
+
+	public function start():Void {	
+		if(easingEquation == null) {
+			easingEquation = defaultEasingEquation;
+		}
+		startTime = getTimer();
+		if (this.duration == 0) {
+			endTween();
+		} else {
+			TimeTween.addTween(this);
+		}
+		this.isTweening = true;
+	}
+	
+	public function stop():Void {		
+		TimeTween.removeTweenAt(this.id);
+		this.isTweening = false;
+	}
+	
+	public function pause():Void {		
+		this.startPause = getTimer();
+		delete TimeTween.activeTweens[this.id];
+		this.isTweening = false;
+	}
+	
+	public function resume():Void {
+		this.startTime += (getTimer() - startPause);		
+		TimeTween.activeTweens[this.id] = this;
+		this.isTweening = true;
+	}
+	
+	public function doInterval():Void {
+		var curTime:Number = getTimer() - startTime;
+		var curVal:Object;
+		if(easingParams == null) {
+			curVal = getCurVal(curTime);
+		} else {
+			curVal = getCurVal2(curTime);
+		}
+		if (curTime >= duration) {			
+			endTween(curVal);
+		} else {
+			if (updateMethod != null) {
+				listener[updateMethod](curVal);
+			} else {
+				listener.onTweenUpdate(curVal);
+			}
+		}
+	}
+	
+	public function toString(Void):String {
+		return "TimeTween";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TimeTween.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Tween.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Tween.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Tween.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,114 @@
+
+/*
+* @class Tween
+* @author Alex Uhlmann
+* @description  Base class for time based and frame based tween engines. 	
+*/
+dynamic class de.alex_uhlmann.animationpackage.utility.Tween {		
+
+	public var listener:Object;
+	//startValue and endValue need to support Number and Array values.
+	public var startValue:Object;
+	public var endValue:Object;
+	public var duration:Number = 1000;
+	public var easingEquation:Function;
+	public var updateMethod:String;
+	public var endMethod:String;
+	public var arrayMode:Boolean = false;
+	public var id:Number;
+	public var easingParams:Array;
+	public var lastVal:Number;
+	public var startTime:Number;
+	public var isTweening:Boolean;
+	public var isPaused:Boolean;
+	public var stop:Function;
+	private var startPause:Number;	
+	
+	public function Tween(listener:Object, 
+						startValue:Object, endValue:Object, duration:Number, 
+						easingParams:Array) {			
+		
+		if(listener == null ) {
+			return;
+		}
+		if (typeof(startValue) != "number") {
+			arrayMode = true;
+		}
+
+		this.listener = listener;
+		
+		this.startValue = startValue;
+		this.endValue = endValue;
+		if(duration != null) {
+			this.duration = duration;
+		}
+		this.easingParams = easingParams;
+		this.isTweening = false;
+		this.isPaused = false;
+	}
+	
+	public function getCurVal(curTime:Number):Object {
+		if (arrayMode) {
+			var returnArray:Array = new Array();
+			var i:Number;
+			var len:Number = startValue.length;
+			for (i = 0; i < len; i++) {
+				returnArray[i] = easingEquation(curTime, 
+												startValue[i], 
+												endValue[i] - startValue[i], 
+												duration);
+			}
+			return returnArray;
+		}
+		else {
+			return easingEquation(curTime, 
+								  startValue, 
+								  Number(endValue) - Number(startValue), 
+								  duration);		
+		}
+	}		
+	
+	public function getCurVal2(curTime:Number):Object {
+		if (arrayMode) {
+			var returnArray:Array = new Array();
+			var i:Number;
+			var len:Number = startValue.length;
+			for (i = 0; i < len; i++) {	
+				returnArray[i] = easingEquation.apply(null, [curTime, 
+															 startValue[i], 
+															 endValue[i] - startValue[i], 
+															 duration].concat(this.easingParams));
+			}
+			return returnArray;
+		}
+		else {			
+			return easingEquation.apply(null, [curTime, 
+											   startValue, 
+											   Number(endValue) - Number(startValue), 
+											   duration].concat(this.easingParams));
+		}
+	}
+	
+	public function setTweenHandlers(update:String, endValue:String):Void {
+		updateMethod = update;
+		endMethod = endValue;
+	}
+	
+	//defaults to sin
+	public function defaultEasingEquation(t:Number, b:Number, c:Number, d:Number):Number {
+		return c/2 * ( Math.sin( Math.PI * (t/d-0.5) ) + 1 ) + b;
+	}
+	
+	private function endTween(v:Object):Void {
+		if (endMethod != null) {
+			listener[endMethod](v);
+		} else {
+			listener.onTweenEnd(v);
+		}
+		this.stop();
+	}	
+
+	public function toString(Void):String {
+		return "Tween";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/Tween.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TweenAction.as
===================================================================
--- z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TweenAction.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TweenAction.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,325 @@
+import de.alex_uhlmann.animationpackage.APCore;
+import de.alex_uhlmann.animationpackage.utility.Animator;
+
+/*
+* @class TweenAction
+* @author Alex Uhlmann
+* @description  Class that handles callbacks of the mx.effects.Tween and 
+* 				de.alex_uhlmann.animationpackage.utility.FrameTween. 
+* 				See Animator class for more details.  
+*/
+
+class de.alex_uhlmann.animationpackage.utility.TweenAction {		
+
+	private var scope:Object;
+	private var targetStr:String;
+	private var identifier:Function;
+	private var ref:Animator;
+	private var len:Number;
+	/*relaxed type to accommodate numbers or arrays*/
+	private var initVal:Object;
+	private var endVal:Object;
+	private var singleMode:Boolean;
+
+	public function TweenAction(ref:Animator, startVal:Object, endVal:Object) {
+		this.ref = ref;
+		this.initVal = initVal;
+		this.endVal = endVal;		
+	}	
+		
+	public function initSingleMode(scope:Object, targetStr:String, identifier:Function):Void {
+		this.scope = scope;
+		this.targetStr = targetStr;
+		this.identifier = identifier;
+		this.singleMode = true;	
+	}
+	
+	public function initMultiMode(len:Number):Void {
+		this.scope = scope;
+		this.targetStr = targetStr;
+		this.identifier = identifier;
+		this.len = len;
+		this.singleMode = false;
+	}	
+	
+	/* Optimized, less readable code. See m */
+	public function o(v:Number):Void {		
+		var p:Object = this.scope;
+		var t:String = this.targetStr;
+		var f:Function = this.identifier;
+		if(typeof(f) != "number") {
+			p[t](v);
+		} else {
+			p[t] = v;
+		}
+		var r:Object = this.ref;	
+		r.caller.currentValue = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}
+	
+	/*onTweenUpdateOnce with rounded values to integers*/
+	public function o2(v:Number):Void {		
+		var p:Object = this.scope;
+		var t:String = this.targetStr;
+		var f:Function = this.identifier;		
+		v = Math.round(v);
+		if(typeof(f) != "number") {
+			p[t](v);
+		} else {
+			p[t] = v;			
+		}
+		var r:Object = this.ref;	
+		r.caller.currentValue = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}
+	
+	/* Optimized, less readable code.
+	* o = onTweenUpdateOnce
+	* m = onTweenUpdateMulitple
+	* r = reference to Animator class.
+	* s = setter: (Array) setter property from Animator class.
+	* p = object, scope: first element of setter property from Animator class.
+	* t = targetString: second element of setter property from Animator class.
+	* f = function: identifier. Combination of o and t. 
+	* v = value parameter.
+	* u = onUpdateOnce
+	* w = onUpdateMultiple
+	*/	
+	public function m(v:Array):Void {		
+		var r:Object = this.ref;
+		var s:Array = r.setter;
+		var p:Object;
+		var t:String;
+		var f:Function;
+		var i:Number = this.len;
+		while(--i>-1) {
+			p = s[i][0];
+			t = s[i][1];
+			f = p[t];			
+			if(typeof(f) != "number") {
+				p[t](v[i]);
+			} else {
+				p[t] = v[i];
+			}		
+		}
+		r.caller.currentValues = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}
+	
+	/*onTweenUpdateMultiple with rounded values to integers*/
+	public function m2(v:Number):Void {		
+		var r:Object = this.ref;
+		var s:Array = r.setter;
+		var p:Object;
+		var t:String;
+		var f:Function;
+		var i:Number = this.len;
+		var m:Function = Math.round;
+		while(--i>-1) {
+			v[i] = m(v[i]);
+			p = s[i][0];
+			t = s[i][1];
+			f = p[t];			
+			if(typeof(f) != "number") {
+				p[t](v[i]);
+			} else {
+				p[t] = v[i];
+			}		
+		}
+		r.caller.currentValues = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}
+	
+	
+	
+	
+	
+	
+	
+	/* 
+	* Same functions as above, just one row for methods only and one row for properties only. 
+	* For the sake of higher performance.
+	*/	
+	//for properties only
+	public function op(v:Number):Void {	
+		var p:Object = this.scope;
+		var t:String = this.targetStr;			
+		p[t] = v;
+		var r:Object = this.ref;	
+		r.caller.currentValue = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}	
+	
+	public function o2p(v:Number):Void {		
+		var p:Object = this.scope;
+		var t:String = this.targetStr;	
+		v = Math.round(v);
+		p[t] = v;
+		var r:Object = this.ref;	
+		r.caller.currentValue = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}	
+
+	public function mp(v:Array):Void {		
+		var r:Object = this.ref;
+		var s:Array = r.setter;
+		var i:Number = this.len;
+		while(--i>-1) {
+			s[i][0][s[i][1]] = v[i];			
+		}
+		r.caller.currentValues = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}
+	
+	public function m2p(v:Array):Void {		
+		var r:Object = this.ref;
+		var s:Array = r.setter;
+		var i:Number = this.len;
+		var m:Function = Math.round;
+		while(--i>-1) {
+			v[i] = m(v[i]);
+			s[i][0][s[i][1]] = v[i];		
+		}
+		r.caller.currentValues = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}	
+	
+	//for methods only
+	public function om(v:Number):Void {
+		var p:Object = this.scope;
+		var t:String = this.targetStr;		
+		p[t](v);
+		var r:Object = this.ref;	
+		r.caller.currentValue = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});		
+	}	
+	
+	public function o2m(v:Number):Void {		
+		var p:Object = this.scope;
+		var t:String = this.targetStr;	
+		v = Math.round(v);	
+		p[t](v);
+		var r:Object = this.ref;	
+		r.caller.currentValue = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}	
+
+	public function mm(v:Array):Void {		
+		var r:Object = this.ref;
+		var s:Array = r.setter;
+		var i:Number = this.len;
+		while(--i>-1) {
+			s[i][0][s[i][1]](v[i]);
+		}
+		r.caller.currentValues = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}
+	
+	public function m2m(v:Array):Void {		
+		var r:Object = this.ref;
+		var s:Array = r.setter;
+		var i:Number = this.len;
+		var m:Function = Math.round;
+		while(--i>-1) {
+			v[i] = m(v[i]);
+			s[i][0][s[i][1]](v[i]);
+		}
+		r.caller.currentValues = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}
+	
+	
+	
+	
+	public function mu(v:Array):Void {		
+		var r:Object = this.ref;
+		var s:Array = r.setter;
+		var p:Object;
+		var t:String;
+		var f:Function;
+		p = s[0][0];
+		t = s[0][1];
+		f = p[t];
+		f.apply(p,v);
+		r.caller.currentValues = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}	
+	
+	public function mu2(v:Array):Void {		
+		var r:Object = this.ref;
+		var s:Array = r.setter;
+		var p:Object;
+		var t:String;
+		var f:Function;		
+		var i:Number = this.len;
+		var m:Function = Math.round;
+		while(--i>-1) {
+			v[i] = m(v[i]);
+		}
+		p = s[0][0];
+		t = s[0][1];
+		f = p[t];	
+		f.apply(p,v);
+		r.caller.currentValues = v;
+		r.caller["dispatchEvent"]({type:"onUpdate", target: r.caller, value: v});
+	}	
+	
+	/* Optimized, less readable code.	
+	* e = onTweenEnd
+	*/	
+	public function e(v):Void {		
+		var r:Object = this.ref;
+		/*
+		* It is possible that time based tweening does not 
+		* reach the exact end value of the animation child.
+		* If the forceEndVal property is true (default), TweenAction will 
+		* invoke the update function again to force the end value.
+		*/
+		if(r.caller.forceEndVal) {
+			v = this.endVal;
+			this[r.myTween.updateMethod](v);			
+		} else {
+			if(this.singleMode) {
+				/*
+				* check for closest value to be as precise as possible:
+				* v = current value not set.
+				* ev = targeted value. end value in theory.
+				* r.caller.currentValue = current value, last value set.
+				* if the overshoot (v - ev) is smaller 
+				* than the difference between the targeted value 
+				* and the last value set, than set the overshoot.
+				* Otherwise go with the last value set.
+				*/
+				var ev = this.endVal;
+				if((v - ev) < (ev - r.caller.currentValue)) {
+					this[r.myTween.updateMethod](v);
+					v = r.caller.currentValue;
+				} else {
+					if(r.caller.rounded) {						
+						v = Math.round(r.caller.currentValue);
+					} else {
+						v = r.caller.currentValue;
+					}			
+				}
+			} else {
+				/*
+				* for multiple values we always set the last value set 
+				* as end value.
+				*/
+				v = r.caller.currentValue;
+			}		
+		}
+		
+		r.deleteAnimation();
+		
+		/*invoke the callback through all listeners*/
+		r.caller.tweening = false;
+		r.finished = true;
+		APCore.broadcastMessage(r.callback, r.caller, v);
+		r.caller["dispatchEvent"]({type:"onEnd", target:r.caller, value: v});
+	}
+
+	public function toString(Void):String {
+		return "TweenAction";
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/alex_uhlmann/animationpackage/utility/TweenAction.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/andre_michelle/events/FrameBasedInterval.as
===================================================================
--- z3c.reference/trunk/flash/src/de/andre_michelle/events/FrameBasedInterval.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/andre_michelle/events/FrameBasedInterval.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,79 @@
+import de.andre_michelle.events.*;
+
+class de.andre_michelle.events.FrameBasedInterval
+{
+	static public var m_frame: Number = 0;
+	static private var intervals: Array;
+
+	public static function get frame(): Number
+	{
+		return m_frame;
+	}
+
+	static function addInterval( object: Object, method: String , intervalLength: Number ): Object
+	{
+		if ( intervals == undefined )
+		{
+			intervals = new Array();
+			startMonitoring();
+		}
+
+		var interval: Object = {
+
+			object: object,
+			method: method,
+			intervalLength: intervalLength,
+			args: arguments.splice( 3 ),
+			startFrame: m_frame
+		};
+
+		intervals.push( interval );
+
+		return interval;
+	}
+
+	static function removeInterval( interval ): Boolean
+	{
+		var i: String;
+		for ( i in intervals )
+		{
+			if ( intervals[i] == interval )
+			{
+				intervals.splice( Number(i) , 1 );
+				if ( intervals.length == 0 )
+				{
+					delete intervals;
+					stopMonitoring();
+				}
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	static private function startMonitoring(): Void
+	{
+		ImpulsDispatcher.addImpulsListener( FrameBasedInterval , 'checkFrame' );
+	}
+
+	static private function stopMonitoring(): Void
+	{
+		ImpulsDispatcher.removeImpulsListener( FrameBasedInterval );
+	}
+
+	static function checkFrame(): Void
+	{
+		++m_frame;
+		var i: String;
+		for ( i in intervals )
+		{
+			var interval = intervals[i];
+			if ( ( m_frame - interval.startFrame ) % interval.intervalLength == 0 )
+			{
+				var o = interval.object;
+				o[ interval.method ].apply( o , interval.args );
+			}
+		}
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/andre_michelle/events/FrameBasedInterval.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/de/andre_michelle/events/ImpulsDispatcher.as
===================================================================
--- z3c.reference/trunk/flash/src/de/andre_michelle/events/ImpulsDispatcher.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/de/andre_michelle/events/ImpulsDispatcher.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,106 @@
+class de.andre_michelle.events.ImpulsDispatcher
+{
+	static var _listeners: Array;
+	static var _timeline: MovieClip;
+	static var timer: Number;
+	static var frames: Number;
+	static var fps: Number;
+	static var fpsInterval: Number;
+	
+	static function initialize ( timeline: MovieClip ): Void
+	{		
+		if ( _timeline ) decontrol();
+		pause();
+		_listeners = new Array();
+		timer = getTimer();
+		_timeline = timeline;
+	}
+
+	static function decontrol( timeline: MovieClip ): Void
+	{
+		_global.ASSetPropFlags( timeline , "onEnterFrame" , 0 , 7 );
+		delete timeline.onEnterFrame;
+		delete _listeners;
+		delete _timeline;
+		delete timer;
+	}
+
+	static function watchFPS(): Void
+	{
+		fpsInterval = setInterval( function(){ ImpulsDispatcher.fps = ImpulsDispatcher.frames; ImpulsDispatcher.frames = 0; } , 1000 );
+		addImpulsListener( ImpulsDispatcher , 'countFrames' );
+		frames = 0;		
+	}
+
+	static function unwatchFPS(): Void
+	{
+		clearInterval( fpsInterval );
+		removeImpulsListener( ImpulsDispatcher );
+		fps = undefined;
+	}
+
+	static function getFPS(): Number
+	{		
+		if ( fps == undefined ) return 0;
+		return fps;
+	}
+
+	static function countFrames(): Void
+	{		
+		++frames;		
+	}
+
+	static function pause(): Void
+	{
+		_global.ASSetPropFlags( _timeline , "onEnterFrame" , 0 , 7 );
+		delete _timeline.onEnterFrame;
+		_global.ASSetPropFlags( _timeline , "onEnterFrame" , 7 );
+		fps = undefined;
+	}
+
+	static function resume(): Void
+	{		
+		if ( _listeners.length == 0 ) return;
+		_global.ASSetPropFlags( _timeline , "onEnterFrame" , 0 , 7 );
+		_timeline.onEnterFrame = ImpulsDispatcher.onImpuls;
+		_global.ASSetPropFlags( _timeline , "onEnterFrame" , 7 );
+		timer = getTimer();
+		frames = 0;
+	}
+
+	static function addImpulsListener( handler , callback: String ): Void
+	{		
+		_listeners.push( { o: handler, c: callback } );
+		if ( _listeners.length == 1 ) resume();
+	}
+
+	static function removeImpulsListener( handler ): Boolean
+	{
+		var l: String;
+		var listener;
+		for ( l in _listeners )
+		{
+			listener = _listeners[ l ];
+			if ( listener.o == handler )
+			{
+				_listeners.splice( Number(l) , 1 );
+				if ( _listeners.length == 0 ) pause();
+				return true;
+			}
+		}
+		return false;
+	}
+
+	static function onImpuls(): Void
+	{		
+		var delta_t: Number = ( getTimer() - timer ) / 1000;
+		timer = getTimer();
+		var l: String;
+		var listener;
+		for ( l in _listeners )
+		{
+			listener = _listeners[ l ];
+			listener.o[ listener.c ]( delta_t );
+		}
+	}
+}
\ No newline at end of file


Property changes on: z3c.reference/trunk/flash/src/de/andre_michelle/events/ImpulsDispatcher.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/org/dembicki/Path.as
===================================================================
--- z3c.reference/trunk/flash/src/org/dembicki/Path.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/org/dembicki/Path.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,102 @@
+/*
+© Ivan Dembicki, 2004, dembicki at narod.ru
+please check updates: http://www.dembicki.org
+
+Path class 
+version 1.3
+version 1.2: http://www.dembicki.org/Path1_2.as
+version 1.1: http://www.dembicki.org/Path1_1.as
+version 1.0: http://www.dembicki.org/Path1_0.as
+*/
+class org.dembicki.Path {
+	var path_points:String = "", path_length:Number = 0;
+	var segments:Number = 0;
+	private var ln_array:Array = [];
+	function Path() {
+		var arg = typeof arguments[0] == "number" ? arguments : arguments[0];
+		this.path_points=arg.toString(), this.path_length=0;
+		var k = 0, i;
+		var len = arg.length;
+		var x0 = arg[0] || 0, y0 = arg[1] || 0, x1, y1, x2, y2, ln, o, a1, a2, a3, a4, a, b, c, d, e, a2t, sa;
+		for (i=2; i<len; i += 4) {
+			x1 = arg[i] || 0;
+			y1 = arg[i+1] || 0;
+			if (i == (len-2)) {
+				x2 = arg[i+2] ? arg[i+2] : (arg[0] || 0);
+				y2 = arg[i+3] ? arg[i+3] : (arg[1] || 0);
+			} else {
+				x2 = arg[i+2] || 0;
+				y2 = arg[i+3] || 0;
+			}
+			ln = this.ln_array[k++]=[{_y:y0, _x:x0}, {_y:y1, _x:x1}, {_y:y2, _x:x2}];
+			o = ln[3]={};
+			a1 = o.a1=x0-2*x1+x2;
+			a2 = o.a2=y0-2*y1+y2;
+			a3 = o.a3=x0-x1;
+			a4 = o.a4=y0-y1;
+			a = o.a=4*(a1*a1+a2*a2);
+			b = o.b=-8*(a1*a3+a2*a4);
+			c = o.c=4*(a3*a3+a4*a4);
+			e = o.e=Math.sqrt(c);
+			d = Math.sqrt(c+b+a);
+			sa = Math.sqrt(a);
+			a2t = a*2;
+			ln[4] = (2*sa*(d*(b+a2t)-e*b)+(b*b-4*a*c)*(Math.log(2*e+b/sa)-Math.log(2*d+(b+a2t)/sa)))/(8*Math.pow(a, (3/2)));
+			if (isNaN(ln[4])) {
+				var del = 100000;
+				arg[i] += Math.random()/del;
+				arg[i+1] += Math.random()/del;
+				arg[i+2] += Math.random()/del;
+				arg[i+3] += Math.random()/del;
+				arg[i+4] += Math.random()/del;
+				arg[i+5] += Math.random()/del;
+				i -= 4;
+				k--;
+			} else {
+				this.path_length += ln[4];
+				x0 = x2;
+				y0 = y2;
+			}
+		}
+		this.segments = k--;
+	}
+	public function getPoint(poz:Number, omit_rotation:Boolean) {
+		
+		//added
+		if (poz > this.path_length) {
+			poz = this.path_length;
+		} else if (poz < 0) {
+			poz = 0;
+		}
+		//end added
+		
+		poz = poz%this.path_length;
+		//poz<0 ? poz += this.path_length : "";
+		if(poz<0)poz += this.path_length;
+		if(!poz)poz += .00001;
+		if (this.segments<1) {
+			return false;
+		}
+		var i = 0, ln, len = 0, ff = 0;
+		for (i; i<=this.segments; i++) {
+			ln=this.ln_array[i], len += ln[4];
+			if (len>poz) {
+				ff = (poz-(len-ln[4]))/ln[4];
+				break;
+			}
+		}
+		var fn = function (ff) {
+			var o = ln[3], a1 = o.a1, a2 = o.a2, a3 = o.a3, a4 = o.a4, a = o.a, b = o.b, c = o.c, e = o.e, i = 1, st = 1, f_l = ln[4], t_l = ff*f_l, max_i = 100, d, sa, a2i;
+			while (max_i--) {
+				d=Math.sqrt(c+i*(b+a*i)), sa=Math.sqrt(a), a2i=a*2*i, f_l=(2*sa*(d*(b+a2i)-e*b)+(b*b-4*a*c)*(Math.log(2*e+b/sa)-Math.log(2*d+(b+a2i)/sa)))/(8*Math.pow(a, (3/2)));
+				if (Math.abs(f_l-t_l)<.000001) {
+					return i;
+				}
+				st /= 2, i += f_l<t_l ? st : f_l>t_l ? -st : 0;
+			}
+			return i;
+		};
+		var f = fn(ff), p0 = ln[0], p1 = ln[1], p2 = ln[2], e = 1-f, ee = e*e, ff = f*f, b = 2*f*e;
+		return omit_rotation ? {_x:p2._x*ff+p1._x*b+p0._x*ee, _y:p2._y*ff+p1._y*b+p0._y*ee} : {_x:p2._x*ff+p1._x*b+p0._x*ee, _y:p2._y*ff+p1._y*b+p0._y*ee, _rotation:Math.atan2(p0._y-p1._y+(2*p1._y-p0._y-p2._y)*f, p0._x-p1._x+(2*p1._x-p0._x-p2._x)*f)/(Math.PI/180)};
+	}
+}


Property changes on: z3c.reference/trunk/flash/src/org/dembicki/Path.as
___________________________________________________________________
Name: svn:executable
   + *

Added: z3c.reference/trunk/flash/src/org/json/Json.as
===================================================================
--- z3c.reference/trunk/flash/src/org/json/Json.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/org/json/Json.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,346 @@
+/*
+Copyright (c) 2005 JSON.org
+
+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 Software shall be used for Good, not Evil.
+
+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.
+*/
+
+/*
+ported to Actionscript May 2005 by Trannie Carter <tranniec at designvox.com>, wwww.designvox.com
+USAGE:
+	try {
+		var o:Object = JSON.parse(jsonStr);
+		var s:String = JSON.stringify(obj);
+	} catch(ex) {
+		trace(ex.name + ":" + ex.message + ":" + ex.at + ":" + ex.text);
+	}
+
+*/
+
+class org.json.Json {
+
+	static function stringify(arg):String {
+
+        var c, i, l, s = '', v;
+
+        switch (typeof arg) {
+        case 'object':
+            if (arg) {
+                if (arg instanceof Array) {
+                    for (i = 0; i < arg.length; ++i) {
+                        v = stringify(arg[i]);
+                        if (s) {
+                            s += ',';
+                        }
+                        s += v;
+                    }
+                    return '[' + s + ']';
+                } else if (typeof arg.toString != 'undefined') {
+                    for (i in arg) {
+                        v = arg[i];
+                        if (typeof v != 'undefined' && typeof v != 'function') {
+                            v = stringify(v);
+                            if (s) {
+                                s += ',';
+                            }
+                            s += stringify(i) + ':' + v;
+                        }
+                    }
+                    return '{' + s + '}';
+                }
+            }
+            return 'null';
+        case 'number':
+            return isFinite(arg) ? String(arg) : 'null';
+        case 'string':
+            l = arg.length;
+            s = '"';
+            for (i = 0; i < l; i += 1) {
+                c = arg.charAt(i);
+                if (c >= ' ') {
+                    if (c == '\\' || c == '"') {
+                        s += '\\';
+                    }
+                    s += c;
+                } else {
+                    switch (c) {
+                        case '\b':
+                            s += '\\b';
+                            break;
+                        case '\f':
+                            s += '\\f';
+                            break;
+                        case '\n':
+                            s += '\\n';
+                            break;
+                        case '\r':
+                            s += '\\r';
+                            break;
+                        case '\t':
+                            s += '\\t';
+                            break;
+                        default:
+                            c = c.charCodeAt();
+                            s += '\\u00' + Math.floor(c / 16).toString(16) +
+                                (c % 16).toString(16);
+                    }
+                }
+            }
+            return s + '"';
+        case 'boolean':
+            return String(arg);
+        default:
+            return 'null';
+        }
+    }
+
+	static function parse(text:String):Object {
+        var at = 0;
+        var ch = ' ';
+		var _value:Function;
+
+        var _error:Function = function (m) {
+            throw {
+                name: 'JSONError',
+                message: m,
+                at: at - 1,
+                text: text
+            };
+        }
+
+        var _next:Function = function() {
+            ch = text.charAt(at);
+            at += 1;
+            return ch;
+        }
+
+        var _white:Function = function() {
+            while (ch) {
+                if (ch <= ' ') {
+                    _next();
+                } else if (ch == '/') {
+                    switch (_next()) {
+                        case '/':
+                            while (_next() && ch != '\n' && ch != '\r') {}
+                            break;
+                        case '*':
+                            _next();
+                            for (;;) {
+                                if (ch) {
+                                    if (ch == '*') {
+                                        if (_next() == '/') {
+                                            _next();
+                                            break;
+                                        }
+                                    } else {
+                                        _next();
+                                    }
+                                } else {
+                                    _error("Unterminated comment");
+                                }
+                            }
+                            break;
+                        default:
+                            _error("Syntax error");
+                    }
+                } else {
+                    break;
+                }
+            }
+        }
+
+        var _string:Function = function() {
+            var i, s = '', t, u;
+			var outer:Boolean = false;
+
+            if (ch == '"') {
+				while (_next()) {
+                    if (ch == '"') {
+                        _next();
+                        return s;
+                    } else if (ch == '\\') {
+                        switch (_next()) {
+                        case 'b':
+                            s += '\b';
+                            break;
+                        case 'f':
+                            s += '\f';
+                            break;
+                        case 'n':
+                            s += '\n';
+                            break;
+                        case 'r':
+                            s += '\r';
+                            break;
+                        case 't':
+                            s += '\t';
+                            break;
+                        case 'u':
+                            u = 0;
+                            for (i = 0; i < 4; i += 1) {
+                                t = parseInt(_next(), 16);
+                                if (!isFinite(t)) {
+                                    outer = true;
+									break;
+                                }
+                                u = u * 16 + t;
+                            }
+							if(outer) {
+								outer = false;
+								break;
+							}
+                            s += String.fromCharCode(u);
+                            break;
+                        default:
+                            s += ch;
+                        }
+                    } else {
+                        s += ch;
+                    }
+                }
+            }
+            _error("Bad string");
+        }
+
+        var _array:Function = function() {
+            var a = [];
+
+            if (ch == '[') {
+                _next();
+                _white();
+                if (ch == ']') {
+                    _next();
+                    return a;
+                }
+                while (ch) {
+                    a.push(_value());
+                    _white();
+                    if (ch == ']') {
+                        _next();
+                        return a;
+                    } else if (ch != ',') {
+                        break;
+                    }
+                    _next();
+                    _white();
+                }
+            }
+            _error("Bad array");
+        }
+
+        var _object:Function = function() {
+            var k, o = {};
+
+            if (ch == '{') {
+                _next();
+                _white();
+                if (ch == '}') {
+                    _next();
+                    return o;
+                }
+                while (ch) {
+                    k = _string();
+                    _white();
+                    if (ch != ':') {
+                        break;
+                    }
+                    _next();
+                    o[k] = _value();
+                    _white();
+                    if (ch == '}') {
+                        _next();
+                        return o;
+                    } else if (ch != ',') {
+                        break;
+                    }
+                    _next();
+                    _white();
+                }
+            }
+            _error("Bad object");
+        }
+
+        var _number:Function = function() {
+            var n = '', v;
+
+            if (ch == '-') {
+                n = '-';
+                _next();
+            }
+            while (ch >= '0' && ch <= '9') {
+                n += ch;
+                _next();
+            }
+            if (ch == '.') {
+                n += '.';
+                while (_next() && ch >= '0' && ch <= '9') {
+                    n += ch;
+                }
+            }
+            //v = +n;
+			v = 1 * n;
+            if (!isFinite(v)) {
+                _error("Bad number");
+            } else {
+                return v;
+            }
+        }
+
+        var _word:Function = function() {
+            switch (ch) {
+                case 't':
+                    if (_next() == 'r' && _next() == 'u' && _next() == 'e') {
+                        _next();
+                        return true;
+                    }
+                    break;
+                case 'f':
+                    if (_next() == 'a' && _next() == 'l' && _next() == 's' &&
+                            _next() == 'e') {
+                        _next();
+                        return false;
+                    }
+                    break;
+                case 'n':
+                    if (_next() == 'u' && _next() == 'l' && _next() == 'l') {
+                        _next();
+                        return null;
+                    }
+                    break;
+            }
+            _error("Syntax error");
+        }
+
+        _value = function() {
+            _white();
+            switch (ch) {
+                case '{':
+                    return _object();
+                case '[':
+                    return _array();
+                case '"':
+                    return _string();
+                case '-':
+                    return _number();
+                default:
+                    return ch >= '0' && ch <= '9' ? _number() : _word();
+            }
+        }
+
+        return _value();
+    }
+}

Modified: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Canvas.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Canvas.as	2007-09-18 09:01:27 UTC (rev 79731)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Canvas.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -14,14 +14,14 @@
     private var height:Number = 1;
     
     private var border_mc:MovieClip;
-    private var mask_mc:MovieClip;
+    private var mask_arr:Array;
     
 	function Canvas()
 	{
         super();
         
         createEmptyMovieClip("border_mc", getNextHighestDepth());
-        createEmptyMovieClip("mask_mc", getNextHighestDepth());
+        mask_arr = new Array();
         
         var shadow = new flash.filters.DropShadowFilter(3);
         filters = [shadow];
@@ -41,18 +41,26 @@
         border_mc.lineTo(0, height);
         border_mc.endFill();
 
-        mask_mc.clear();
-        mask_mc.lineStyle(0, 0x000000, 100);
-        mask_mc.beginFill(0x000000, 0);
-        mask_mc.moveTo(1, 1);
-        mask_mc.lineTo(width, 1);
-        mask_mc.lineTo(width, height);
-        mask_mc.lineTo(1, height);
-        mask_mc.endFill();
+        for (var i = 0; i < mask_arr.length; i++)
+        {
+            var mask_mc = mask_arr[i];
+            mask_mc.clear();
+            mask_mc.lineStyle(0, 0x000000, 100);
+            mask_mc.beginFill(0x000000, 0);
+            mask_mc.moveTo(1, 1);
+            mask_mc.lineTo(width, 1);
+            mask_mc.lineTo(width, height);
+            mask_mc.lineTo(1, height);
+            mask_mc.endFill();
+        }
     }
     
     public function getMask()
     {
+        var nextDepth = getNextHighestDepth();
+        var mask_mc = createEmptyMovieClip("mask_mc_" + nextDepth, nextDepth);
+        mask_arr.push(mask_mc);
+        
         return mask_mc;
     }
 

Modified: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Controller.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Controller.as	2007-09-18 09:01:27 UTC (rev 79731)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Controller.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -17,87 +17,145 @@
 [Event("onRotateRightRelease")]
 [Event("onAcceptRelease")]
 [Event("onAbortRelease")]
+[Event("onSliderPress")]
+[Event("onSliderRelease")]
+[Event("onSliderChange")]
+[Event("onViewportRatioChange")]
 
 
 class z3c.reference.imagetool.baseskin.Controller extends Component
 {
     private var PADDING:Number = 20;
     
-	private var menuDrag_mc:MovieClip;
-	private var zoomIn_mc:MovieClip;
-	private var zoomOut_mc:MovieClip;
+	public var buttons_mc:MovieClip;
 	private var rotateLeft_mc:MovieClip;
 	private var rotateRight_mc:MovieClip;
-	private var menuAbort_mc:MovieClip;
-	private var menuAccept_mc:MovieClip;
-	private var cropsize_mc:MovieClip; //movieclip holding the textfields for manual size input
+	private var slider_mc:MovieClip;
 	private var outputsize_mc:MovieClip;
+	private var canvas_mc:MovieClip;
+
+	private var dropdown_container_mc:MovieClip;    // contains the dropdown component
+	private var dropdown_mc:MovieClip;              // reference to the dropdown component
 	
-	private var bg_mc:MovieClip;
 	
 	function Controller()
 	{
-		trace("Menu Initialized");
+	    attachMovie("canvas_mc", "canvas_mc", getNextHighestDepth());
+	    createEmptyMovieClip("buttons_mc", getNextHighestDepth());
+	    buttons_mc.setMask(canvas_mc.getMask());
 		
-		bg_mc._width=Stage.width;
-		bg_mc._height=50;
-		var shadow = new flash.filters.DropShadowFilter(3);
-        bg_mc.filters = [shadow];
+		rotateLeft_mc = buttons_mc.attachMovie("rotateLeft_mc", "rotateLeft_mc", buttons_mc.getNextHighestDepth());
+		rotateLeft_mc.onRelease = function() { _parent._parent.broadcastEvent(new EventInfo(_parent._parent, "onRotateLeftRelease")); }
 
-		menuDrag_mc.onPress = function() { _parent.startDrag(false); }		
-		menuDrag_mc.onRelease = function() { _parent.stopDrag(); }
+		rotateRight_mc = buttons_mc.attachMovie("rotateRight_mc", "rotateRight_mc", buttons_mc.getNextHighestDepth());
+		rotateRight_mc.onRelease = function() { _parent._parent.broadcastEvent(new EventInfo(_parent._parent, "onRotateRightRelease")); }
 		
-		zoomIn_mc.onPress = function() { _parent.broadcastEvent(new EventInfo(_parent, "onZoomInPress")); }
-		zoomIn_mc.onRelease =  this.zoomIn_mc.onReleaseOutside = function() { _parent.broadcastEvent(new EventInfo(_parent, "onZoomInRelease")); }
+		slider_mc = buttons_mc.attachMovie("slider_mc", "slider_mc", buttons_mc.getNextHighestDepth(), {width: 100});
+		slider_mc.addListener(this);
 		
-		zoomOut_mc.onPress = function() { _parent.broadcastEvent(new EventInfo(_parent, "onZoomOutPress")); }
-		zoomOut_mc.onRelease = this.zoomOut_mc.onReleaseOutside = function() { _parent.broadcastEvent(new EventInfo(_parent, "onZoomOutRelease")); }
-		
-		rotateLeft_mc.onRelease = function() { _parent.broadcastEvent(new EventInfo(_parent, "onRotateLeftRelease")); }
-		rotateRight_mc.onRelease = function() { _parent.broadcastEvent(new EventInfo(_parent, "onRotateRightRelease")); }
-		
-		menuAccept_mc.onRelease = function() { _parent.broadcastEvent(new EventInfo(_parent, "onAcceptRelease")); }
-		menuAbort_mc.onRelease = function() { _parent.broadcastEvent(new EventInfo(_parent, "onAbortRelease")); }
-		
-	/*	
-		this.cropsize_mc.width_txt.ptr=this.pointer;
-		this.cropsize_mc.width_txt.onChanged=function() {
-		    //trace("width was changed: " + this.text);
-		    this.ptr.onManualCropSizeChange(this.text, this._parent.height_txt.text);
-		}
-		this.cropsize_mc.height_txt.ptr=this.pointer; 
-		this.cropsize_mc.height_txt.onChanged=function(){
-		    this.ptr.onManualCropSizeChange(this._parent.width_txt.text, this.text);
-		}
-		
-		this.outputsize_mc.width_txt.ptr=this.pointer;
-		this.outputsize_mc.width_txt.onChanged=function() {
-		    //trace("width was changed: " + this.text);
-		    this.ptr.onManualOutputSizeChange(this.text, this._parent.height_txt.text);
-		}
-		this.outputsize_mc.height_txt.ptr=this.pointer; 
-		this.outputsize_mc.height_txt.onChanged=function(){
-		    this.ptr.onManualOutputSizeChange(this._parent.width_txt.text, this.text);
-		}
-	*/	
+		dropdown_container_mc = _level0.dropdown_mc;
+		dropdown_mc = dropdown_container_mc.attachMovie("ComboBox", "dropdown_mc", dropdown_container_mc.getNextHighestDepth());
+        dropdown_mc.setSize(150, dropdown_mc._height);        		
+		dropdown_mc._visible = false;
 	}
 	
-	function setCropSizeValues(width:Number, height:Number) {
-	    this.cropsize_mc.width_txt.text=width;
-	    this.cropsize_mc.height_txt.text=height;
+	public function init()
+	{
+	    var presets = FlashvarManager.get("presets");
+	    if (!presets)
+            return;
+            
+        dropdown_mc.setStyle("fontFamily", "Arial");
+        dropdown_mc.setStyle("fontSize", 11);
+        dropdown_mc.setStyle("themeColor", 0xc0c0c0)
+        dropdown_mc.setStyle("openDuration", 0);
+        dropdown_mc.setStyle("openEasing", null);
+        dropdown_mc.setStyle("selectionDuration", null);
+        dropdown_mc.setStyle("selectionEasing", null);
+        //dropdown_mc.setStyle("useRollOver", false);
+        dropdown_mc.setStyle("textSelectedColor", 0x000000)
+        dropdown_mc.setStyle("rollOverColor", 0xdddddd);
+
+        //dropdown_mc.setStyle("rollOverColor", 0xe8e8e8);
+        //dropdown_mc.setStyle("textRollOverColor", 0x333333);
+        //dropdown_mc.setStyle("selectionColor", 0xe8e8e8);
+        //dropdown_mc.setStyle("textSelectedColor", 0x333333);
+        //dropdown_mc.setStyle("embedFonts", true);
+        
+		dropdown_mc.rowCount = 10;
+        dropdown_mc.addEventListener("change", this);
+        
+        var itemList = new Array();
+        for (var i in presets)
+        {
+    		itemList.push(presets[i]);
+        }
+        
+        // revert and select current item
+        var selectedItem = itemList[itemList.length - 1];
+        for (var i = itemList.length - 1; i >= 0; i--)
+        {
+            var item = itemList[i];
+            item.isRatioFixed = !!(item.ratio || (item.output_w && item.output_h) || (item.output_w && item.output_h) || (item.min_w && item.min_h) || (item.max_w && item.max_h));
+            dropdown_mc.addItem({label: item.name, data: item});
+    		if (item.selected)
+    		{
+    		    dropdown_mc.selectedIndex = itemList.length - 1 - i;
+    		    selectedItem = item;
+    		}
+        }
+
+        dropdown_mc._visible = itemList.length > 1;
+
+        fireRatioChange(selectedItem);
 	}
-	function updateOutputSizeValues(width:Number, height:Number) {
-	    this.outputsize_mc.width_txt.text=width;
-	    this.outputsize_mc.height_txt.text=height;
+	
+	// event listeners ----------------------------------------------------------------
+	
+	// forward slider events
+	function onSliderChange(ei:EventInfo)
+	{
+	    broadcastEvent(ei);
 	}
+
+	function onSliderPress(ei:EventInfo)
+	{
+	    broadcastEvent(ei);
+	}
+
+	function onSliderRelease(ei:EventInfo)
+	{
+	    broadcastEvent(ei);
+	}
 	
+	// forward dropdown events
+    private function change(obj:Object)
+    {
+        fireRatioChange(obj.target.selectedItem.data);
+    }
+    
+    private function fireRatioChange(item:Object)
+    {
+        var ei:EventInfo = new EventInfo(this, "onViewportRatioChange");
+        ei.setInfo("preset", item);
+        broadcastEvent(ei);
+    }
+    
+    function onFitImage(ei:EventInfo)
+    {
+        slider_mc.setPercent(0);
+    }
+	
 	public function onParentResize(w:Number, h:Number)
 	{
-	    bg_mc._width = w
-	    bg_mc._height = h;
-	    
+	    var centerY = h / 2;
+
+	    canvas_mc._x = 0;
+	    canvas_mc._y = 0;
+	    canvas_mc.onParentResize(w, h);
+
+	    // left alligned
 	    var nextX = PADDING;
-	    var centerY = h / 2;
 	    
     	rotateLeft_mc._x = nextX;
     	rotateLeft_mc._y = centerY - rotateLeft_mc._height / 2;
@@ -107,20 +165,23 @@
     	rotateRight_mc._y = centerY - rotateRight_mc._height / 2;
     	nextX += rotateRight_mc._width + PADDING;
 
-    	zoomIn_mc._x = nextX;
-    	zoomIn_mc._y = centerY - zoomIn_mc._height / 2;
-    	nextX += zoomIn_mc._width + PADDING;
-
-    	zoomOut_mc._x = nextX;
-    	zoomOut_mc._y = centerY - zoomOut_mc._height / 2;
-    	nextX += zoomOut_mc._width + PADDING;
-
-    	menuAccept_mc._x = nextX;
-    	menuAccept_mc._y = centerY - menuAccept_mc._height / 2;
-    	nextX += menuAccept_mc._width + PADDING;
-
-    	menuAbort_mc._x = nextX;
-    	menuAbort_mc._y = centerY - menuAbort_mc._height / 2;
-    	nextX += menuAbort_mc._width + PADDING;
+    	
+    	// right alligned
+    	if (FlashvarManager.get("presets").length > 1)
+    	{
+        	nextX = w - dropdown_mc._width - PADDING;    	
+    		dropdown_mc._y = Stage.height - 44;
+    		dropdown_mc._x = Stage.width - 20 - dropdown_mc._width;
+        	nextX = dropdown_mc._x - PADDING - slider_mc._width;
+    	}
+        else
+        {
+            nextX = w - slider_mc._width - PADDING;
+        }
+        
+    	slider_mc._x = nextX;
+    	slider_mc._y = centerY - slider_mc._height / 2;
+    	
+    	nextX = slider_mc._x - PADDING; //- ???
 	}
 }
\ No newline at end of file

Modified: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/EditableImage.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/EditableImage.as	2007-09-18 09:01:27 UTC (rev 79731)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/EditableImage.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -7,445 +7,405 @@
 
 import z3c.reference.imagetool.core.*;
 import z3c.reference.imagetool.baseskin.*;
+import flash.display.BitmapData;
+import flash.geom.*;
 
+import flash.display.*;
+import flash.filters.*;
+import flash.events.*;
+import flash.utils.getTimer;
+
+
 [Event("onImageLoaded")]
-[Event("onImagePress")]
-[Event("onImageRelease")]
 
 
 class z3c.reference.imagetool.baseskin.EditableImage extends Component
 {
-    private var MIN_VIEWPORT_SIZE:Number = 20;
-
+    private var container_mc:MovieClip;
     private var image_mc:MovieClip;
     private var fader_mc:MovieClip;
-    private var viewport_mc:MovieClip;
     
-    private var isDragging:Boolean = false;
-    private var isLineDragging:Boolean = false;
-    private var isCornerDragging:Boolean = false;
-    private var currentDragElement:String = "";
-    private var dragElementOffsetX:Number = 0;
-    private var dragElementOffsetY:Number = 0;
-    private var dragStartPoint:flash.geom.Point;
-    private var viewportStartWidth:Number = 1;
-    private var viewportStartHeight:Number = 1;
-    private var viewportFixedRatio:Number = 1;
-    private var viewportStartPoint:flash.geom.Point;
-    
     private var mcLoader:MovieClipLoader;
-
+    private var bitmapData:BitmapData;
+    
 	function EditableImage()
 	{
 	    super();
 	    
+	    createEmptyMovieClip("container_mc", getNextHighestDepth());
 	    createEmptyMovieClip("image_mc", getNextHighestDepth());
 	    createEmptyMovieClip("fader_mc", getNextHighestDepth());
-	    
-	    attachMovie("viewport_mc", "viewport_mc", getNextHighestDepth());
-	    viewport_mc.addListener(this);
-	    
+        
 	    mcLoader = new MovieClipLoader();
 	    mcLoader.addListener(this);
 	    
+	    useHandCursor = false;
+	    
 	    Key.addListener(this);
     }
     
     public function loadImage(url:String)
     {
-        mcLoader.loadClip(url, image_mc);
+        mcLoader.loadClip(url, container_mc);
     }
 
-    public function getCropPosition():flash.geom.Point
+    public function setSize(w:Number, h:Number)
     {
-        return new flash.geom.Point(viewport_mc._x, viewport_mc._y);
+        image_mc._width = w;
+        image_mc._height = h;
     }
     
-    public function getCropDimension():flash.geom.Point
+    public function setFaderVisible(visible:Boolean)
     {
-        return new flash.geom.Point(viewport_mc._width, viewport_mc._height);
+        fader_mc._visible = visible;
     }
-
-    function onEnterFrame()
-    {
-        if (FlashvarManager.get("keepAspectRatio") || Key.isDown(Key.SHIFT))
-        {
-            if (isCornerDragging)
-                scaleViewportByRatio();
-        }
-        else
-        {
-            if (isLineDragging)
-                scaleViewportByLine(_xmouse, _ymouse);
-
-            if (isCornerDragging)
-                scaleViewportByCorner(_xmouse, _ymouse);
-        }
-        
-        if (isDragging || isCornerDragging || isLineDragging)
-            updateFader();
-    }
     
-    private function scaleViewportByLine(cursorX:Number, cursorY:Number)
+    public function setVisibleArea(area:Rectangle)
     {
-        switch(currentDragElement)
-        {
-            case "L":
-                var dx = -(cursorX - dragStartPoint.x);
+        fader_mc.clear();
 
-                if (viewportStartPoint.x - dx >= 0)
-                {
-                    viewport_mc._x = viewportStartPoint.x - dx;
-                }
-                else
-                {
-                    viewport_mc._x = 0;
-                    viewport_mc._width = viewportStartPoint.x + viewportStartWidth;
-                    return;
-                }
+        fader_mc.beginFill(0x000000, 50);
+        fader_mc.moveTo(0, 0);
+        fader_mc.lineTo(area.x, 0);
+        fader_mc.lineTo(area.x, area.y);
+        fader_mc.lineTo(0, area.y)
+        fader_mc.endFill();
 
-                if (viewportStartWidth + dx >= MIN_VIEWPORT_SIZE)
-                {
-                    viewport_mc._width = viewportStartWidth + dx;
-                }
-                else
-                {
-                    viewport_mc._width = MIN_VIEWPORT_SIZE;
-                    viewport_mc._x = viewportStartPoint.x + viewportStartWidth - MIN_VIEWPORT_SIZE;
-                    return;
-                }
+        fader_mc.beginFill(0x000000, 50);
+        fader_mc.moveTo(area.x, 0);
+        fader_mc.lineTo(area.x + area.width, 0);
+        fader_mc.lineTo(area.x + area.width, area.y);
+        fader_mc.lineTo(area.x, area.y)
+        fader_mc.endFill();
 
-                break;
+        fader_mc.beginFill(0x000000, 50);
+        fader_mc.moveTo(area.x + area.width, 0);
+        fader_mc.lineTo(image_mc._width, 0);
+        fader_mc.lineTo(image_mc._width, area.y);
+        fader_mc.lineTo(area.x + area.width, area.y)
+        fader_mc.endFill();
 
-            case "T":
-                var dy = -(cursorY - dragStartPoint.y);
+        fader_mc.beginFill(0x000000, 50);
+        fader_mc.moveTo(0, area.y);
+        fader_mc.lineTo(area.x, area.y);
+        fader_mc.lineTo(area.x, area.y + area.height);
+        fader_mc.lineTo(0, area.y + area.height);
+        fader_mc.endFill();
 
-                if (viewportStartPoint.y - dy >= 0)
-                {
-                    viewport_mc._y = viewportStartPoint.y - dy;
-                }
-                else
-                {
-                    viewport_mc._y = 0;
-                    viewport_mc._height = viewportStartPoint.y + viewportStartHeight;
-                    return;
-                }
+        fader_mc.beginFill(0x000000, 50);
+        fader_mc.moveTo(area.x + area.width, area.y);
+        fader_mc.lineTo(image_mc._width, area.y);
+        fader_mc.lineTo(image_mc._width, area.y + area.height);
+        fader_mc.lineTo(area.x + area.width, area.y + area.height)
+        fader_mc.endFill();
 
-                if (viewportStartHeight + dy >= MIN_VIEWPORT_SIZE)
-                {
-                    viewport_mc._height = viewportStartHeight + dy;
-                }
-                else
-                {
-                    viewport_mc._height = MIN_VIEWPORT_SIZE;
-                    viewport_mc._y = viewportStartPoint.y + viewportStartHeight - MIN_VIEWPORT_SIZE;
-                    return;
-                }
-                break;
+        fader_mc.beginFill(0x000000, 50);
+        fader_mc.moveTo(0, area.y + area.height);
+        fader_mc.lineTo(area.x, area.y + area.height);
+        fader_mc.lineTo(area.x, image_mc._height);
+        fader_mc.lineTo(0, image_mc._height)
+        fader_mc.endFill();
 
-                
-            case "R":
-                var dx = cursorX - dragStartPoint.x;
+        fader_mc.beginFill(0x000000, 50);
+        fader_mc.moveTo(area.x, area.y + area.height);
+        fader_mc.lineTo(area.x + area.width, area.y + area.height);
+        fader_mc.lineTo(area.x + area.width, image_mc._height);
+        fader_mc.lineTo(area.x, image_mc._height)
+        fader_mc.endFill();
 
-                if (viewportStartPoint.x + viewportStartWidth + dx >= image_mc._width)
-                {
-                    viewport_mc._width = image_mc._width - viewportStartPoint.x;
-                    return;
-                }
-                
-                if (viewportStartWidth + dx >= MIN_VIEWPORT_SIZE)
-                {
-                    viewport_mc._width = viewportStartWidth + dx;
-                }
-                else
-                {
-                    viewport_mc._width = MIN_VIEWPORT_SIZE;
-                }
-                break;
-                
-            case "B":
-                var dy = cursorY - dragStartPoint.y;
-                
-                if (viewportStartPoint.y + viewportStartHeight + dy >= image_mc._height)
-                {
-                    viewport_mc._height = image_mc._height - viewportStartPoint.y;
-                    return;
-                }
-                
-                if (viewportStartHeight + dy >= MIN_VIEWPORT_SIZE)
-                {
-                    viewport_mc._height = viewportStartHeight + dy;
-                }
-                else
-                {
-                    viewport_mc._height = MIN_VIEWPORT_SIZE;
-                }
-                break;
-        }
-        
-        viewport_mc.updateSensitiveAreas();
+        fader_mc.beginFill(0x000000, 50);
+        fader_mc.moveTo(area.x + area.width, area.y + area.height);
+        fader_mc.lineTo(image_mc._width, area.y + area.height);
+        fader_mc.lineTo(image_mc._width, image_mc._height);
+        fader_mc.lineTo(area.x + area.width, image_mc._height)
+        fader_mc.endFill();
     }
-    
-    private function scaleViewportByCorner(cursorX:Number, cursorY:Number)
-    {
-        var lines = currentDragElement.split("");
-        for (var i = 0; i < lines.length; i++)
-        {
-            currentDragElement = lines[i];
-            scaleViewportByLine(cursorX, cursorY);
-        }
-        currentDragElement = lines.join("");
-    }
-    
-    private function scaleViewportByRatio()
-    {
-        switch(currentDragElement)
-        {
-            case "LT":
-                var offsetX = _xmouse - viewportStartPoint.x;
-                var offsetY = _ymouse - viewportStartPoint.y;
-                var offset = (offsetX < offsetY) ? (offsetX) : (offsetY);
-                var cursorX = viewportStartPoint.x + (offset + dragElementOffsetX);
-                var cursorY = viewportStartPoint.y + (offset + dragElementOffsetY) / viewportFixedRatio;
-                scaleViewportByCorner(cursorX, cursorY);
-                break;
-            
-            case "RT":
-                var offsetX = viewportStartPoint.x + viewportStartWidth - _xmouse;
-                var offsetY = _ymouse - viewportStartPoint.y;
-                var offset = (offsetX < offsetY) ? offsetX : offsetY;
-                var cursorX = viewportStartPoint.x + viewportStartWidth - (offset - dragElementOffsetX) / viewportFixedRatio;
-                var cursorY = viewportStartPoint.y + (offset + dragElementOffsetY);
-                scaleViewportByCorner(cursorX, cursorY);
-                break;
-                
-            case "LB":
-                var offsetX = _xmouse - viewportStartPoint.x;
-                var offsetY = viewportStartPoint.y + viewportStartHeight - _ymouse;
-                var offset = (offsetX < offsetY) ? offsetX : offsetY;
-                var cursorX = viewportStartPoint.x + (offset + dragElementOffsetX);
-                var cursorY = viewportStartPoint.y + viewportStartHeight - (offset - dragElementOffsetY) / viewportFixedRatio;
-                scaleViewportByCorner(cursorX, cursorY);
-                break;
-            
-            case "RB":
-                var offsetX = _xmouse - viewportStartPoint.x;
-                var offsetY = _ymouse - viewportStartPoint.y;
-                var offset = (offsetX > offsetY) ? (offsetX) : (offsetY);
-                var cursorX = viewportStartPoint.x + (offset + dragElementOffsetX);
-                var cursorY = viewportStartPoint.y + (offset + dragElementOffsetY) / viewportFixedRatio;
-                scaleViewportByCorner(cursorX, cursorY);
-                break;
-        }
-    }
-    
-    private function moveViewportBy(x:Number, y:Number)
-    {
-        if (viewport_mc._x + x < 0)
-            viewport_mc._x = 0;
-        else if (viewport_mc._x + x > image_mc._width - viewport_mc._width)
-            viewport_mc._x = image_mc._width - viewport_mc._width;
-        else
-            viewport_mc._x += x;
-            
-        if (viewport_mc._y + y < 0)
-            viewport_mc._y = 0;
-        else if (viewport_mc._y + y > image_mc._height - viewport_mc._height)
-            viewport_mc._y = image_mc._height - viewport_mc._height;
-        else
-            viewport_mc._y += y;
-        
-    }
-    
+
     // event listeners --------------------------------------------------------------
 
     function onLoadInit(mc:MovieClip)
     {
-        viewport_mc.init();
-        viewportFixedRatio = FlashvarManager.get("keepAspectRatio") ? (viewport_mc._width / viewport_mc._height) : 1;
-        viewport_mc._x = FlashvarManager.get("crop_x");
-        viewport_mc._y = FlashvarManager.get("crop_x");
-        updateFader();
+        bitmapData = new BitmapData(container_mc._width, container_mc._height, false, 0);
+        image_mc.attachBitmap(bitmapData, image_mc.getNextHighestDepth(), "auto", true);
+        bitmapData.draw(container_mc);
+        container_mc.unloadMovie();
+        container_mc.removeMovieClip();
+        //initSeamCarving();
         
         var ei:EventInfo = new EventInfo(this, "onImageLoaded");
         broadcastEvent(ei);
     }
-
-    function onKeyDown()
-    {
-        var offset = Key.isDown(Key.SHIFT) ? 5 : 1;
-        
-        switch(Key.getCode())
-        {
-            case Key.UP:
-                moveViewportBy(0, -offset);
-                break;
-                
-            case Key.DOWN:
-                moveViewportBy(0, offset);
-                break;
-                
-            case Key.LEFT:
-                moveViewportBy(-offset, 0);
-                break;
-                
-            case Key.RIGHT:
-                moveViewportBy(offset, 0);
-                break;
-                
-            case Key.SHIFT:
-                if (FlashvarManager.get("keepAspectRatio"))
-                {
-                    
-                }
-                else
-                {
-                    //viewport_mc._x = Math.floor(viewport_mc._x);
-                    //viewport_mc._y = Math.floor(viewport_mc._y);
-                    //viewport_mc._width = Math.floor(viewport_mc._width);
-                    //viewport_mc._height = Math.floor(viewport_mc._height);
-                }
-                break;
-        }
-    }
     
-    function onMouseDown()
+    function onRollOver()
     {
-        // first check if the mouse is over the image at all
-        if (_xmouse < 0 || _xmouse > _width || _ymouse < 0 || _ymouse > _height)
-            return;
-            
-        // now check if the hit the image
-        if (_xmouse >= viewport_mc._x && _xmouse <= viewport_mc._x + viewport_mc._width && 
-            _ymouse >= viewport_mc._y && _ymouse <= viewport_mc._y + viewport_mc._height)
-                return;
-            
-        var ei:EventInfo = new EventInfo(this, "onImagePress");
+        var ei:EventInfo = new EventInfo(this, "onImageRollOver");
         broadcastEvent(ei);
     }
     
-    function onMouseUp()
+    function onRollOut()
     {
-        //if (_xmouse >= viewport_mc._x && _xmouse <= viewport_mc._x + viewport_mc._width && 
-        //    _ymouse >= viewport_mc._y && _ymouse <= viewport_mc._y + viewport_mc._height)
-        //        return;
-
-        var ei:EventInfo = new EventInfo(this, "onImageRelease");
+        var ei:EventInfo = new EventInfo(this, "onImageRollOut");
         broadcastEvent(ei);
     }
-    
-    function onViewportPress(ei:EventInfo)
+
+    public function onParentResize(w:Number, h:Number)
     {
-        viewport_mc.startDrag(false, 0, 0, image_mc._width - viewport_mc._width, image_mc._height - viewport_mc._height);
-        isDragging = true;
+
     }
+
+    // seam carving stuff ----------------------------------------------------------------------------
+    // note: this was just a test and it seems like as2 is way too slow to handle seam carving - also
+    // there seems to be a bug somewhere - you're welcome to play around with this :-)
     
-    function onViewportRelease(ei:EventInfo)
+    private var result_mc:MovieClip;
+
+	private var screen: BitmapData;		
+	private var displaceMap:BitmapData;
+	private var energyMap: BitmapData;
+	private var grayscaleMap: BitmapData;
+	private var blurMap: BitmapData;
+	
+	private static var origin:flash.geom.Point;// = new Point();
+	private static var colorMatrix:ColorMatrixFilter;// = new ColorMatrixFilter( new Array( 0,0,0, 0, 0, 0, 0, 0, 0, 0, .2125, .7154, .0721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
+	private static var blur:BlurFilter;// = new BlurFilter( 4,4,1);
+	//private static const convolution: ConvolutionFilter = new ConvolutionFilter( 3, 3, new Array( 0, -1, 0, -1, 4, -1, 0, -1, 0 ) );
+	//private static const convolutionH: ConvolutionFilter = new ConvolutionFilter( 1, 3, new Array(  -2, 4, -2 ) );
+	//private static const convolutionV: ConvolutionFilter = new ConvolutionFilter( 3, 1, new Array(  -2, 4, -2 ) );
+	
+	private var mode: Boolean = false;
+	
+	private var fillRect:Rectangle;
+	private var filterRect:Rectangle;
+	private var dmf:DisplacementMapFilter;
+	private static var m1:Matrix = new Matrix(1,0,0,1,-2,-2);
+	private static var m2:Matrix = new Matrix(1,0,0,1,2,2);
+
+    private function initSeamCarving()
     {
-        viewport_mc.stopDrag();
-        viewport_mc._x = Math.floor(viewport_mc._x);
-        viewport_mc._y = Math.floor(viewport_mc._y);
-        updateFader();
-        isDragging = false;
+        createEmptyMovieClip("result_mc", getNextHighestDepth());
+
+    	origin = new flash.geom.Point();
+    	colorMatrix = new ColorMatrixFilter( new Array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, .2125, .7154, .0721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
+    	blur = new BlurFilter(4, 4, 1);
+
+    	filterRect = bitmapData.rectangle.clone();
+    	screen = bitmapData.clone();
+	
+    	energyMap = new BitmapData(bitmapData.width, bitmapData.height, false, 0);
+	
+    	grayscaleMap = bitmapData.clone();
+    	blurMap = bitmapData.clone();
+    	grayscaleMap.applyFilter( bitmapData, filterRect, origin, colorMatrix );
+    	blurMap.applyFilter(grayscaleMap, filterRect, origin, blur);
+    	energyMap.draw(blurMap, m1);
+    	energyMap.draw(blurMap, m2, null, "difference");
+	
+    	//energyMap.applyFilter( grayscaleMap, filterRect, origin, convolution);
+	
+    	displaceMap = new BitmapData(bitmapData.width + 1, bitmapData.height + 1, false, 0x808080);
+    	fillRect = new Rectangle();
+	
+	
+    	dmf = new DisplacementMapFilter();
+    	dmf.mapPoint = origin;
+    	dmf.componentY = dmf.componentX = 4;
+    	dmf.mode = "color";//DisplacementMapFilterMode.COLOR
+    	dmf.alpha = 0;
+    	dmf.mapBitmap = displaceMap;
+	
+	    //var bmp = new flash.display.Bitmap( screen )
+    	/*
+    	var bm:Bitmap = new Bitmap( displaceMap );
+    	bm.x = 500;
+    	addChild( bm );
+    	*/
+	
+    	//stage.addEventListener( KeyboardEvent.KEY_UP, onKeyUp );
+    	//stage.addEventListener( MouseEvent.CLICK, onClick );
+    	//stage.addEventListener( Event.ENTER_FRAME, onEnterFrame );
+    	
+    	onEnterFrame = doSteps;
     }
-    
-    function onLinePress(ei:EventInfo)
+
+/*
+    function onRelease()
     {
-        currentDragElement = ei.getInfo("line");
-        viewportStartPoint = new flash.geom.Point(viewport_mc._x, viewport_mc._y);
-        dragStartPoint = new flash.geom.Point(Math.floor(_xmouse), Math.floor(_ymouse));
-        viewportStartWidth = viewport_mc._width;
-        viewportStartHeight = viewport_mc._height;
-        isLineDragging = true;
+    	bitmapData = Bitmap( new PICTURE ).bitmapData;
+    	filterRect = bitmapData.rectangle.clone();
+	
     }
-    
-    function onLineRelease(ei:EventInfo)
+
+    function onKeyUp( event: KeyboardEvent )
     {
-        isLineDragging = false;
+    	mode = !mode;
     }
-    
-    function onCornerPress(ei:EventInfo)
+*/
+    function doSteps()
     {
-        currentDragElement = ei.getInfo("corner");
-        dragElementOffsetX = ei.getInfo("offsetX");
-        dragElementOffsetY = ei.getInfo("offsetY");
-        viewportStartPoint = new flash.geom.Point(viewport_mc._x, viewport_mc._y);
-        dragStartPoint = new flash.geom.Point(Math.floor(_xmouse), Math.floor(_ymouse));
-        viewportStartWidth = viewport_mc._width;
-        viewportStartHeight = viewport_mc._height;
-        isCornerDragging = true;
+    	//( mode ) ? stepX() : stepY();
+    	stepX();
+    	screen.copyPixels( bitmapData, bitmapData.rectangle, origin);
     }
-    
-    function onCornerRelease(ei:EventInfo)
+
+    private function stepX()
     {
-        isCornerDragging = false;
+	
+    	if ( filterRect.width == 1 ) return;
+	
+    	//Die grayscale map braucht man nur am anfang zu bauen wenn man sie
+    	//mitverzerrt - die Frage ist nur, ob DisplacementMap schneller ist als colormatrix
+    	//energyMap.applyFilter( bitmapData, filterRect, origin, colorMatrix );
+	
+    	//Das ist zwar nicht 100% korrekt, aber wenn man die energy map mitverzerrt
+    	//und nicht neuberechnet sieht as gar nicht so schmlimm aus. Vielleicht
+    	//kann man das neuberechnen nur alle 20 oder 40 steps machen. 
+    	//energyMap.applyFilter( grayscaleMap, filterRect, origin, convolutionH );
+	
+    	blurMap.applyFilter( grayscaleMap,filterRect,origin,blur);
+    	energyMap.draw(grayscaleMap,m1);
+    	energyMap.draw(grayscaleMap,m2,null,"difference");
+	
+    	var n: Number = filterRect.width;
+    	var seamsV: Array = new Array();
+    	var seam: Seam;
+    	var bestEnergy:Number = Number.MAX_VALUE;
+	
+    	for ( var x: Number = 0; x < n; ++x )
+    	{
+    		seam = new Seam;
+    		seam.direction = SeamDirection.V;
+    		seam.start = x;
+    		seam.bake( energyMap, filterRect, bestEnergy );
+    		if ( seam.energy < bestEnergy ){
+    			bestEnergy = seam.energy;
+    			seamsV.push( seam );
+    		}
+    	}
+	
+    	seamsV.sortOn( 'energy', Array.NUMERIC  );
+	
+    	var p: SeamPoint = Seam( seamsV[ 0 ] ).points;
+    	var w: Number = filterRect.width;
+    	var h: Number = filterRect.height;
+	
+    	x = p.x;
+    	displaceMap.fillRect(displaceMap.rectangle,0x808080);
+	
+    	for (var y:Number = 0;y<h-1;y++)
+    	{
+    		displaceMap.setPixel(p.x,y,0x81);
+    		if ( p.x>x) x = p.x;
+    		p = p.next;
+    	}
+    	if ( p.x > x ) x = p.x;
+    	while ( y<displaceMap.width)
+    	{
+    		displaceMap.setPixel(p.x,y++,0x81);
+    	}
+	
+    	fillRect.x = x+3;
+    	fillRect.y = 0;
+    	fillRect.width = displaceMap.width - fillRect.x;
+    	fillRect.height = displaceMap.height;
+    	displaceMap.fillRect(fillRect,0x81);
+    	displaceMap.floodFill(x+2,0,0x81);
+	
+    	dmf.scaleX = 256;
+    	dmf.scaleY = 0;
+    	filterRect.width--;
+	
+    	bitmapData.applyFilter(bitmapData,filterRect,origin,dmf);
+    	fillRect.y = 0;
+    	fillRect.x = filterRect.width;
+    	fillRect.height = bitmapData.height;
+    	bitmapData.fillRect(fillRect,0);
+	
+    	grayscaleMap.applyFilter(grayscaleMap,filterRect,origin,dmf);
+    	//energyMap.applyFilter(energyMap,filterRect,origin,dmf);
     }
-    
-    public function onParentResize(w:Number, h:Number)
+
+    private function stepY()
     {
+    	if ( filterRect.height == 1 ) return;
+		
+	
+    	//energyMap.applyFilter( bitmapData, filterRect, origin, colorMatrix );
+    	//energyMap.applyFilter( grayscaleMap, filterRect, origin, convolutionV);
+    	blurMap.applyFilter( grayscaleMap,filterRect,origin,blur);
+    	energyMap.draw(grayscaleMap,m1);
+    	energyMap.draw(grayscaleMap,m2,null,"difference");
+	
+    	var n: Number = filterRect.height;
+    	var seamsV: Array = new Array();
+    	var seam: Seam;
+    	var x: Number, y: Number;
+    	var bestEnergy:Number = Number.MAX_VALUE;
+	
+    	for ( y = 0; y < n; ++y )
+    	{
+    		seam = new Seam;
+    		seam.direction = SeamDirection.H;
+    		seam.start = y;
+    		seam.bake( energyMap, filterRect,bestEnergy );
+    		if ( seam.energy < bestEnergy )
+    		{
+    			bestEnergy = seam.energy;
+    			seamsV.push( seam );
+    		} 
+		
+    	}
+	
+    	seamsV.sortOn( 'energy', Array.NUMERIC );
+	
+    	var w: Number = filterRect.width;
+    	var h: Number = filterRect.height;
 
+    	var p: SeamPoint = Seam( seamsV[ 0 ] ).points;
+    	y = p.y;
+    	displaceMap.fillRect(displaceMap.rectangle,0x808080);
+	
+    	for ( x = 0; x<w-1; x++ )
+    	{
+    		displaceMap.setPixel(x,p.y,0x81);
+    		if ( p.y>y) y = p.y;
+    		p = p.next;
+    	}
+    	if ( p.y>y) y = p.y;
+    	while ( x<displaceMap.width )
+    	{
+    		displaceMap.setPixel(x++,p.y,0x81);
+    	}
+		
+    	fillRect.x = 0;
+    	fillRect.y = y + 3;
+    	fillRect.width = displaceMap.width;
+    	fillRect.height = displaceMap.height - fillRect.y;
+    	displaceMap.fillRect(fillRect,0x81);
+    	displaceMap.floodFill(0,y+2,0x81);
+	
+    	dmf.scaleX = 0;
+    	dmf.scaleY = 256;
+	
+    	filterRect.height--;
+	
+    	bitmapData.applyFilter(bitmapData,filterRect,origin,dmf);
+    	fillRect.x = 0;
+    	fillRect.y = filterRect.height;
+    	fillRect.width = bitmapData.width;
+    	bitmapData.fillRect(fillRect,0);
+	
+	
+    	grayscaleMap.applyFilter(grayscaleMap,filterRect,origin,dmf);
+    	//energyMap.applyFilter(energyMap,filterRect,origin,dmf);
     }
-    
-    // helpers ----------------------------------------------------------------------------
-    
-    private function updateFader()
+
+    private function renderSeam( x: Number, y: Number )
     {
-        fader_mc.clear();
+    	screen.setPixel( x, y, 0xff0000 );
+    }
+}
 
-        fader_mc.beginFill(0x000000, 50);
-        fader_mc.moveTo(0, 0);
-        fader_mc.lineTo(viewport_mc._x, 0);
-        fader_mc.lineTo(viewport_mc._x, viewport_mc._y);
-        fader_mc.lineTo(0, viewport_mc._y)
-        fader_mc.endFill();
 
-        fader_mc.beginFill(0x000000, 50);
-        fader_mc.moveTo(viewport_mc._x, 0);
-        fader_mc.lineTo(viewport_mc._x + viewport_mc._width, 0);
-        fader_mc.lineTo(viewport_mc._x + viewport_mc._width, viewport_mc._y);
-        fader_mc.lineTo(viewport_mc._x, viewport_mc._y)
-        fader_mc.endFill();
 
-        fader_mc.beginFill(0x000000, 50);
-        fader_mc.moveTo(viewport_mc._x + viewport_mc._width, 0);
-        fader_mc.lineTo(image_mc._width, 0);
-        fader_mc.lineTo(image_mc._width, viewport_mc._y);
-        fader_mc.lineTo(viewport_mc._x + viewport_mc._width, viewport_mc._y)
-        fader_mc.endFill();
-        
-        fader_mc.beginFill(0x000000, 50);
-        fader_mc.moveTo(0, viewport_mc._y);
-        fader_mc.lineTo(viewport_mc._x, viewport_mc._y);
-        fader_mc.lineTo(viewport_mc._x, viewport_mc._y + viewport_mc._height);
-        fader_mc.lineTo(0, viewport_mc._y + viewport_mc._height)
-        fader_mc.endFill();
 
-        fader_mc.beginFill(0x000000, 50);
-        fader_mc.moveTo(viewport_mc._x + viewport_mc._width, viewport_mc._y);
-        fader_mc.lineTo(image_mc._width, viewport_mc._y);
-        fader_mc.lineTo(image_mc._width, viewport_mc._y + viewport_mc._height);
-        fader_mc.lineTo(viewport_mc._x + viewport_mc._width, viewport_mc._y + viewport_mc._height)
-        fader_mc.endFill();
 
-        fader_mc.beginFill(0x000000, 50);
-        fader_mc.moveTo(0, viewport_mc._y + viewport_mc._height);
-        fader_mc.lineTo(viewport_mc._x, viewport_mc._y + viewport_mc._height);
-        fader_mc.lineTo(viewport_mc._x, image_mc._height);
-        fader_mc.lineTo(0, image_mc._height)
-        fader_mc.endFill();
-
-        fader_mc.beginFill(0x000000, 50);
-        fader_mc.moveTo(viewport_mc._x, viewport_mc._y + viewport_mc._height);
-        fader_mc.lineTo(viewport_mc._x + viewport_mc._width, viewport_mc._y + viewport_mc._height);
-        fader_mc.lineTo(viewport_mc._x + viewport_mc._width, image_mc._height);
-        fader_mc.lineTo(viewport_mc._x, image_mc._height)
-        fader_mc.endFill();
-
-        fader_mc.beginFill(0x000000, 50);
-        fader_mc.moveTo(viewport_mc._x + viewport_mc._width, viewport_mc._y + viewport_mc._height);
-        fader_mc.lineTo(image_mc._width, viewport_mc._y + viewport_mc._height);
-        fader_mc.lineTo(image_mc._width, image_mc._height);
-        fader_mc.lineTo(viewport_mc._x + viewport_mc._width, image_mc._height)
-        fader_mc.endFill();
-    }
-}

Added: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/EditableImageAttitude.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/EditableImageAttitude.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/EditableImageAttitude.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,131 @@
+/**
+* z3c.reference.imagetool.baseskin.EditableImageAttitude 
+* makes animated rotations around the center of the mc
+* 
+*
+* @author <gerold.boehler at lovelysystems.com>
+*/
+
+import z3c.reference.imagetool.core.*;
+
+import com.robertpenner.easing.*;
+import de.alex_uhlmann.animationpackage.animation.Rotation;
+
+
+[Event("onImageRotated")]
+
+
+class z3c.reference.imagetool.baseskin.EditableImageAttitude extends z3c.reference.imagetool.baseskin.MovieclipAttitude
+{
+    private var nextDegree:Number = 0;
+    private var animRotate:Rotation;
+    
+    function EditableImageAttitude(mc_:MovieClip)
+    {
+        super();
+
+	    animRotate = new Rotation(mc_);
+	    animRotate.addEventListener("onEnd", this);
+        animRotate.animationStyle(500, Sine.easeInOut);
+    }
+    
+    public function rotateLeft()
+    {
+        if (animRotate.isTweening())
+            return;
+
+        if (nextDegree == 0 || nextDegree == 180)
+		    animRotate.setRegistrationPoint({position:"CENTER"});
+
+        nextDegree -= 90;
+        animRotate.run(nextDegree);
+    }
+    
+    public function rotateRight()
+    {
+        if (animRotate.isTweening())
+            return;
+        
+        if (nextDegree == 0 || nextDegree == 180)
+		    animRotate.setRegistrationPoint({position:"CENTER"});
+
+        nextDegree += 90;
+        animRotate.run(nextDegree);
+    }
+    
+    public function rotate(degrees:Number)
+    {
+        if (animRotate.isTweening())
+            return;
+        
+        var r = degrees % 360;
+        
+        if (r == 0)
+            r = 0;
+        if (r == 90)
+        {
+	        animRotate.setRegistrationPoint({position:"CENTER"});
+            r = -90;
+        }
+        else if (r == -90)
+        {
+	        animRotate.setRegistrationPoint({position:"CENTER"});
+            r = 90;
+        }
+        else if (r == 180 || r == -180)
+            r = 180;
+        else if (r == 270 || r == -270)
+        {
+	        animRotate.setRegistrationPoint({position:"CENTER"});
+            r = 90;
+        }
+
+        nextDegree = r;
+        animRotate.run(r);
+    }
+    
+    public function get r():Number
+    {
+        if (nextDegree == -90)
+            return 90;
+            
+        if (nextDegree == 90)
+            return 270;
+            
+        return nextDegree;
+    }
+    
+    // event listeners -----------------------------------------------
+    
+    function onEnd(eo:Object)
+    {
+        switch(nextDegree)
+        {
+            case 0:
+                mc._rotation = 0;
+                break;
+                
+            case 90:
+                break;
+                
+            case -180:
+                mc._rotation = 180;
+                nextDegree = 180;
+                break;
+                
+            case 270:
+                mc._rotation = -90;
+                nextDegree = -90;
+                break;
+        }
+
+        // don't forget to call updatePosition after a rotation
+        updatePosition();
+                
+        var ei:EventInfo = new EventInfo(this, "onImageRotated");
+        broadcastEvent(ei);
+    }
+
+    // helpers --------------------------------------------------------
+    
+}
\ No newline at end of file

Modified: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/ImageTool.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/ImageTool.as	2007-09-18 09:01:27 UTC (rev 79731)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/ImageTool.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -1,373 +1,893 @@
 /**
 * z3c.reference.imagetool.baseskin.ImageTool 
-* is a tool for cropping images TTW
+* is a tool for cropping and rotating images
 *
-* @author <viktor.sohm at lovelysystems.com>
-* @author <manfred.schwendinger at lovelysystems.com>
-* @author <armin.wolf at lovelysystems.com>
 * @author <gerold.boehler at lovelysystems.com>
 */
 
+import flash.geom.*;
 import z3c.reference.imagetool.core.*;
 import z3c.reference.imagetool.baseskin.*;
 
+import com.robertpenner.easing.*;
+import de.alex_uhlmann.animationpackage.animation.Alpha;
 
+
 class z3c.reference.imagetool.baseskin.ImageTool extends Component
 {
     private var PADDING:Number = 10;
+    private var MIN_VIEWPORT_SIZE:Number = 10;
 
     private var canvas_mc:MovieClip;
     private var editable_image_mc:MovieClip;
+    private var fader_mc:MovieClip;
+    private var viewport_mc:MovieClip;
     private var mousepointer_mc:MovieClip;
     private var controller_mc:MovieClip;
+    private var preloader_mc:MovieClip;
     
-    private var imageScale:Number = 100;
-    private var imageRatio:Number = 1;
-    private var maxImageWidth:Number = 0;
-    private var maxImageHeight:Number = 0;
+    private var dragStartPoint:Point;
+    private var isViewportDragging:Boolean = false;
+    private var isElementDragging:Boolean = false;
+    private var currentDragElement:String = "";
 
-    private var editableImageStartX:Number = 0;
-    private var editableImageStartY:Number = 0;
-    private var editableImageStartWidth:Number = 1;
-    private var editableImageStartHeight:Number = 1;
-    private var zoomLevel:Number = 0;
-    private var nextDegree:Number = 0;
+    private var dragCursorStart:Point;
+    private var dragImageStart:Point;
+    private var isDraggingImage:Boolean = false;
     
-    private var dragCursorStartX:Number = 0;
-    private var dragCursorStartY:Number = 0;
-    private var dragImageStartX:Number = 0;
-    private var dragImageStartY:Number = 0;
+    private var viewportStartPoint:Point;
+    private var viewportStartSize:Point;
+    private var viewportFixedRatio:Number = 1;
+    private var viewportOutputSize:Point;
+    private var viewportMinSize:Point;
+    private var viewportMaxSize:Point;
     
-    private var isDraggingImage:Boolean = false;
+    private var imageAttitude:EditableImageAttitude;
 
+    private var animAlphaOut:Alpha;
+    private var animAlphaIn:Alpha;
+    
+    private var changesLoaded:Boolean = false;
+    
 	function ImageTool()
 	{
 	    super();
+
+	    // parse the preset list if available
+	    var presets = FlashvarManager.get("presets");
+	    // json wants "" not ''
+	    presets = presets.split("'").join("\"");
+	    if (presets)
+	    {
+    	    try
+    	    {
+    	        var presets = org.json.Json.parse(presets);
+    	        FlashvarManager.set("presets", presets);
+    		}
+    		catch (ex)
+    		{
+    			log("problem in parsing:" + ex.name + ":" + ex.message + ":" + ex.at + ":" + ex.text);
+    		}
+	    }
 	    
-	    attachMovie("canvas_mc", "canvas_mc", getNextHighestDepth());
+	    attachMovie("canvas_mc", "canvas_mc", getNextHighestDepth(), {_alpha: 0});
 
 	    attachMovie("editable_image_mc", "editable_image_mc", getNextHighestDepth());
 	    editable_image_mc.addListener(this);
 	    editable_image_mc.setMask(canvas_mc.getMask());
+	    editable_image_mc._alpha = 0;
+
+	    createEmptyMovieClip("fader_mc", getNextHighestDepth());
+
+        attachMovie("viewport_mc", "viewport_mc", getNextHighestDepth(), {_visible: false, _alpha: 0});
+	    viewport_mc.addListener(this);
+	    viewport_mc.setMask(canvas_mc.getMask());
 	    
 	    createEmptyMovieClip("mousepointer_mc", getNextHighestDepth());
 	    mousepointer_mc.attachMovie("pointer_drag_mc", "pointer_drag_mc", mousepointer_mc.getNextHighestDepth(), {_visible: false});
 	    mousepointer_mc.attachMovie("pointer_line_mc", "pointer_line_mc", mousepointer_mc.getNextHighestDepth(), {_visible: false});
 	    mousepointer_mc.attachMovie("pointer_corner_mc", "pointer_corner_mc", mousepointer_mc.getNextHighestDepth(), {_visible: false});	    
 	    
-	    attachMovie("controller_mc", "controller_mc", getNextHighestDepth());
+	    attachMovie("controller_mc", "controller_mc", getNextHighestDepth(), {_visible: false, _alpha: 0});
 	    controller_mc.addListener(this);
+	    controller_mc.addListener(viewport_mc);
+	    addListener(controller_mc);
 	    
-	    _visible = false;
-        onEnterFrame = initAfterFirstFrame;
+	    attachMovie("preloader_mc", "preloader_mc", getNextHighestDepth(), {_x:Stage.width/2, _y:Stage.height/2});
+	    
+	    animAlphaOut = new Alpha(preloader_mc);
+	    animAlphaOut.animationStyle(300, Sine.easeInOut);
+
+	    animAlphaIn = new Alpha([editable_image_mc, controller_mc, viewport_mc, canvas_mc, _level0.dropdown_mc]);
+	    animAlphaIn.animationStyle(300, Sine.easeInOut);
+	    
         Stage.addListener(this);
+	    Key.addListener(this);
+
+        onEnterFrame = initAfterFirstFrame;        
     }
     
-    var tmp = 0;
     function initAfterFirstFrame()
     {
         editable_image_mc.loadImage(FlashvarManager.get("url"));
-        onEnterFrame = null;//function() { rotateImage(tmp); tmp += 0.01;};
+        onEnterFrame = onEnterFrameUpdateViewport;
     }
     
+    // saving - loading -----------------------------------------------------------------
+    
 	function saveChanges()
 	{
-        trace("\n\nsaveChanges");
+        // then get the scale factor for the output values
+        var finalScale = imageAttitude.originalWidth / imageAttitude.w;
+        var finalImageW = imageAttitude.originalWidth;
+        var finalImageH = imageAttitude.originalHeight;
+        var finalImageR = imageAttitude.r;
+        var finalCropX = (viewport_mc._x - imageAttitude.x) * finalScale;
+        var finalCropY = (viewport_mc._y - imageAttitude.y) * finalScale;
+        var finalViewportW = viewport_mc._width * finalScale;
+        var finalViewportH = viewport_mc._height * finalScale;
         
-        var url_str:String="";
+        // if a output size is defined, apply it
+        var outputW = viewportOutputSize.x;
+        var outputH = viewportOutputSize.y;
+        var outputScale = 1;
+        if (outputW)
+            outputScale = outputW / finalViewportW;
+        else if (outputH)
+            outputScale = outputH / finalViewportH;
+            
+        // scale, clamp and floor values
+        finalImageW = Math.floor(finalImageW * outputScale);
+        finalImageH = Math.floor(finalImageH * outputScale);
+        finalCropX = Math.max(0, Math.round(finalCropX * outputScale));
+        finalCropY = Math.max(0, Math.round(finalCropY * outputScale));
+        finalViewportW = Math.min(finalImageW, Math.round(finalViewportW * outputScale));
+        finalViewportH = Math.min(finalImageH, Math.round(finalViewportH * outputScale));
+
+        var url_str = "JavaScript:cropImage(" + [finalCropX, finalCropY, finalViewportW, finalViewportH, finalImageW, finalImageH, finalImageR] + ")";
+        log("url_str: "+url_str);
         
-        url_str+="JavaScript:cropImage(";
+        // we are inside debug mode, so do not use getURL
+        if (System.capabilities.playerType == "External")
+            return;
         
-        //crop_x = Math.round(bounding_mc.left-image_mc.left)//Math.round((bounding_mc.left-image_mc.left) / image_mc.getZoomFactor());
-        //crop_y = Math.round(bounding_mc.top-image_mc.top)//Math.round((bounding_mc.top-image_mc.top) / image_mc.getZoomFactor());
+        getURL(url_str);
+	}
+	
+    private function loadChanges()
+    {
+        // here the image is loaded, scaled and rotated properly, now transform the passed dimensions to match the image 
+
+        // first get the original size of the image and swap w/h if the image is rotated
+        //var originalRatio = imageAttitude.originalRatio;
+        var finalScale = imageAttitude.originalWidth / imageAttitude.w;
         
+        // first transform the presets
+        // use the supplied crop_w and crop_h parameters to determine the current preset
+        var inputRatio = FlashvarManager.get("crop_w") / FlashvarManager.get("crop_h");
+        var presets = FlashvarManager.get("presets");
+        for (var i in presets)
+        {
+            var preset = presets[i];
+            var ratio = preset.ratio.split(":");
+            preset.ratio = parseInt(ratio[0]) / parseInt(ratio[1]);
+            
+            // this is dangerous - should change that
+            preset.selected = Math.abs(preset.output_w / preset.output_h - inputRatio) < 0.01 || Math.abs(preset.ratio - inputRatio) < 0.01;
+
+            preset.min_w /= finalScale;
+            preset.min_h /= finalScale;
+            preset.max_w /= finalScale
+            preset.max_h /= finalScale;
+        }
+
         
-        //var rotation:Number = (Math.round(image_mc.getRotation()) % 360)*-1; //seems like pil accepts rotation in the other direction
-        //rotation = rotation > 0 ? rotation : rotation + 360;
+        FlashvarManager.set("crop_x", FlashvarManager.get("crop_x") / finalScale);
+        FlashvarManager.set("crop_y", FlashvarManager.get("crop_y") / finalScale);
+        FlashvarManager.set("crop_w", FlashvarManager.get("crop_w") / finalScale);
+        FlashvarManager.set("crop_h", FlashvarManager.get("crop_h") / finalScale);
+
+        var viewportX = FlashvarManager.get("crop_x");
+        var viewportY = FlashvarManager.get("crop_y");
+        var viewportW = FlashvarManager.get("crop_w");
+        var viewportH = FlashvarManager.get("crop_h");
+
+        centerImage();
+
+        viewport_mc._x = imageAttitude.x + viewportX;
+        viewport_mc._y = imageAttitude.y + viewportY;
+        viewport_mc.setSize(viewportW, viewportH);
+
+        updateFader();
+
+        _level0.dropdown_mc._visible = true;
+        controller_mc._visible = true;
+        viewport_mc._visible = true;
+        animAlphaOut.run(0);
+        animAlphaIn.run(100);        
+
+        controller_mc.init();
         
-        //url_str += crop_x + ", ";        
-        //url_str += crop_y + ", ";        
+        changesLoaded = true;
+    }
+    
+    // image dragging -----------------------------------------------------------------    
+	
+    function startDragImage()
+    {
+        viewportStartPoint = new Point(viewport_mc._x, viewport_mc._y);
+        dragCursorStart = new Point(_xmouse, _ymouse);
+        dragImageStart = new Point(imageAttitude.x, imageAttitude.y);
+
+        onEnterFrame = dragImage;
         
-        //url_str += output_w + ", ";
-        //url_str += output_h + ", ";
-        /*
-        if (rotation==90 || rotation==270)
+        dragImage();
+        Mouse.hide();
+        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._visible = true;
+    }
+    
+    function stopDragImage(ei:EventInfo)
+    {        
+        onEnterFrame = onEnterFrameUpdateViewport;
+
+        //if (!isWithinViewport(_xmouse, _ymouse))
+        //{
+            _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._visible = false;
+            Mouse.show();
+        //}
+
+        saveChanges();
+    }
+    
+    function dragImage()
+    {
+        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._x = _level0._xmouse;
+        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._y = _level0._ymouse;
+
+        var dX = _xmouse - dragCursorStart.x;
+        var dY = _ymouse - dragCursorStart.y;
+        var nextX = dragImageStart.x + dX;
+        var nextY = dragImageStart.y + dY;
+        
+        if (imageAttitude.w >= canvas_mc._width)
         {
-            url_str += Math.round(original_h * image_mc.getZoomFactor()) + ", ";
-            url_str += Math.round(original_w * image_mc.getZoomFactor()) + ", " ;
+            if (nextX >= canvas_mc._x)
+            {
+                nextX = canvas_mc._x;
+                dX = nextX - dragImageStart.x;
+            }
+                
+            if (nextX + imageAttitude.w < canvas_mc._x + canvas_mc._width)
+            {
+                nextX = canvas_mc._x + canvas_mc._width - imageAttitude.w;
+                dX = nextX - dragImageStart.x;
+            }
+
+            imageAttitude.x = nextX;
+            viewport_mc._x = viewportStartPoint.x + dX;
         }
-        else
+        
+        if (imageAttitude.h >= canvas_mc._height)
         {
-            url_str += Math.round(original_w * image_mc.getZoomFactor()) + ", " ;
-            url_str += Math.round(original_h * image_mc.getZoomFactor()) + ", ";
+            if (nextY >= canvas_mc._y)
+            {
+                nextY = canvas_mc._y;
+                dY = nextY - dragImageStart.y;
+            }
+                
+            if (nextY + imageAttitude.h < canvas_mc._y + canvas_mc._height)
+            {
+                nextY = canvas_mc._y + canvas_mc._height - imageAttitude.h;
+                dY = nextY - dragImageStart.y;
+            }
+
+            imageAttitude.y = nextY;
+            viewport_mc._y = viewportStartPoint.y + dY;
         }
-        */
+    }
+    
+    // image positioning / scaling -----------------------------------------------------------------    
+	
+    private function centerImage()
+    {
+        imageAttitude.x = canvas_mc._x + (canvas_mc._width - imageAttitude.w) / 2;
+        imageAttitude.y = canvas_mc._y + (canvas_mc._height - imageAttitude.h) / 2;
+        //updateFader();
+    }
+    
+    private function resetImage()
+    {
+        imageAttitude.w = imageAttitude.initialWidth;
+        imageAttitude.h = imageAttitude.initialHeight;
+        centerImage();
         
-        //url_str += rotation.toString() + ", ";
-        //url_str += image_mc.getZoomFactor()+"";
-        
-        var globalTL = new flash.geom.Point();
-        var cropPos = new Object();
-        var cropDim = new Object();
-        var imageDim = new Object();
+        var ei:EventInfo = new EventInfo(this, "onFitImage");
+        broadcastEvent(ei);
+    }
+    
+    // important: this function doesn't operate on the imageAttitude since we first need
+    // to setup the dimensions based on the stage size
+    private function fitImageToStage()
+    {
+        if (FlashvarManager.get("rotation") == 0 || FlashvarManager.get("rotation") == 180)
+        {
+            var originalRatio = imageAttitude.originalWidth / imageAttitude.originalHeight;
+            if (canvas_mc._width - imageAttitude.originalWidth < canvas_mc._height - imageAttitude.originalHeight)
+                editable_image_mc.setSize(canvas_mc._width, canvas_mc._width / originalRatio);
+            else
+                editable_image_mc.setSize(canvas_mc._height * originalRatio, canvas_mc._height);
+        }
+        else if (FlashvarManager.get("rotation") == 90 || FlashvarManager.get("rotation") == 270)
+        {
+            var originalRatio = imageAttitude.originalHeight / imageAttitude.originalWidth;
+            if (canvas_mc._width - imageAttitude.originalHeight < canvas_mc._height - imageAttitude.originalWidth)
+                editable_image_mc.setSize(canvas_mc._width / originalRatio, canvas_mc._width);
+            else
+                editable_image_mc.setSize(canvas_mc._height, canvas_mc._height * originalRatio);
+        }
+    }
 
-        switch(nextDegree)
+
+    // viewport handling -----------------------------------------------------------------    	
+    
+    function onEnterFrameUpdateViewport()
+    {
+        if (isElementDragging)
         {
-            case 0:
-                imageDim.x = editable_image_mc._width;
-                imageDim.y = editable_image_mc._height;
-                globalTL.x = canvas_mc._x + (canvas_mc._width - editable_image_mc._width) / 2;
-                globalTL.y = canvas_mc._y + (canvas_mc._height - editable_image_mc._height) / 2;
+            if (viewport_mc.getLocked() || Key.isDown(Key.SHIFT))
+                scaleViewportByRatio(currentDragElement, _xmouse, _ymouse)
+            else
+                scaleViewportByDragElement(currentDragElement, _xmouse, _ymouse);
+        }
+        
+        if (isViewportDragging || isElementDragging)
+            updateFader();
+    }
+    
+    private function scaleViewportByDragElement(dragElement:String, cursorX:Number, cursorY:Number)
+    {
+        var lines = dragElement.split("");
+        for (var i = 0; i < lines.length; i++)
+        {
+            var rect = getElementExtents(lines[i], cursorX, cursorY)
+                
+            viewport_mc._x = rect.x;
+            viewport_mc._y = rect.y;
+            viewport_mc.setWidth(rect.width);
+            viewport_mc.setHeight(rect.height);
+        }
+    }
+    
+    private function scaleViewportByRatio(dragElement:String, cursorX:Number, cursorY:Number)
+    {
+        var resultX = cursorX;
+        var resultY = cursorY;
+        
+        switch(dragElement)
+        {
+            case "LT":
+                var startX = viewportStartPoint.x + viewportStartSize.x;
+                var startY = viewportStartPoint.y + viewportStartSize.y;
+                var offsetX = startX - cursorX;
+                var offsetY = startY - cursorY;
+                var offset = Math.max(offsetX, offsetY);
+                resultX = startX - offset;
+                resultY = startY - offset / viewportFixedRatio;
+                
+                // clamp to window
+                if (resultX <= imageAttitude.x)
+                {
+                    resultX = imageAttitude.x;
+                    resultY = startY + (resultX - startX) / viewportFixedRatio;
+                }
+                
+                if (resultY <= imageAttitude.y)
+                {
+                    resultY = imageAttitude.y;
+                    resultX = startX + (resultY - startY) * viewportFixedRatio;
+                }
+                
+                // clamp to min size if given                
+                if (viewportMinSize && (viewportStartPoint.x + viewportStartSize.x - resultX < viewportMinSize.x || viewportStartPoint.y + viewportStartSize.y - resultY < viewportMinSize.y))
+                {
+                    resultX = viewportStartPoint.x + viewportStartSize.x - viewportMinSize.x;
+                    resultY = viewportStartPoint.y + viewportStartSize.y - viewportMinSize.y;
+                }
+                
+                // clamp to max size if given
+                if (viewportMaxSize && (viewportStartPoint.x + viewportStartSize.x - resultX > viewportMaxSize.x || viewportStartPoint.y + viewportStartSize.y - resultY > viewportMaxSize.y))
+                {
+                    resultX = viewportStartPoint.x + viewportStartSize.x - viewportMaxSize.x;
+                    resultY = viewportStartPoint.y + viewportStartSize.y - viewportMaxSize.y;
+                }
+                
+                break;
 
-                var scaleFactor = editable_image_mc._width / maxImageWidth;
-                cropDim.x = editable_image_mc.getCropDimension().x;
-                cropDim.y = editable_image_mc.getCropDimension().y;
-                cropDim.x *= scaleFactor;
-                cropDim.y *= scaleFactor;
+            case "RT":
+                var startX = viewportStartPoint.x;
+                var startY = viewportStartPoint.y + viewportStartSize.y;
+                var offsetX = cursorX - startX;
+                var offsetY = startY - cursorY;
+                var offset = Math.max(offsetX, offsetY)
+                resultX = startX + offset;
+                resultY = startY - offset / viewportFixedRatio;
                 
-                cropPos.x = editable_image_mc.getCropPosition().x;
-                cropPos.y = editable_image_mc.getCropPosition().y;
-                editable_image_mc.localToGlobal(cropPos);
-                cropPos.x -= globalTL.x;
-                cropPos.y -= globalTL.y;
-
+                // clamp to window
+                if (resultX >= imageAttitude.x + imageAttitude.w)
+                {
+                    resultX = imageAttitude.x + imageAttitude.w;
+                    resultY = startY - (imageAttitude.x + imageAttitude.w - startX) / viewportFixedRatio;
+                }
+                
+                if (resultY <= imageAttitude.y)
+                {
+                    resultY = imageAttitude.y;
+                    resultX = startX - (resultY - startY) * viewportFixedRatio;
+                }
+                
+                // clamp to min size if given
+                if (viewportMinSize && (resultX - viewportStartPoint.x < viewportMinSize.x || viewportStartPoint.y + viewportStartSize.y - resultY < viewportMinSize.y))
+                {
+                    resultX = viewportStartPoint.x + viewportMinSize.x;
+                    resultY = viewportStartPoint.y + viewportStartSize.y - viewportMinSize.y;
+                }
+                
+                // clamp to max size if given
+                if (viewportMaxSize && (viewportStartPoint.x + viewportStartSize.x - resultX > viewportMaxSize.x || viewportStartPoint.y + viewportStartSize.y - resultY > viewportMaxSize.y))
+                {
+                    resultX = viewportStartPoint.x + viewportMaxSize.x;
+                    resultY = viewportStartPoint.y + viewportStartSize.y - viewportMaxSize.y;
+                }
+                
                 break;
-                
-            case 180:
-                imageDim.x = editable_image_mc._width;
-                imageDim.y = editable_image_mc._height;
 
-                globalTL.x = canvas_mc._x + (canvas_mc._width - editable_image_mc._width) / 2;
-                globalTL.y = canvas_mc._y + (canvas_mc._height - editable_image_mc._height) / 2;
+            case "LB":
+                var startX = viewportStartPoint.x + viewportStartSize.x;
+                var startY = viewportStartPoint.y;
+                var offsetX = startX - cursorX;
+                var offsetY = cursorY - startY;
+                var offset = Math.max(offsetX, offsetY)
+                resultX = startX - offset;
+                resultY = startY + offset / viewportFixedRatio;
 
-                var scaleFactor = editable_image_mc._width / maxImageWidth;
-                cropDim.x = editable_image_mc.getCropDimension().x;
-                cropDim.y = editable_image_mc.getCropDimension().y;
-                cropDim.x *= scaleFactor;
-                cropDim.y *= scaleFactor;
+                // clamp to window
+                if (resultX <= imageAttitude.x)
+                {
+                    resultX = imageAttitude.x;
+                    resultY = startY - (resultX - startX) / viewportFixedRatio;
+                }
+                
+                if (resultY >= imageAttitude.y + imageAttitude.h)
+                {
+                    resultY = imageAttitude.y + imageAttitude.h;
+                    resultX = startX - (imageAttitude.y + imageAttitude.h - startY) * viewportFixedRatio;
+                }
+                
+                // clamp to min size if given
+                if (viewportMinSize && (viewportStartPoint.x + viewportStartSize.x - resultX < viewportMinSize.x || resultY - viewportStartPoint.y < viewportMinSize.y))
+                {
+                    resultX = viewportStartPoint.x + viewportStartSize.x - viewportMinSize.x;
+                    resultY = viewportStartPoint.y + viewportMinSize.y;
+                }
+                
+                // clamp to max size if given
+                if (viewportMaxSize && (viewportStartPoint.x + viewportStartSize.x - resultX > viewportMaxSize.x || resultY - viewportStartPoint.y > viewportMaxSize.y))
+                {
+                    resultX = viewportStartPoint.x + viewportStartSize.x - viewportMaxSize.x;
+                    resultY = viewportStartPoint.y + viewportMaxSize.y;
+                }
+                
+                break;
 
-                cropPos.x = editable_image_mc.getCropPosition().x + editable_image_mc.getCropDimension().x;
-                cropPos.y = editable_image_mc.getCropPosition().y + editable_image_mc.getCropDimension().y;
-                editable_image_mc.localToGlobal(cropPos);
-                cropPos.x -= globalTL.x;
-                cropPos.y -= globalTL.y;
+            case "RB":
+                var startX = viewportStartPoint.x;
+                var startY = viewportStartPoint.y;
+                var offsetX = cursorX - startX;
+                var offsetY = cursorY - startY;
+                var offset = Math.max(offsetX, offsetY);
+                resultX = viewportStartPoint.x + offset;
+                resultY = viewportStartPoint.y + offset / viewportFixedRatio;
 
+                // clamp to window
+                if (resultX >= imageAttitude.x + imageAttitude.w)
+                {
+                    resultX = imageAttitude.x + imageAttitude.w;
+                    resultY = startY + (imageAttitude.x + imageAttitude.w - startX) / viewportFixedRatio;
+                }
+                
+                if (resultY >= imageAttitude.y + imageAttitude.h)
+                {
+                    resultY = imageAttitude.y + imageAttitude.h;
+                    resultX = startX + (imageAttitude.y + imageAttitude.h - startY) * viewportFixedRatio;
+                }
+                
+                // clamp to min size if given
+                if (viewportMinSize && (resultX - viewportStartPoint.x < viewportMinSize.x || resultY - viewportStartPoint.y < viewportMinSize.y))
+                {
+                    resultX = viewportStartPoint.x + viewportMinSize.x;
+                    resultY = viewportStartPoint.y + viewportMinSize.y;
+                }
+                
+                // clamp to max size if given
+                if (viewportMaxSize && (resultX - viewportStartPoint.x > viewportMaxSize.x || resultY - viewportStartPoint.y > viewportMaxSize.y))
+                {
+                    resultX = viewportStartPoint.x + viewportMaxSize.x;
+                    resultY = viewportStartPoint.y + viewportMaxSize.y;
+                }
+                
                 break;
+        }
+        
+        scaleViewportByDragElement(dragElement, resultX, resultY);
+    }
+    
+    private function getElementExtents(dragElement:String, cursorX:Number, cursorY:Number):Rectangle
+    {
+        return getLineExtents(dragElement, cursorX, cursorY);
+    }
+    
+    private function getLineExtents(dragElement:String, cursorX:Number, cursorY:Number):Rectangle
+    {
+        switch(dragElement)
+        {
+            case "L":
+                var dw = cursorX - dragStartPoint.x;
+                var rightPosX = viewportStartPoint.x + viewportStartSize.x;
+                var nextWidth = viewportStartSize.x - dw;
+
+                if (rightPosX - nextWidth < imageAttitude.x)
+                    return new Rectangle(imageAttitude.x, viewport_mc._y, rightPosX - imageAttitude.x, viewport_mc._height)
                 
-            case 90:
-                editable_image_mc._rotation = 0;
+                if (rightPosX - nextWidth > viewportStartPoint.x + viewportStartSize.x - MIN_VIEWPORT_SIZE)
+                    return new Rectangle(viewportStartPoint.x + viewportStartSize.x - MIN_VIEWPORT_SIZE, viewport_mc._y, MIN_VIEWPORT_SIZE, viewport_mc._height);
 
-                imageDim.x = editable_image_mc._height;
-                imageDim.y = editable_image_mc._width;
+                return new Rectangle(viewportStartPoint.x + dw, viewport_mc._y, viewportStartSize.x - dw, viewport_mc._height);
 
-                globalTL.x = canvas_mc._y + (canvas_mc._width - editable_image_mc._height) / 2;
-                globalTL.y = canvas_mc._x + (canvas_mc._height - editable_image_mc._width) / 2;
+            case "T":
+                var dh = cursorY - dragStartPoint.y;
+                var bottomPosY = viewportStartPoint.y + viewportStartSize.y;
+                var nextHeight = viewportStartSize.y - dh;
 
-                var scaleFactor = editable_image_mc._height / maxImageHeight;
-                cropDim.x = editable_image_mc.getCropDimension().y;
-                cropDim.y = editable_image_mc.getCropDimension().x;
-                cropDim.x *= scaleFactor;
-                cropDim.y *= scaleFactor;
-            
-                cropPos.x = editable_image_mc.getCropPosition().y;
-                cropPos.y = editable_image_mc.getCropPosition().x;
-                editable_image_mc.localToGlobal(cropPos);
-                cropPos.x = 2*editable_image_mc._height - cropPos.x + globalTL.x - cropDim.y;
-                cropPos.y = cropPos.y - globalTL.y;
+                if (bottomPosY - nextHeight < imageAttitude.y)
+                    return new Rectangle(viewport_mc._x, imageAttitude.y, viewport_mc._width, bottomPosY - imageAttitude.y);
 
-                editable_image_mc._rotation = nextDegree;
+                if (bottomPosY - nextHeight > viewportStartPoint.y + viewportStartSize.y - MIN_VIEWPORT_SIZE)
+                    return new Rectangle(viewport_mc._x, viewportStartPoint.y + viewportStartSize.y - MIN_VIEWPORT_SIZE, viewport_mc._width, MIN_VIEWPORT_SIZE);
 
-                break;
-                
-            case 270:
-                editable_image_mc._rotation = 0;
+                return new Rectangle(viewport_mc._x, viewportStartPoint.y + dh, viewport_mc._width, viewportStartSize.y - dh);
 
-                imageDim.x = editable_image_mc._height;
-                imageDim.y = editable_image_mc._width;
+            case "R":
+                var dw = cursorX - dragStartPoint.x;
+                var w = viewportStartSize.x + dw;
 
-                globalTL.x = canvas_mc._y + (canvas_mc._width - editable_image_mc._height) / 2;
-                globalTL.y = canvas_mc._x + (canvas_mc._height - editable_image_mc._width) / 2;
+                if (viewportStartPoint.x + w > imageAttitude.x + imageAttitude.w)
+                    return new Rectangle(viewport_mc._x, viewport_mc._y, imageAttitude.x + imageAttitude.w - viewportStartPoint.x, viewport_mc._height);
 
-                var scaleFactor = editable_image_mc._height / maxImageHeight;
-                cropDim.x = editable_image_mc.getCropDimension().y;
-                cropDim.y = editable_image_mc.getCropDimension().x;
-                cropDim.x *= scaleFactor;
-                cropDim.y *= scaleFactor;
-                
-                cropPos.x = editable_image_mc.getCropPosition().y;
-                cropPos.y = editable_image_mc.getCropPosition().x;
-                editable_image_mc.localToGlobal(cropPos);
-                cropPos.x = cropPos.x - globalTL.x;
-                cropPos.y = 2*editable_image_mc._width - cropPos.y + globalTL.y - cropDim.x;
+                if (w < MIN_VIEWPORT_SIZE)
+                    return new Rectangle(viewport_mc._x, viewport_mc._y, MIN_VIEWPORT_SIZE, viewport_mc._height);
 
-                editable_image_mc._rotation = nextDegree;
+                return new Rectangle(viewport_mc._x, viewport_mc._y, viewportStartSize.x + dw, viewport_mc._height);
 
-                break;
+            case "B":
+                var dh = cursorY - dragStartPoint.y;
+                var h = viewportStartSize.y + dh;
+
+                if (viewportStartPoint.y + h > imageAttitude.y + imageAttitude.h)
+                    return new Rectangle(viewport_mc._x, viewport_mc._y, viewport_mc._width, imageAttitude.y + imageAttitude.h - viewportStartPoint.y);
+
+                if (h < MIN_VIEWPORT_SIZE)
+                    return new Rectangle(viewport_mc._x, viewport_mc._y, viewport_mc._width, MIN_VIEWPORT_SIZE);
+
+                return new Rectangle(viewport_mc._x, viewport_mc._y, viewport_mc._width, viewportStartSize.y + dh);
         }
         
-        var rotation = ((360 - nextDegree) % 360);
+        return null;
+    }
         
-        url_str += [Math.round(cropPos.x), Math.round(cropPos.y), Math.round(cropDim.x), Math.round(cropDim.y), Math.round(imageDim.x), Math.round(imageDim.y), rotation].toString();
-        url_str+=");";
-        trace("url_str: "+url_str);
+    private function moveViewportBy(x:Number, y:Number)
+    {
+        if (viewport_mc._x + x < imageAttitude.x)
+            viewport_mc._x = imageAttitude.x;
+        else if (viewport_mc._x + x > imageAttitude.x + imageAttitude.w - viewport_mc._width)
+            viewport_mc._x = imageAttitude.x + imageAttitude.w - viewport_mc._width;
+        else
+            viewport_mc._x += x;
+            
+        if (viewport_mc._y + y < imageAttitude.y)
+            viewport_mc._y = imageAttitude.y;
+        else if (viewport_mc._y + y > imageAttitude.y + imageAttitude.h - viewport_mc._height)
+            viewport_mc._y = imageAttitude.y + imageAttitude.h - viewport_mc._height;
+        else
+            viewport_mc._y += y;
         
-        // we are inside debug mode, so do not use getURL
-        if (System.capabilities.playerType == "External")
+        updateFader();
+        saveChanges();
+    }
+    
+    private function resetViewport()
+    {
+        if (!changesLoaded)
             return;
+            
+        var minWidth = imageAttitude.w > imageAttitude.h ? imageAttitude.h : imageAttitude.w;
+        var minHeight = imageAttitude.w > imageAttitude.h ? imageAttitude.w : imageAttitude.h;
+        var minLen = Math.min(minWidth, minHeight);
         
-        getURL(url_str);
-	}
-	
-	function onMouseMove()
-	{
-	    //trace(_level0._xmouse + " " +  _level0._ymouse)
-	}
-	
-	private function zoomImage(dir:Number)
-	{
-	    if (zoomLevel + dir < 0 || zoomLevel + dir > 100)
-	        return;
-	    
-	    zoomLevel += dir;
-	    
-	    var newImageWidth = editableImageStartWidth * (1 + zoomLevel / 100.0);
-	    var newImageHeight = editableImageStartHeight * (1 + zoomLevel / 100.0);
-        var dx = editableImageStartWidth - newImageWidth;
-        var dy = editableImageStartHeight - newImageHeight;
-        trace(nextDegree)
-        switch(nextDegree)
+        var viewportWidth = 50;
+        var viewportHeight = 50 / viewportFixedRatio;
+        
+        viewport_mc._x = imageAttitude.x + imageAttitude.w/2 - viewportWidth/2;
+        viewport_mc._y = imageAttitude.y + imageAttitude.h/2 - viewportHeight/2;
+        viewport_mc.setSize(viewportWidth, viewportHeight);
+    }
+
+    // menu event listeners --------------------------------------------------------------
+    
+    function onRotateLeftRelease(ei:EventInfo)
+    {
+        viewport_mc._visible = false;
+        editable_image_mc.setVisibleArea(new Rectangle());
+        resetImage();
+        imageAttitude.rotateLeft();
+    }
+    
+    function onRotateRightRelease(ei:EventInfo)
+    {
+        viewport_mc._visible = false;
+        editable_image_mc.setVisibleArea(new Rectangle());
+        resetImage();
+        imageAttitude.rotateRight();
+    }
+
+    var viewportImageRatio;
+    var imageStartPoint;
+    var imageStartSize;
+    function onSliderPress(ei:EventInfo)
+    {
+        viewportImageRatio = viewport_mc._width / imageAttitude.w;
+        imageStartPoint = new Point(imageAttitude.x, imageAttitude.y);
+        imageStartSize = new Point(imageAttitude.w, imageAttitude.h);
+        viewportStartPoint = new Point(viewport_mc._x, viewport_mc._y);
+        viewportStartSize = new Point(viewport_mc._width, viewport_mc._height);
+    }
+    
+    function onSliderChange(ei:EventInfo)
+    {
+        var percent = ei.getInfo("percent");
+
+        var imageDeltaW = imageAttitude.originalWidth - imageAttitude.w;
+        var imageDeltaH = imageAttitude.originalHeight - imageAttitude.h;
+        var imageDeltaX = imageDeltaW * percent;
+        var imageDeltaY = imageDeltaH * percent;
+        
+        imageAttitude.w = imageAttitude.initialWidth + imageDeltaX;
+        imageAttitude.h = imageAttitude.initialHeight + imageDeltaY;
+        
+        centerImage();
+/*
+        var viewportW = viewportStartSize.x + (imageAttitude.w - imageStartSize.x) * viewportImageRatio;
+        var viewportH = viewportStartSize.y + (imageAttitude.h - imageStartSize.y) * viewportImageRatio;
+        viewport_mc.setSize(viewportW, viewportH);
+
+        var canvasCenterX = canvas_mc._x + canvas_mc._width / 2;
+        var canvasCenterY = canvas_mc._y + canvas_mc._height / 2;
+        var viewportStartOffsetX = viewportStartPoint.x - canvasCenterX;
+        var viewportStartOffsetY = viewportStartPoint.y - canvasCenterY;
+        var dx = imageStartPoint.x + imageStartSize.x/2 + imageAttitude.w;
+        var dy = imageStartPoint.y + imageStartSize.y/2 + imageAttitude.h;
+        viewport_mc._x = canvasCenterX + viewportStartOffsetX + dx * viewportImageRatio;
+        viewport_mc._y = canvasCenterY + viewportStartOffsetY + dy * viewportImageRatio;
+*/
+        // TODO - remove this and scale viewport when zooming
+
+        viewport_mc._visible = percent == 0;
+        editable_image_mc.setFaderVisible(percent == 0);
+        if (percent == 0)
         {
-            case 0:
-                editable_image_mc._width = editableImageStartWidth * (1 + zoomLevel / 100.0);
-                editable_image_mc._height = editableImageStartHeight * (1 + zoomLevel / 100.0);
-                editable_image_mc._x = editableImageStartX + dx/2;
-                editable_image_mc._y = editableImageStartY + dy/2;
-                break;
-                
-            case 90:
-                editable_image_mc._rotation = 0;
-                editable_image_mc._width = editableImageStartWidth * (1 + zoomLevel / 100.0);
-                editable_image_mc._height = editableImageStartHeight * (1 + zoomLevel / 100.0);
-                editable_image_mc._rotation = nextDegree;
-                editable_image_mc._x = editableImageStartX - dx/2;
-                editable_image_mc._y = editableImageStartY + dy/2;
-                break;
-            
-            case 180:
-                editable_image_mc._width = editableImageStartWidth * (1 + zoomLevel / 100.0);
-                editable_image_mc._height = editableImageStartHeight * (1 + zoomLevel / 100.0);
-                editable_image_mc._x = editableImageStartX - dx/2;
-                editable_image_mc._y = editableImageStartY - dy/2;
-                break;
+            resetViewport();
+            updateFader();
+            saveChanges();
+        }
 
-            case 270:
-                editable_image_mc._rotation = 0;
-                editable_image_mc._width = editableImageStartWidth * (1 + zoomLevel / 100.0);
-                editable_image_mc._height = editableImageStartHeight * (1 + zoomLevel / 100.0);
-                editable_image_mc._rotation = nextDegree;
-                editable_image_mc._x = editableImageStartX + dx/2;
-                editable_image_mc._y = editableImageStartY - dy/2;
-                break;
+        // !TODO
+    }
+    
+    function onViewportRatioChange(ei:EventInfo)
+    {
+        var preset = ei.getInfo("preset");
+        var isLocked = preset.isRatioFixed;
+        
+        viewport_mc.setLocked(isLocked);
+        viewportOutputSize = null;
+        viewportMinSize = null;
+        viewportMaxSize = null;
+        viewportFixedRatio = 0;
+
+        if (!isLocked)
+        {
+            viewportFixedRatio = 1;
         }
-	}
-
+        else if (preset.ratio)
+        {
+            viewportFixedRatio = preset.ratio;
+        }
+        else 
+        {
+            if (preset.output_w && preset.output_h)
+            {
+                viewportFixedRatio = parseInt(preset.output_w) / parseInt(preset.output_h);
+                viewportOutputSize = new Point(parseInt(preset.output_w), parseInt(preset.output_h));
+            }
+            
+            if (preset.min_w && preset.min_h)
+            {
+                if (!viewportFixedRatio)
+                    viewportFixedRatio = parseInt(preset.min_w) / parseInt(preset.min_h);
+                viewportMinSize = new Point(parseInt(preset.min_w), parseInt(preset.min_h));
+            }
+            
+            if (preset.max_w && preset.max_h)
+            {
+                if (!viewportFixedRatio)
+                    viewportFixedRatio = parseInt(preset.max_w) / parseInt(preset.max_h);
+                viewportMaxSize = new Point(parseInt(preset.max_w), parseInt(preset.max_h));
+            }
+            
+            if (!viewportFixedRatio)
+                viewportFixedRatio = 1;
+        }        
+        
+        resetViewport();
+        updateFader();
+        saveChanges();
+    }
+    
     // event listeners --------------------------------------------------------------
     
     function onImageLoaded(ei:EventInfo)
     {
-        // save the original image dimensions
-        maxImageWidth = editable_image_mc._width;
-        maxImageHeight = editable_image_mc._height;
-        imageRatio = maxImageWidth / maxImageHeight;
-        
         // call resize once to setup everything up properly
         onResize();
 
-        // save the initial position and dimension of the image
-        editableImageStartX = editable_image_mc._x;
-        editableImageStartY = editable_image_mc._y;
-        editableImageStartWidth = editable_image_mc._width;
-        editableImageStartHeight = editable_image_mc._height;
+        imageAttitude = new EditableImageAttitude(editable_image_mc);
+        imageAttitude.addListener(this);        
+        imageAttitude.setOriginalSize(editable_image_mc._width, editable_image_mc._height);
+        
+        // first make the image fit into the canvas
+        fitImageToStage();
+        centerImage();
 
-        _visible = true;
-    }
-
-    function onImagePress(ei:EventInfo)
-    {
-        if (zoomLevel == 0)
-            return;
+        // then init the attitude object so we get the registration point right
+        imageAttitude.setTarget(editable_image_mc);
         
-        if (_xmouse < canvas_mc._x || _xmouse > canvas_mc._x + canvas_mc._width ||
-            _ymouse < canvas_mc._y || _ymouse > canvas_mc._y + canvas_mc._height)
-            return;
-        
-        dragCursorStartX = _level0._xmouse;
-        dragCursorStartY = _level0._ymouse;
-        dragImageStartX = editable_image_mc._x;
-        dragImageStartY = editable_image_mc._y;
-
-        onEnterFrame = dragImage;
-        Mouse.hide();
-        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._visible = true;
+        // if the image is rotated, do this first and then load changes
+        if (FlashvarManager.get("rotation") > 0)
+            imageAttitude.rotate(FlashvarManager.get("rotation"));
+        else
+            loadChanges();
     }
     
-    function onImageRelease(ei:EventInfo)
+    function onImageRotated(ei:EventInfo)
     {
-        if (zoomLevel == 0)
+        // if changes were not loaded yet, we had to rotate the image first - load changes now
+        if (!changesLoaded)
+        {
+            loadChanges();
             return;
+        }
         
-        onEnterFrame = null;
-        Mouse.show();
-        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._visible = false;
+        viewport_mc._visible = true;
+        resetViewport();
+        updateFader();
+        centerImage();
+        saveChanges();
     }
-    
-    // controller event listeners --------------------------------------------------------------
 
-    // menu event listeners --------------------------------------------------------------
-    
-    function onRotateLeftRelease(ei:EventInfo)
+    function onViewportPress(ei:EventInfo)
     {
-        nextDegree = (editable_image_mc._rotation - 90) % 360;
-        nextDegree = (nextDegree < 0) ? ( nextDegree + 360) : nextDegree;        
-        centerImage();
-        editable_image_mc._rotation = nextDegree;
+        var areaX = imageAttitude.x;
+        var areaY = imageAttitude.y;
+        var areaW = imageAttitude.x + imageAttitude.w - viewport_mc._width;
+        var areaH = imageAttitude.y + imageAttitude.h - viewport_mc._height;
+        viewport_mc.startDrag(false, areaX, areaY, areaW, areaH);
+        isViewportDragging = true;
     }
     
-    function onRotateRightRelease(ei:EventInfo)
+    function onViewportRelease(ei:EventInfo)
     {
-        nextDegree = (editable_image_mc._rotation + 90) % 360;
-        centerImage();
-        editable_image_mc._rotation = nextDegree;
+        viewport_mc.stopDrag();
+        updateFader();
+        isViewportDragging = false;
+        saveChanges();
     }
+
+    function onDragElementPress(ei:EventInfo)
+    {
+        currentDragElement = ei.getInfo("type");
+        viewportStartPoint = new Point(viewport_mc._x, viewport_mc._y);
+        viewportStartSize = new Point(viewport_mc._width, viewport_mc._height);
+        dragStartPoint = new Point(ei.getInfo("dragStartX"), ei.getInfo("dragStartY"));
+        isElementDragging = true;
+    }
     
-    function onZoomInPress(ei:EventInfo)
+    function onDragElementRelease(ei:EventInfo)
     {
-        onEnterFrame = function() { zoomImage(1, 2); }
+        isElementDragging = false;
+        saveChanges();
+    }    
+
+    function onKeyDown()
+    {
+        var offset = Key.isDown(Key.SHIFT) ? 5 : 1;
+
+        switch(Key.getCode())
+        {
+            case Key.UP:
+                moveViewportBy(0, -offset);
+                break;
+                
+            case Key.DOWN:
+                moveViewportBy(0, offset);
+                break;
+                
+            case Key.LEFT:
+                moveViewportBy(-offset, 0);
+                break;
+                
+            case Key.RIGHT:
+                moveViewportBy(offset, 0);
+                break;
+        }        
     }
     
-    function onZoomInRelease(ei:EventInfo)
+    function onMouseDown()
     {
-        onEnterFrame = null;
+        if (!isOverImage(_xmouse, _ymouse))
+            return;
+        
+        if (imageAttitude.w <= canvas_mc._width && imageAttitude.h <= canvas_mc._height)
+            return;
+
+        startDragImage();
     }
     
-    function onZoomOutPress(ei:EventInfo)
+    function onMouseUp()
     {
-        onEnterFrame = function() { zoomImage(-1, 2); }
+        stopDragImage();
     }
     
-    function onZoomOutRelease(ei:EventInfo)
+    function onImageRollOver(ei:EventInfo)
     {
-        onEnterFrame = null;
+        /*
+        if (imageCanBeDragged())
+        {
+            onEnterFrameUpdateDragCursor();
+            _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._visible = true;
+            Mouse.hide();
+            onEnterFrame = onEnterFrameUpdateDragCursor;
+        }
+        else
+        {
+            _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._visible = false;
+            Mouse.show();
+            onEnterFrame = onEnterFrameUpdateViewport;
+        }
+        */
     }
     
-    function onAbortRelease(ei:EventInfo)
+    function onEnterFrameUpdateDragCursor()
     {
-
+        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._x = _level0._xmouse;
+        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._y = _level0._ymouse;
     }
     
-    function onAcceptRelease(ei:EventInfo)
+    function onImageRollOut(ei:EventInfo)
     {
-        saveChanges();
+        /*
+        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._visible = false;
+        Mouse.show();
+        onEnterFrame = onEnterFrameUpdateViewport;
+        */
     }
     
     public function onResize()
@@ -386,99 +906,94 @@
         canvas_mc._y = PADDING;
         
         centerImage();
-    }
-    
-    // helpers ----------------------------------------------------------------------------
-    
-    function dragImage()
-    {
-        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._x = _level0._xmouse;
-        _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc._y = _level0._ymouse;
+        resetViewport();
         
-        var nextX = dragImageStartX + _xmouse - dragCursorStartX;
-        var nextY = dragImageStartY + _ymouse - dragCursorStartY;
-        if (nextX <= canvas_mc._x && nextX + editable_image_mc._width >= canvas_mc._x + canvas_mc._width)
-            editable_image_mc._x = nextX;
-
-        if (nextY <= canvas_mc._y && nextY + editable_image_mc._height >= canvas_mc._y + canvas_mc._height)
-            editable_image_mc._y = nextY;
+        if (changesLoaded)
+        {
+            updateFader();
+            saveChanges();
+        }
     }
     
-    private function centerImage()
+    private function updateFader()
     {
-        fitImage();
+        var x = 0;
+        var y = 0;
+        var w = 0;
+        var h = 0;
         
-        var dx = canvas_mc._width - editable_image_mc._width;
-        var dy = canvas_mc._height - editable_image_mc._height;
-
-        switch(nextDegree)
+        switch(imageAttitude.r)
         {
             case 0:
-                editable_image_mc._x = canvas_mc._x + dx/2;
-                editable_image_mc._y = canvas_mc._y + dy/2;
+                x = viewport_mc._x - imageAttitude.x;
+                y = viewport_mc._y - imageAttitude.y;
+                w = viewport_mc._width;
+                h = viewport_mc._height;
                 break;
                 
             case 90:
-                editable_image_mc._x = canvas_mc._x + editable_image_mc._width + dx/2;
-                editable_image_mc._y = canvas_mc._y + dy/2;
+                x = imageAttitude.y + imageAttitude.h - (viewport_mc._y + viewport_mc._height);
+                y = viewport_mc._x - imageAttitude.x;
+                w = viewport_mc._height;
+                h = viewport_mc._width;
                 break;
-            
+
             case 180:
-                editable_image_mc._x = canvas_mc._x + editable_image_mc._width + dx/2;
-                editable_image_mc._y = canvas_mc._y + editable_image_mc._height + dy/2;
+                x = imageAttitude.w - viewport_mc._x + imageAttitude.x - viewport_mc._width;
+                y = imageAttitude.h - viewport_mc._y + imageAttitude.y - viewport_mc._height;
+                w = viewport_mc._width;
+                h = viewport_mc._height;
                 break;
-                
+
             case 270:
-                editable_image_mc._x = canvas_mc._x + dx/2;
-                editable_image_mc._y = canvas_mc._y + editable_image_mc._height + dy/2;
+                x = viewport_mc._y - imageAttitude.y;
+                y = imageAttitude.w - viewport_mc._x + imageAttitude.x - viewport_mc._width;
+                w = viewport_mc._height;
+                h = viewport_mc._width;
                 break;
         }
+        
+        x = Math.max(0, Math.round(x));
+        y = Math.max(0, Math.round(y));
+        w = Math.min(imageAttitude.w, Math.round(w))
+        h = Math.min(imageAttitude.h, Math.round(h));
 
-        editableImageStartX = editable_image_mc._x;
-        editableImageStartY = editable_image_mc._y;
+        editable_image_mc.setVisibleArea(new Rectangle(x, y, w, h));
     }
     
-    private function fitImage()
+    // helpers -------------------------------------------------------------------------
+    
+    public function isWithinCanvas(x:Number, y:Number, w:Number, h:Number)
     {
-        editable_image_mc._rotation = 0;
-
-        var dW = editable_image_mc._width - canvas_mc._width;
-        var dH = editable_image_mc._height - canvas_mc._height;
-
-        switch(nextDegree)
-        {
-            case 0:
-            case 180:
-                if (dW < dH)
-                {
-                    editable_image_mc._width = canvas_mc._height * imageRatio;
-                    editable_image_mc._height = canvas_mc._height;
-                }
-                else
-                {
-                    editable_image_mc._width = canvas_mc._width;
-                    editable_image_mc._height = canvas_mc._width / imageRatio;
-                }
-                break;
-                
-            case 90:
-            case 270:            
-                if (dW < dH)
-                {
-                    editable_image_mc._width = canvas_mc._height;
-                    editable_image_mc._height = canvas_mc._height / imageRatio;
-                }
-                else
-                {
-                    editable_image_mc._width = canvas_mc._width * imageRatio;
-                    editable_image_mc._height = canvas_mc._width;
-                }
-                break;
-        }
-        
-        editableImageStartWidth = editable_image_mc._width;
-        editableImageStartHeight = editable_image_mc._height;
-        editable_image_mc._rotation = nextDegree;
-        zoomLevel = 0;
-    }    
+        w = (w == undefined) ? 0 : w;
+        h = (h == undefined) ? 0 : h;
+        return (x >= canvas_mc._x) && (x < canvas_mc._x + canvas_mc._width) &&  (y >= canvas_mc._y) && (y < canvas_mc._y + canvas_mc._height);
+    }
+    
+    public function isWithinImage(x:Number, y:Number, w:Number, h:Number)
+    {
+        w = (w == undefined) ? 0 : w;
+        h = (h == undefined) ? 0 : h;
+        return (x >= imageAttitude.x) && (x + w < imageAttitude.x + imageAttitude.w) && (y >= imageAttitude.y) && (y + h < imageAttitude.y + imageAttitude.h);
+    }
+    
+    public function isWithinViewport(x:Number, y:Number)
+    {
+        return (x >= viewport_mc._x) && (x < viewport_mc._x + viewport_mc._width) &&  (y >= viewport_mc._y) && (y < viewport_mc._y + viewport_mc._height);
+    }
+    
+    public function isOverImage(x:Number, y:Number)
+    {
+        return isWithinCanvas(x, y) && isWithinImage(x, y) && !isWithinViewport(x, y);
+    }
+    
+    public function imageCanBeDragged():Boolean
+    {
+        return imageAttitude.w > canvas_mc._width || imageAttitude.h > canvas_mc._height;
+    }
+    
+    public function isOverController(x:Number, y:Number)
+    {
+        return (x >= controller_mc._x) && (y >= controller_mc._y) && (x < controller_mc._x + controller_mc._width) && (y < controller_mc._y + controller_mc._height);
+    }
 }

Added: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/MovieclipAttitude.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/MovieclipAttitude.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/MovieclipAttitude.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,234 @@
+/**
+* z3c.reference.imagetool.baseskin.MovieclipAttitude 
+* helper class to get the coordinates and dimensions in global space for a specified movieclip
+* makes sure we get the global width and heights for rotated movieclips
+* converts funny flash rotations to 'normal' rotations (0, 90, 180, 270) / (0, -90, -180, -270)
+* 
+* extends EventBroadcaster so that subclasses can fire events if they need to
+*
+* @author <gerold.boehler at lovelysystems.com>
+*/
+
+class z3c.reference.imagetool.baseskin.MovieclipAttitude extends z3c.reference.imagetool.core.EventBroadcaster
+{
+    private var mX:Number = 0;
+    private var mY:Number = 0;
+    private var mW:Number = 1;
+    private var mH:Number = 1;
+    private var mIw:Number = 1;
+    private var mIh:Number = 1;
+    private var mOw:Number = 1;
+    private var mOh:Number = 1;
+    private var mR:Number = 0;  // in flash rotations
+    
+    private var mc:MovieClip;
+    
+    function MovieclipAttitude()
+    {
+        super();
+    }
+    
+    // only used to remember the original dimensions
+    public function setOriginalSize(w:Number, h:Number)
+    {
+        mOw = w;
+        mOh = h;
+    }
+    
+    // important: pass the mc without rotations applied!!!
+    public function setTarget(mc_:MovieClip)
+    {
+        mc = mc_;
+        mX = mc._x;
+        mY = mc._y;
+        mW = mc._width;
+        mH = mc._height;
+        mIw = mW;
+        mIh = mH;
+
+        updatePosition();
+    }
+    
+    public function set x(value:Number)
+    {
+        if (mc._rotation == 0 || mc._rotation == -90)
+            mc._x = value;
+        else if (mc._rotation == 180 || mc._rotation == 90)
+            mc._x = value + w;
+            
+        updatePosition();
+    }
+    
+    public function set y(value:Number)
+    {
+        if (mc._rotation == 0 || mc._rotation == 90)
+            mc._y = value;
+        else if (mc._rotation == 180 || mc._rotation == -90)
+            mc._y = value + h;
+            
+        updatePosition();
+    }
+    
+    public function set r(value:Number)
+    {
+        mR = value % 360;
+        
+        if (mR == 0)
+            mc._rotation = 0;
+        if (mR == 90)
+            mc._rotation = -90;
+        else if (mR == -90)
+            mc._rotation = 90;
+        else if (mR == 180 || mR == -180)
+            mc._rotation = 180;
+        else if (mR == 270 || mR == -270)
+            mc._rotation = -mR;
+            
+        updatePosition();
+    }
+    
+    public function get w():Number
+    {
+        if (mc._rotation == 0 || mc._rotation == 180)
+            return mW;
+        else if (mc._rotation == 90 || mc._rotation == -90)
+            return mH;
+            
+        return 1;
+    }
+
+    public function get h():Number
+    {
+        if (mc._rotation == 0 || mc._rotation == 180)
+            return mH;
+        else if (mc._rotation == 90 || mc._rotation == -90)
+            return mW;
+            
+        return 1;
+    }
+    
+    public function set w(value:Number)
+    {
+        var rot = mc._rotation;
+        mc._rotation = 0;
+        if (rot == 0 || rot == 180)
+        {
+            mW = value;
+            mc._width = mW;
+        }
+        else if (rot == 90 || rot == -90)
+        {
+            mH = value;
+            mc._height = mH;
+        }
+        mc._rotation = rot;
+        
+        updatePosition();
+    }
+    
+    public function set h(value:Number)
+    {
+        var rot = mc._rotation;
+        mc._rotation = 0;
+        if (rot == 0 || rot == 180)
+        {
+            mH = value;
+            mc._height = mH;
+        }
+        else if (rot == 90 || rot == -90)
+        {
+            mW = value
+            mc._width = mW;
+        }
+        mc._rotation = rot;
+        
+        updatePosition();
+    }
+    
+    public function get x():Number
+    {
+        return mX;
+    }
+
+    public function get y():Number
+    {
+        return mY;
+    }
+    
+    public function get initialWidth():Number
+    {
+        if (mc._rotation == 0 || mc._rotation == 180)
+            return mIw;
+        else if (mc._rotation == 90 || mc._rotation == -90)
+            return mIh;
+    }
+    
+    public function get initialHeight():Number
+    {
+        if (mc._rotation == 0 || mc._rotation == 180)
+            return mIh;
+        else if (mc._rotation == 90 || mc._rotation == -90)
+            return mIw;
+    }
+    
+    public function get originalWidth():Number
+    {
+        if (!mc)
+            return mOw;
+        else if (mc._rotation == 0 || mc._rotation == 180)
+            return mOw;
+        else if (mc._rotation == 90 || mc._rotation == -90)
+            return mOh;
+    }
+    
+    public function get originalHeight():Number
+    {
+        if (!mc)
+            return mOh;
+        else if (mc._rotation == 0 || mc._rotation == 180)
+            return mOh;
+        else if (mc._rotation == 90 || mc._rotation == -90)
+            return mOw;
+    }
+    
+    public function get originalRatio():Number
+    {
+        return originalWidth / originalHeight;
+    }
+    
+    public function get r():Number
+    {
+        return mR;
+    }
+
+    // helpers ---------------------------------------------------------------
+
+    private function updatePosition()
+    {
+        if (mc._rotation == 0)
+        {
+            mX = mc._x;
+            mY = mc._y;
+        }
+        else if (mc._rotation == 180)
+        {
+            mX = mc._x - w;
+            mY = mc._y - h;
+        }
+        else if (mc._rotation == -90)
+        {
+            mX = mc._x;
+            mY = mc._y - h;
+        }
+        else if (mc._rotation == 90)
+        {
+            mX = mc._x - w;
+            mY = mc._y;
+        }
+    }
+    
+    public function toString()
+    {
+        return " x: " + x + " y: " + y + " w: " + w + " h: " + h + " r: " + r;
+    }
+}
\ No newline at end of file

Added: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Seam.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Seam.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Seam.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,177 @@
+import flash.display.BitmapData;
+import flash.geom.Rectangle;
+import z3c.reference.imagetool.baseskin.*;
+
+class z3c.reference.imagetool.baseskin.Seam
+{
+	var _start: Number;
+	var _direction: Number;
+	var _points: SeamPoint;
+	var _energy: Number;
+	
+	public function Seam() {}
+	
+	public function set start(value:Number)
+	{
+		_start = value;
+		
+		_points = new SeamPoint;
+		
+		if ( _direction == SeamDirection.H )
+		{
+			_points.x = 0;
+			_points.y = _start;
+		}
+		else
+		{
+			_points.x = _start;
+			_points.y = 0;
+		}
+	}
+	
+	public function get points(): SeamPoint
+	{
+		return _points;
+	}
+	
+	public function set direction(value:Number)
+	{
+		_direction = value;
+	}
+	
+	public function get energy(): Number
+	{
+		return _energy;
+	}
+	
+	
+	public function bake( energyMap:BitmapData, filterRect:Rectangle, bestEnergy:Number )
+	{
+		var point: SeamPoint = _points;
+		var o: Number = _start;
+		var isV: Boolean = ( _direction == SeamDirection.V );
+		var end: Number = ( isV ) ? filterRect.height : filterRect.width;
+		var endO: Number = ( isV ) ? filterRect.width : filterRect.height;
+		var differenceTotal: Number;
+		var energy: Number;
+		var e0: Number, e1: Number, e2: Number;
+		var d0: Number, d1: Number, d2: Number;
+		var min: Number;
+		
+		_energy = 0;
+		
+		if ( isV )
+		{
+			energy = energyMap.getPixel( o, 0 );
+		} else {
+			energy = energyMap.getPixel( 0, o );
+		}	
+		
+		
+		
+		for ( var p: Number = 1; p < end; p++ )
+		{
+			point = point.next = new SeamPoint;
+			
+			if ( isV )
+			{
+				e0 = o > 0 ? energyMap.getPixel( o - 1, p ) : 0x100 | energy;
+				e1 = energyMap.getPixel( o, p );
+				e2 = o < endO ? energyMap.getPixel( o + 1, p ) : 0x100 | energy;
+				
+				d0 = energy ^ e0;
+				d1 = energy ^ e1;
+				d2 = energy ^ e2;
+				
+				if ( d0 < d1 )
+				{
+					if ( d0 < d2 )
+					{
+						o--;
+						energy = e0;
+						if ( o < 0 ) o = 0;
+						min = d0;
+					} else {
+						o++;
+						energy = e2;
+						if ( o > endO ) o = endO ;
+						min =  d2; 
+					}
+				} else {
+					if ( d1 <= d2 )
+					{
+						energy = e1;
+						min = d1;
+					} else {
+						o++;
+						energy = e2;
+						if ( o > endO ) o = endO;
+						min =  d2; 
+					}	
+				}
+				
+				point.x = o;
+				point.y = p;
+			}
+			else
+			{
+				e0 = o > 0 ? energyMap.getPixel( p, o - 1) : 0x100 | energy;
+				e1 = energyMap.getPixel( p, o    );
+				e2 = o < endO ? energyMap.getPixel( p, o + 1) : 0x100 | energy;
+				
+				d0 = energy ^ e0;
+				d1 = energy ^ e1;
+				d2 = energy ^ e2;
+				
+				if ( d0 < d1 )
+				{
+					if ( d0 < d2 )
+					{
+						o--;
+						energy = e0;
+						if ( o < 0 ) o = 0;
+						min = d0;
+					} else {
+						o++;
+						energy = e2;
+						if ( o > endO ) o = endO ;
+						min =  d2; 
+					}
+				} else {
+					if ( d1 <= d2 )
+					{
+						energy = e1;
+						min = d1;
+					} else {
+						o++;
+						energy = e2;
+						if ( o > endO ) o = endO;
+						min =  d2; 
+					}	
+				
+				}
+				
+				point.x = p;
+				point.y = o;
+			}
+			_energy += min;
+			if (_energy> bestEnergy)
+			{
+				_energy = Number.MAX_VALUE;
+				return;
+			}
+		}
+	}
+	
+	
+	public function walk( func: Function )
+	{
+		var p: SeamPoint = _points;
+		
+		while ( p )
+		{
+			func( p.x, p.y );
+			p = p.next;	
+		}	
+	}	
+}
\ No newline at end of file

Added: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/SeamDirection.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/SeamDirection.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/SeamDirection.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,6 @@
+
+class z3c.reference.imagetool.baseskin.SeamDirection
+{
+	public static var V: Number = 0;
+	public static var H: Number = 1;
+}

Added: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/SeamPoint.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/SeamPoint.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/SeamPoint.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,9 @@
+import z3c.reference.imagetool.baseskin.*;
+
+class z3c.reference.imagetool.baseskin.SeamPoint
+{
+	public var x: Number;
+	public var y: Number;
+	
+	public var next: SeamPoint;
+}

Added: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Slider.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Slider.as	                        (rev 0)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Slider.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -0,0 +1,96 @@
+/*
+ *  the slider for zooming the image
+ *
+ *  @author <gerold.boehler at lovelysystems.com>
+ */
+
+import z3c.reference.imagetool.core.*;
+import z3c.reference.imagetool.baseskin.*;
+
+
+[Event("onSliderPress")]
+[Event("onSliderRelease")]
+[Event("onSliderChange")]
+
+
+class z3c.reference.imagetool.baseskin.Slider extends Component
+{
+    private var line_mc:MovieClip;
+    private var button_mc:MovieClip;
+
+    private var maxLength:Number = 0;
+    private var currentPercent:Number = 0;
+    
+    // from attachMovie
+    private var width:Number = 1;
+    
+	function Slider()
+	{
+        super();
+        
+        createEmptyMovieClip("line_mc", getNextHighestDepth());
+        line_mc.clear();
+        line_mc.lineStyle(0, 0x000000, 100);
+        line_mc.moveTo(0, 0);
+        line_mc.lineTo(width, 0);
+        line_mc.endFill();
+        line_mc._y = 6;
+
+        createEmptyMovieClip("button_mc", getNextHighestDepth());
+        button_mc.clear();
+        button_mc.beginFill(0xc0c0c0, 100);
+        button_mc.moveTo(0, 0);
+        button_mc.lineTo(12, 0);
+        button_mc.lineTo(12, 12);
+        button_mc.lineTo(0, 12);
+        button_mc.endFill();
+        button_mc._y = 0;
+        
+        maxLength = width - button_mc._width;
+
+        button_mc.onPress = function() { _parent.onButtonPress(); }
+        button_mc.onRelease = button_mc.onReleaseOutside = function() { _parent.onButtonRelease(); }
+        
+        var shadow = new flash.filters.DropShadowFilter(1);
+        filters = [shadow];
+    }
+    
+    public function setPercent(percent:Number)
+    {
+        button_mc._x = 0;
+        dragSlider();
+    }
+    
+    function onButtonPress()
+    {
+        button_mc.startDrag(false, 0, 0, width - button_mc._width, 0)
+        onEnterFrame = dragSlider;
+
+        var ei:EventInfo = new EventInfo(this, "onSliderPress");
+        ei.setInfo("percent", currentPercent);
+        broadcastEvent(ei);
+    }
+    
+    function onButtonRelease()
+    {
+        dragSlider();
+        button_mc.stopDrag();
+        onEnterFrame = null;
+
+        var ei:EventInfo = new EventInfo(this, "onSliderRelease");
+        ei.setInfo("percent", currentPercent);
+        broadcastEvent(ei);
+    }
+    
+    function dragSlider()
+    {
+        var nextPercent = button_mc._x / maxLength;
+        if (nextPercent == currentPercent)
+            return;
+            
+        currentPercent = nextPercent;
+        var ei:EventInfo = new EventInfo(this, "onSliderChange");
+        ei.setInfo("percent", currentPercent);
+        broadcastEvent(ei);
+    }
+}

Modified: z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Viewport.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Viewport.as	2007-09-18 09:01:27 UTC (rev 79731)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/baseskin/Viewport.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -24,12 +24,16 @@
     private var corner_RT:MovieClip;
     private var corner_LB:MovieClip;
     private var corner_RB:MovieClip;
+    private var current_top_corner:MovieClip;       // save the currently topmost corner
     
-    private var linePointerDegrees:Object;
-    private var cornerPointerDegrees:Object;
+    private var dragPointerDegrees:Object;
     
     private var current_pointer_mc:MovieClip;
     
+    private var width:Number;
+    private var height:Number;
+    private var isLocked:Boolean = false;
+    
 	function Viewport()
 	{
 	    super();
@@ -37,20 +41,17 @@
 	    createEmptyMovieClip("drag_area_mc", getNextHighestDepth());
 	    initDragArea(drag_area_mc);
 
-        if (!FlashvarManager.get("keepAspectRatio"))
-        {
-    	    createEmptyMovieClip("line_left_mc", getNextHighestDepth());
-    	    initLine(line_left_mc, "L");
+	    createEmptyMovieClip("line_left_mc", getNextHighestDepth());
+	    initLine(line_left_mc, "L");
 
-    	    createEmptyMovieClip("line_right_mc", getNextHighestDepth());
-    	    initLine(line_right_mc, "R");
+	    createEmptyMovieClip("line_right_mc", getNextHighestDepth());
+	    initLine(line_right_mc, "R");
 
-    	    createEmptyMovieClip("line_top_mc", getNextHighestDepth());
-    	    initLine(line_top_mc, "T");
+	    createEmptyMovieClip("line_top_mc", getNextHighestDepth());
+	    initLine(line_top_mc, "T");
 
-    	    createEmptyMovieClip("line_bottom_mc", getNextHighestDepth());
-    	    initLine(line_bottom_mc, "B");
-        }
+	    createEmptyMovieClip("line_bottom_mc", getNextHighestDepth());
+	    initLine(line_bottom_mc, "B");
         
 	    createEmptyMovieClip("corner_LT", getNextHighestDepth());
 	    initCorner(corner_LT, "LT");
@@ -64,113 +65,119 @@
 	    createEmptyMovieClip("corner_RB", getNextHighestDepth());
 	    initCorner(corner_RB, "RB");
 	    
-	    linePointerDegrees = new Object();
-	    linePointerDegrees.L = 90;
-	    linePointerDegrees.R = 270;
-	    linePointerDegrees.T = 180;
-	    linePointerDegrees.B = 0;
+	    current_top_corner = corner_RB;
 	    
-	    cornerPointerDegrees = new Object();
-	    cornerPointerDegrees.LT = 135;
-	    cornerPointerDegrees.RT = 225;
-	    cornerPointerDegrees.LB = 45;
-	    cornerPointerDegrees.RB = 315;
+	    dragPointerDegrees = new Object();
+	    dragPointerDegrees.L = 90;
+	    dragPointerDegrees.R = 270;
+	    dragPointerDegrees.T = 180;
+	    dragPointerDegrees.B = 0;
+	    dragPointerDegrees.LT = 135;
+	    dragPointerDegrees.RT = 225;
+	    dragPointerDegrees.LB = 45;
+	    dragPointerDegrees.RB = 315;
     }
     
-    public function init()
+    public function setLocked(locked:Boolean)
     {
-        var w = FlashvarManager.get("crop_w");
-        var h = FlashvarManager.get("crop_h");
-        
-        drag_area_mc.clear();
-        drag_area_mc.lineStyle(0, 0xc0c0c0, 100);
-	    drag_area_mc.beginFill(0xff0000, 0);
-	    drag_area_mc.moveTo(0, 0);
-	    drag_area_mc.lineTo(w, 0);
-	    drag_area_mc.lineTo(w, h);
-	    drag_area_mc.lineTo(0, h);
-	    drag_area_mc.endFill();
-	    
-	    redrawSensitiveAreas(w, h, SENSITIVE_AREA);
-	    repositionSensitiveAreas(w, h);
+        isLocked = locked;
+        updateDragElements();
     }
     
-    public function updateSensitiveAreas(maxW:Number, maxH:Number)
+    public function getLocked():Boolean
     {
-        /*
-        var dx = _width - FlashvarManager.get("crop_w");
-        var dy = _height - FlashvarManager.get("crop_h");
-        var dxMax = maxW - FlashvarManager.get("crop_w");
-        var dyMax = maxH - FlashvarManager.get("crop_h");
-        var scaleX = 1 - dx / dxMax;
-        var scaleY = 1 - dy / dxMax;
-        */
-        //redrawSensitiveAreas(maxW, maxH, SENSITIVE_AREA);
-	    //redrawSensitiveAreas(_width, _height, SENSITIVE_AREA);
-	    //repositionSensitiveAreas(_width, _height);
+        return isLocked;
     }
     
-    private function redrawSensitiveAreas(w:Number, h:Number, size:Number)
+    public function setSize(w:Number, h:Number)
     {
-        if (!FlashvarManager.get("keepAspectRatio"))
-        {
-    	    drawRectangle(line_left_mc, 0, 0, size, h);
-    	    drawRectangle(line_right_mc, 0, 0, size, h);
-    	    drawRectangle(line_top_mc, 0, 0, w, size);
-    	    drawRectangle(line_bottom_mc, 0, 0, w, size);
-        }
-
-        drawRectangle(corner_LT, 0, 0, 2*size, 2*size);
-        drawRectangle(corner_RT, 0, 0, 2*size, 2*size);
-        drawRectangle(corner_LB, 0, 0, 2*size, 2*size);
-        drawRectangle(corner_RB, 0, 0, 2*size, 2*size);
+        setWidth(w);
+        setHeight(h);
     }
     
-    private function repositionSensitiveAreas(w:Number, h:Number)
+    public function setWidth(w:Number, ratio:Number)
     {
-        if (!FlashvarManager.get("keepAspectRatio"))
+        width = w;
+        if (ratio)
+            height = w / ratio;
+        
+	    updateDragElements();
+    }
+    
+    public function setHeight(h:Number, ratio:Number)
+    {
+        height = h;
+        if (ratio)
+            width = h * ratio;
+        
+	    updateDragElements();
+    }
+    
+    private function updateDragElements()
+    {
+        drag_area_mc.clear();
+        drag_area_mc.lineStyle(0, 0xffffff, 100);
+	    drag_area_mc.beginFill(0xabcdef, 0)
+	    drag_area_mc.moveTo(0, 0);
+	    drag_area_mc.lineTo(width, 0);
+	    drag_area_mc.lineTo(width, height);
+	    drag_area_mc.lineTo(0, height);
+	    drag_area_mc.endFill();
+	    
+        if (isLocked)
         {
-            line_left_mc._x = 0;
-            line_left_mc._y = 0;
+            line_left_mc.clear();
+            line_right_mc.clear();
+            line_top_mc.clear();
+            line_bottom_mc.clear();
+        }
+        else
+        {
+    	    drawRectangle(line_left_mc, 0, 0, SENSITIVE_AREA, height);
+    	    drawRectangle(line_right_mc, 0, 0, SENSITIVE_AREA, height);
+    	    drawRectangle(line_top_mc, 0, 0, width, SENSITIVE_AREA);
+    	    drawRectangle(line_bottom_mc, 0, 0, width, SENSITIVE_AREA);
+        }
 
-            line_right_mc._x = w - line_right_mc._width;
-            line_right_mc._y = 0;
+        line_left_mc._x = 0;
+        line_left_mc._y = 0;
 
-            line_top_mc._x = 0;
-            line_top_mc._y = 0;
+        line_right_mc._x = width - line_right_mc._width;
+        line_right_mc._y = 0;
 
-            line_bottom_mc._x = 0;
-            line_bottom_mc._y = h - line_bottom_mc._height;
-        }
+        line_top_mc._x = 0;
+        line_top_mc._y = 0;
 
+        line_bottom_mc._x = 0;
+        line_bottom_mc._y = height - line_bottom_mc._height;
+
+        drawRectangle(corner_LT, 0, 0, 2*SENSITIVE_AREA, 2*SENSITIVE_AREA, 0xffffff, 100);
+        drawRectangle(corner_RT, 0, 0, 2*SENSITIVE_AREA, 2*SENSITIVE_AREA, 0xffffff, 100);
+        drawRectangle(corner_LB, 0, 0, 2*SENSITIVE_AREA, 2*SENSITIVE_AREA, 0xffffff, 100);
+        drawRectangle(corner_RB, 0, 0, 2*SENSITIVE_AREA, 2*SENSITIVE_AREA, 0xffffff, 100);
+
         corner_LT._x = 0;
         corner_LT._y = 0;
         
-        corner_RT._x = w - corner_RT._width;
+        corner_RT._x = width - corner_RT._width;
         corner_RT._y = 0;
         
         corner_LB._x = 0;
-        corner_LB._y = h - corner_LB._height;
+        corner_LB._y = height - corner_LB._height;
         
-        corner_RB._x = w - corner_RB._width;
-        corner_RB._y = h - corner_RB._height;
+        corner_RB._x = width - corner_RB._width;
+        corner_RB._y = height - corner_RB._height;
     }
     
-    private function drawRectangle(mc:MovieClip, x:Number, y:Number, w:Number, h:Number)
+    // event listeners --------------------------------------------------------------
+    
+    function onViewportRatioChange(ei:EventInfo)
     {
-	    mc._x = x;
-	    mc._y = y;
-	    mc.clear();
-	    mc.beginFill(0x0000ff, 100)
-	    mc.moveTo(0, 0);
-	    mc.lineTo(w, 0);
-	    mc.lineTo(w, h);
-	    mc.lineTo(0, h);
-	    mc.endFill();
+        var ratio = ei.getInfo("ratio");
+        isLocked = !!ratio;
+        updateDragElements()
     }
     
-    // event listeners --------------------------------------------------------------
-    
     function onDragAreaRollOver(area:MovieClip)
     {
         current_pointer_mc = _level0.imagetool_mc.mousepointer_mc.pointer_drag_mc;
@@ -197,146 +204,111 @@
         var ei:EventInfo = new EventInfo(this, "onViewportRelease");
         broadcastEvent(ei);
     }
-    
-    function onLineRollOver(line_mc:MovieClip)
-    {
-        current_pointer_mc = _level0.imagetool_mc.mousepointer_mc.pointer_line_mc;
-        onEnterFrame();
-        Mouse.hide();
-        current_pointer_mc._rotation = linePointerDegrees[line_mc.line] + _parent._rotation;
-        current_pointer_mc._visible = true;
-    }
-    
-    function onLineRollOut(line:MovieClip)
-    {
-        current_pointer_mc._visible = false;
-        current_pointer_mc = null;
-        Mouse.show();
-    }
-    
-    function onLinePress(line_mc:MovieClip)
-    {
-        var ei:EventInfo = new EventInfo(this, "onLinePress");
-        ei.setInfo("line", line_mc.line);
 
-        switch(line_mc.line)
-        {
-            case "L":
-                ei.setInfo("offsetX", line_mc._xmouse);
-                ei.setInfo("offsetY", 0);
-                break;
-                
-            case "R":
-                ei.setInfo("offsetX", -(line_mc._width - line_mc._xmouse));
-                ei.setInfo("offsetY", 0);
-                break;
-                
-            case "T":
-                ei.setInfo("offsetX", 0);
-                ei.setInfo("offsetY", line_mc._ymouse);
-                break;
-                
-            case "B":
-                ei.setInfo("offsetX", 0);
-                ei.setInfo("offsetY", -(line_mc._height - line_mc._ymouse));
-                break;
-        }        
-
-        broadcastEvent(ei);
-    }
-    
-    function onLineRelease(line_mc:MovieClip)
+    function onDragElementRollOver(element_mc:MovieClip)
     {
-        if (!line_mc.hitTest(_level0._xmouse, _level0._ymouse, true))
-            onLineRollOut();
-            
-        var ei:EventInfo = new EventInfo(this, "onLineRelease");
-        broadcastEvent(ei);
-    }
-    
-    function onCornerRollOver(corner_mc:MovieClip)
-    {
         current_pointer_mc = _level0.imagetool_mc.mousepointer_mc.pointer_corner_mc;
         onEnterFrame();
         Mouse.hide();
-        current_pointer_mc._rotation = cornerPointerDegrees[corner_mc.corner] + _parent._rotation;
+        current_pointer_mc._rotation = dragPointerDegrees[element_mc.type];
         current_pointer_mc._visible = true;
     }
     
-    function onCornerRollOut(line:MovieClip)
+    function onDragElementRollOut(line:MovieClip)
     {
         current_pointer_mc._visible = false;
         current_pointer_mc = null;
         Mouse.show();
     }
     
-    function onCornerPress(corner_mc:MovieClip)
+    function onDragElementPress(element_mc:MovieClip)
     {
-        var ei:EventInfo = new EventInfo(this, "onCornerPress");
-        ei.setInfo("corner", corner_mc.corner);
+        var type = element_mc.type;
+        var ei:EventInfo = new EventInfo(this, "onDragElementPress");
+        ei.setInfo("type", type);
         
-        switch(corner_mc.corner)
+        if (type == "LT")
         {
-            case "LT":
-                ei.setInfo("offsetX", corner_mc._xmouse);
-                ei.setInfo("offsetY", corner_mc._ymouse);
-                break;
-                
-            case "RT":
-                ei.setInfo("offsetX", -(corner_mc._width - corner_mc._xmouse));
-                ei.setInfo("offsetY", corner_mc._ymouse);
-                break;
-                
-            case "LB":
-                ei.setInfo("offsetX", corner_mc._xmouse);
-                ei.setInfo("offsetY", -(corner_mc._height - corner_mc._ymouse));
-                break;
-                
-            case "RB":
-                ei.setInfo("offsetX", -(corner_mc._width - corner_mc._xmouse));
-                ei.setInfo("offsetY", -(corner_mc._height - corner_mc._ymouse));
-                break;
+            ei.setInfo("dragStartX", _x + element_mc._x);
+            ei.setInfo("dragStartY", _y + element_mc._y);
+            current_top_corner.swapDepths(element_mc);
+            current_top_corner = element_mc;
         }
-        
+        else if (type == "RT")
+        {
+            ei.setInfo("dragStartX", _x + element_mc._x + element_mc._width);
+            ei.setInfo("dragStartY", _y + element_mc._y);
+            current_top_corner.swapDepths(element_mc);
+            current_top_corner = element_mc;
+        }
+        else if (type == "LB")
+        {
+            ei.setInfo("dragStartX", _x + element_mc._x);
+            ei.setInfo("dragStartY", _y + element_mc._y + element_mc._height);
+            current_top_corner.swapDepths(element_mc);
+            current_top_corner = element_mc;
+        }
+        else if (type == "RB")
+        {
+            ei.setInfo("dragStartX", _x + element_mc._x + element_mc._width);
+            ei.setInfo("dragStartY", _y + element_mc._y + element_mc._height);
+            current_top_corner.swapDepths(element_mc);
+            current_top_corner = element_mc;
+        }
+        else if (type == "L")
+        {
+            ei.setInfo("dragStartX", _x + element_mc._x)
+        }
+        else if (type == "R")
+        {
+            ei.setInfo("dragStartX", _x + element_mc._x + element_mc._width)
+        }
+        else if (type == "T")
+        {
+            ei.setInfo("dragStartY", _y + element_mc._y)
+        }
+        else if (type == "B")
+        {
+            ei.setInfo("dragStartY", _y + element_mc._y + element_mc._height)
+        }
+
         broadcastEvent(ei);
     }
     
-    function onCornerRelease(corner_mc:MovieClip)
+    function onDragElementRelease(element_mc:MovieClip)
     {
-        if (!corner_mc.hitTest(_level0._xmouse, _level0._ymouse, true))
-            onCornerRollOut();
+        onDragElementRollOut();
             
-        var ei:EventInfo = new EventInfo(this, "onCornerRelease");
+        var ei:EventInfo = new EventInfo(this, "onDragElementRelease");
         broadcastEvent(ei);
     }
-    
+
     function onEnterFrame()
     {
         if (current_pointer_mc)
         {
-            //Mouse.hide();
             current_pointer_mc._x = _level0._xmouse;
             current_pointer_mc._y = _level0._ymouse;
         }
-        else
-        {
-            /*
-            if (this.hitTest(_level0._xmouse, _level0._ymouse, true))
-                Mouse.hide();
-            else
-                Mouse.show();
-            */
-        }
-            
     }
     
-    public function onParentResize(w:Number, h:Number)
+    // helpers ----------------------------------------------------------------------------
+    
+    private function drawRectangle(mc:MovieClip, x:Number, y:Number, w:Number, h:Number, color:Number, alpha:Number)
     {
-
+        color = color ? color : 0xffffff;
+        alpha = alpha ? alpha : 0;
+	    mc._x = x;
+	    mc._y = y;
+	    mc.clear();
+	    mc.beginFill(color, alpha)
+	    mc.moveTo(0, 0);
+	    mc.lineTo(w, 0);
+	    mc.lineTo(w, h);
+	    mc.lineTo(0, h);
+	    mc.endFill();
     }
     
-    // helpers ----------------------------------------------------------------------------
-    
     private function initDragArea(area_mc:MovieClip)
     {
         area_mc.useHandCursor = false;
@@ -348,23 +320,23 @@
     
     private function initLine(line_mc:MovieClip, line:String)
     {
-        line_mc.line = line;
-        line_mc._alpha = 0;
+        line_mc.type = line;
+        line_mc._alpha = 100;
         line_mc.useHandCursor = false;
-	    line_mc.onRollOver = function() { _parent.onLineRollOver(this); }
-	    line_mc.onRollOut = function() { _parent.onLineRollOut(this); }
-        line_mc.onPress = function() { _parent.onLinePress(this); }
-        line_mc.onRelease = line_mc.onReleaseOutside = function() { _parent.onLineRelease(this); }
+	    line_mc.onRollOver = function() { _parent.onDragElementRollOver(this); }
+	    line_mc.onRollOut = function() { _parent.onDragElementRollOut(this); }
+        line_mc.onPress = function() { _parent.onDragElementPress(this); }
+        line_mc.onRelease = line_mc.onReleaseOutside = function() { _parent.onDragElementRelease(this); }
     }
     
     private function initCorner(corner_mc:MovieClip, corner:String)
     {
-        corner_mc.corner = corner;
-        corner_mc._alpha = 0;
+        corner_mc.type = corner;
+        corner_mc._alpha = 100;
         corner_mc.useHandCursor = false;
-	    corner_mc.onRollOver = function() { _parent.onCornerRollOver(this); }
-	    corner_mc.onRollOut = function() { _parent.onCornerRollOut(this); }
-        corner_mc.onPress = function() { _parent.onCornerPress(this); }
-        corner_mc.onRelease = corner_mc.onReleaseOutside = function() { _parent.onCornerRelease(this); }
+	    corner_mc.onRollOver = function() { _parent.onDragElementRollOver(this); }
+	    corner_mc.onRollOut = function() { _parent.onDragElementRollOut(this); }
+        corner_mc.onPress = function() { _parent.onDragElementPress(this); }
+        corner_mc.onRelease = corner_mc.onReleaseOutside = function() { _parent.onDragElementRelease(this); }
     }
 }

Modified: z3c.reference/trunk/flash/src/z3c/reference/imagetool/core/FlashvarManager.as
===================================================================
--- z3c.reference/trunk/flash/src/z3c/reference/imagetool/core/FlashvarManager.as	2007-09-18 09:01:27 UTC (rev 79731)
+++ z3c.reference/trunk/flash/src/z3c/reference/imagetool/core/FlashvarManager.as	2007-09-18 09:16:38 UTC (rev 79732)
@@ -1,82 +1,92 @@
-/*
- *  FlashvarManager.as
- *
- *  Manager for flashvars, use this instead of _level0.xxx to access a flashvar.
- *  Call oneTimeInit at the beginning of your application, the manager collects
- *  all variables on _level0, copies them to a object, decodes strings ('+' and '=')
- *  and parses numbers correctly...
- *
- *  @author <gerold.boehler at lovelysystems.com>
- *
- */
- 
-class z3c.reference.imagetool.core.FlashvarManager extends z3c.reference.imagetool.core.EventBroadcaster
-{
-	private static var _instance:z3c.reference.imagetool.core.FlashvarManager;
-	private var flashVars:Object;
-	
-	
-	function FlashvarManager()
-	{
-		flashVars = new Object();
-	}
-	
-	public static function oneTimeInit():Void
-	{
-	    for (var flashvar in _level0)
-	    {
-	        if (flashvar.indexOf("$") == 0)
-	            continue;
-
-	        getInstance().setVar(flashvar, decodeForFlash(_level0[flashvar]));
-	        delete _level0[flashvar];
-	    }
-	}
-	
-	private static function decodeForFlash(str:String)
-	{
-	    if (!isNaN(parseFloat(str)))
-	        return parseFloat(str);
-	        
-	    if (typeof(str) == "boolean")
-	        return str;
-		
-        if (str.toLowerCase() == "true" || str.toLowerCase == "false")
-            return str.toLowerCase() == "true";
-
-		str = str.split("[p]").join("+");
-		str = str.split("[e]").join("=");
-
-		return str;
-    }
-	
-	private function getVar(name:String):String
-	{
-		if (flashVars[name])
-			return flashVars[name];
-			
-		return undefined;
-	}
-	
-	private function setVar(name:String, value:String):Void
-	{
-	    flashVars[name] = value;
-	    trace("SETTING: " + name + " " + value)
-	}
-
-	public static function get(name:String)
-	{
-	    if (!getInstance().getVar(name)) {
-	        //getInstance().log("!ERROR! Flashvar " + name + " not found!");
-	    }
-	    return getInstance().getVar(name);
-	}
-	
-	public static function getInstance():FlashvarManager
-	{
-		if (!_instance) 
-			_instance = new FlashvarManager();
-			
-		return _instance;
-	}	
+/*
+ *  FlashvarManager.as
+ *
+ *  Manager for flashvars, use this instead of _level0.xxx to access a flashvar.
+ *  Call collectFlashVars at the beginning of your application, the manager collects
+ *  all variables on _level0, copies them to a object, decodes strings ('+' and '=')
+ *  and parses numbers correctly...
+ *
+ *  @author <gerold.boehler at lovelysystems.com>
+ *
+ */
+ 
+class z3c.reference.imagetool.core.FlashvarManager extends z3c.reference.imagetool.core.EventBroadcaster
+{
+	private static var _instance:z3c.reference.imagetool.core.FlashvarManager;
+	private var flashVars:Object;
+	
+	
+	function FlashvarManager()
+	{
+		flashVars = new Object();
+	}
+	
+	public static function collectFlashVars():Void
+	{
+	    for (var flashvar in _level0)
+	    {
+	        if (flashvar.indexOf("$") == 0)
+	            continue;
+
+	        getInstance().setVar(flashvar, decodeForFlash(_level0[flashvar]));
+	        delete _level0[flashvar];
+	    }
+	}
+	
+	private static function decodeForFlash(str:String)
+	{
+	    if (!isNaN(parseFloat(str)))
+	        return parseFloat(str);
+	        
+	    if (typeof(str) == "boolean")
+	        return str;
+
+        if (str.toLowerCase() == "true" || str.toLowerCase() == "false")
+            return str.toLowerCase() == "true";
+
+		str = str.split("[p]").join("+");
+		str = str.split("[e]").join("=");
+
+		return str;
+    }
+	
+	private function getVar(name:String):String
+	{
+		if (flashVars[name] != undefined)
+			return flashVars[name];
+			
+		return undefined;
+	}
+	
+	private function setVar(name:String, value:String):Void
+	{
+	    flashVars[name] = value;
+	    trace("SETTING: " + name + " " + value)
+	}
+
+	public static function set(name:String, value)
+	{
+        getInstance().setVar(name, value);
+	}
+	
+	public static function get(name:String)
+	{
+	    //if (!getInstance().getVar(name))
+	    //    getInstance().log("!ERROR! Flashvar " + name + " not found!");
+
+	    return getInstance().getVar(name);
+	}
+	
+	public static function exists(name:String)
+	{
+	    return get(name) != undefined;
+	}
+	
+	public static function getInstance():FlashvarManager
+	{
+		if (!_instance) 
+			_instance = new FlashvarManager();
+			
+		return _instance;
+	}	
 }
\ No newline at end of file

Modified: z3c.reference/trunk/src/z3c/reference/browser/resources/imagetool.swf
===================================================================
(Binary files differ)



More information about the Checkins mailing list