context: // Copyright (c) 2013 Russell Savage - Dented Pixel
  // 
  // LeanTween version 2.14 - http://dentedpixel.com/developer-diary/
  //
  // Permission is hereby granted, free of charge, to any person obtaining a copy
  // of this software and associated documentation files (the "Software"), to deal
  // in the Software without restriction, including without limitation the rights
  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  // copies of the Software, and to permit persons to whom the Software is
  // furnished to do so, subject to the following conditions:
  //
  // The above copyright notice and this permission notice shall be included in
  // all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  // THE SOFTWARE.
  
  /*
  TERMS OF USE - EASING EQUATIONS#
  Open source under the BSD License.
  Copyright (c)2001 Robert Penner
  All rights reserved.
  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
  
  /**
  * Pass this to the "ease" parameter in the optional hashtable, to get a different easing behavior<br><br>
  * <strong>Example: </strong><br>LeanTween.rotateX(gameObject, 270.0f, 1.5f).setEase(LeanTweenType.easeInBack);
  *
  * @class LeanTweenType
  */
  
  /**
  * @property {integer} linear
  */
  /**
  * @property {integer} easeOutQuad
  */
  /**
  * @property {integer} easeInQuad
  */
  /**
  * @property {integer} easeInOutQuad
  */
  /**
  * @property {integer} easeInCubic
  */
  /**
  * @property {integer} easeOutCubic
  */
  /**
  * @property {integer} easeInOutCubic
  */
  /**
  * @property {integer} easeInQuart
  */
  /**
  * @property {integer} easeOutQuart
  */
  /**
  * @property {integer} easeInOutQuart
  */
  /**
  * @property {integer} easeInQuint
  */
  /**
  * @property {integer} easeOutQuint
  */
  /**
  * @property {integer} easeInOutQuint
  */
  /**
  * @property {integer} easeInSine
  */
  /**
  * @property {integer} easeOutSine
  */
  /**
  * @property {integer} easeInOutSine
  */
  /**
  * @property {integer} easeInExpo
  */
  /**
  * @property {integer} easeOutExpo
  */
  /**
  * @property {integer} easeInOutExpo
  */
  /**
  * @property {integer} easeInCirc
  */
  /**
  * @property {integer} easeOutCirc
  */
  /**
  * @property {integer} easeInOutCirc
  */
  /**
  * @property {integer} easeInBounce
  */
  /**
  * @property {integer} easeOutBounce
  */
  /**
  * @property {integer} easeInOutBounce
  */
  /**
  * @property {integer} easeInBack
  */
  /**
  * @property {integer} easeOutBack
  */
  /**
  * @property {integer} easeInOutBack
  */
  /**
  * @property {integer} easeInElastic
  */
  /**
  * @property {integer} easeOutElastic
  */
  /**
  * @property {integer} easeInOutElastic
  */
  /**
  * @property {integer} punch
  */
  using UnityEngine;
  using System.Collections;
  using System;
  public enum LeanTweenType{
  	notUsed, linear, easeOutQuad, easeInQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, 
  	easeInQuint, easeOutQuint, easeInOutQuint, easeInSine, easeOutSine, easeInOutSine, easeInExpo, easeOutExpo, easeInOutExpo, easeInCirc, easeOutCirc, easeInOutCirc, 
  	easeInBounce, easeOutBounce, easeInOutBounce, easeInBack, easeOutBack, easeInOutBack, easeInElastic, easeOutElastic, easeInOutElastic, easeSpring, easeShake, punch, once, clamp, pingPong, animationCurve
  }
  
  /**
  * Internal Representation of a Tween<br>
  * <br>
  * This class represents all of the optional parameters you can pass to a method (it also represents the internal representation of the tween).<br><br>
  * <strong id='optional'>Optional Parameters</strong> are passed at the end of every method:<br> 
  * <br>
  * &nbsp;&nbsp;<i>Example:</i><br>
  * &nbsp;&nbsp;LeanTween.moveX( gameObject, 1f, 1f).setEase( <a href="LeanTweenType.html">LeanTweenType</a>.easeInQuad ).setDelay(1f);<br>
  * <br>
  * You can pass the optional parameters in any order, and chain on as many as you wish.<br>
  * You can also <strong>pass parameters at a later time</strong> by saving a reference to what is returned.<br>
  * <br>
  * &nbsp;&nbsp;<i>Example:</i><br>
  * &nbsp;&nbsp;<a href="LTDescr.html">LTDescr</a> d = LeanTween.moveX(gameObject, 1f, 1f);<br>
  * &nbsp;&nbsp;&nbsp; ...later set some parameters<br>
  * &nbsp;&nbsp;d.setOnComplete( onCompleteFunc ).setEase( <a href="LeanTweenType.html">LeanTweenType</a>.easeInOutBack );<br>
  * <br>
  * Retrieve a <strong>unique id</strong> for the tween by using the "id" property. You can pass this to LeanTween.pause, LeanTween.resume, LeanTween.cancel methods<br>
  * <br>
  * &nbsp;&nbsp;<i>Example:</i><br>
  * &nbsp;&nbsp;int id = LeanTween.moveX(gameObject, 1f, 3f).id;<br>
  * &nbsp;&nbsp;LeanTween.pause( id );<br>
  * @class LTDescr
  * @constructor
  */
  public class LTDescr{
  	public bool toggle;
  	public bool useEstimatedTime;
  	public bool useFrames;
  	public bool hasInitiliazed;
  	public bool hasPhysics;
  	public float passed;
  	public float delay;
  	public float time;
  	public float lastVal;
  	private uint _id;
  	public int loopCount;
  	public uint counter;
  	public float direction;
  	public bool destroyOnComplete;
  	public Transform trans;
  	public LTRect ltRect;
  	public Vector3 from;
  	public Vector3 to;
  	public Vector3 diff;
  	public Vector3 point;
  	public Vector3 axis;
  	public Vector3 origRotation;
  	public LTBezierPath path;
  	public LTSpline spline;
  	public TweenAction type;
  	public LeanTweenType tweenType;
  	public AnimationCurve animationCurve;
  	public LeanTweenType loopType;
  	public Action<float> onUpdateFloat;
  	public Action<float,object> onUpdateFloatObject;
  	public Action<Vector3> onUpdateVector3;
  	public Action<Vector3,object> onUpdateVector3Object;
  	public Action onComplete;
  	public Action<object> onCompleteObject;
  	public object onCompleteParam;
  	public object onUpdateParam;
  	#if !UNITY_METRO
  	public Hashtable optional;
  	#endif
  
  	private static uint global_counter = 0;
  
      public override string ToString(){
  		return (trans!=null ? "gameObject:"+trans.gameObject : "gameObject:null")+" toggle:"+toggle+" passed:"+passed+" time:"+time+" delay:"+delay+" from:"+from+" to:"+to+" type:"+type+" useEstimatedTime:"+useEstimatedTime+" id:"+id+" hasInitiliazed:"+hasInitiliazed;
  	}
  
  	public LTDescr(){
  
  	}
  
  	/**
  	* Cancel a tween
  	* 
  	* @method cancel
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	*/
  	public LTDescr cancel(){
  		LeanTween.removeTween((int)this._id);
  		return this;
  	}
  
  	public int uniqueId{
  		get{ 
  			uint toId = _id | counter << 16;
  
  			/*uint backId = toId & 0xFFFF;
  			uint backCounter = toId >> 16;
  			if(_id!=backId || backCounter!=counter){
  				Debug.LogError("BAD CONVERSION toId:"+_id);
  			}*/
  
  			return (int)toId;
  		}
  	}
  
  	public int id{
  		get{ 
  			return uniqueId;
  		}
  	}
  
  	public void reset(){
  		this.toggle = true;
  		#if !UNITY_METRO
  		this.optional = null;
  		#endif
  		this.destroyOnComplete = false;
  		this.passed = this.delay = 0.0f;
  		this.useEstimatedTime = this.useFrames = this.hasInitiliazed = false;
  		this.animationCurve = null;
  		this.tweenType = LeanTweenType.linear;
  		this.loopType = LeanTweenType.once;
  		this.loopCount = 0;
  		this.direction = this.lastVal = 1.0f;
  		this.onUpdateFloat = null;
  		this.onUpdateVector3 = null;
  		this.onUpdateFloatObject = null;
  		this.onUpdateVector3Object = null;
  		this.onComplete = null;
  		this.onCompleteObject = null;
  		this.onCompleteParam = null;
  		this.point = Vector3.zero;
  		global_counter++;
  	}
  
  	/**
  	* Pause a tween
  	* 
  	* @method pause
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	*/
  	public LTDescr pause(){
  		if(this.direction != 0.0f){ // check if tween is already paused
          	this.lastVal =  this.direction;
              this.direction = 0.0f;
          }
  
          return this;
  	}
  
  	/**
  	* Resume a paused tween
  	* 
  	* @method resume
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	*/
  	public LTDescr resume(){
  		this.direction = this.lastVal;
  		return this;
  	}
  
  	public LTDescr setAxis( Vector3 axis ){
  		this.axis = axis;
  		return this;
  	}
  	
  	/**
  	* Delay the start of a tween
  	* 
  	* @method setDelay
  	* @param {float} float time The time to complete the tween in
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setDelay( 1.5f );
  	*/
  	public LTDescr setDelay( float delay ){
  		if(this.useEstimatedTime){
  			this.delay = delay;
  		}else{
  			this.delay = delay*Time.timeScale;
  		}
  		
  		return this;
  	}
  
  	/**
  	* Set the type of easing used for the tween. <br>
  	* <ul><li><a href="LeanTweenType.html">List of all the ease types</a>.</li>
  	* <li><a href="http://www.robertpenner.com/easing/easing_demo.html">This page helps visualize the different easing equations</a></li>
  	* </ul>
  	* 
  	* @method setEase
  	* @param {LeanTweenType} easeType:LeanTweenType the easing type to use
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setEase( LeanTweenType.easeInBounce );
  	*/
  	public LTDescr setEase( LeanTweenType easeType ){
  		this.tweenType = easeType;
  		return this;
  	}
  
  	/**
  	* Set the type of easing used for the tween with a custom curve. <br>
  	* @method setEase (AnimationCurve)
  	* @param {AnimationCurve} easeDefinition:AnimationCurve an <a href="http://docs.unity3d.com/Documentation/ScriptReference/AnimationCurve.html" target="_blank">AnimationCure</a> that describes the type of easing you want, this is great for when you want a unique type of movement
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setEase( LeanTweenType.easeInBounce );
  	*/
  	public LTDescr setEase( AnimationCurve easeCurve ){
  		this.animationCurve = easeCurve;
  		return this;
  	}
  
  	public LTDescr setTo( Vector3 to ){
  		this.to = to;
  		return this;
  	}
  
  	public LTDescr setFrom( Vector3 from ){
  		this.from = from;
  		this.hasInitiliazed = true; // this is set, so that the "from" value isn't overwritten later on when the tween starts
  		this.diff = this.to - this.from;
  		return this;
  	}
  
  	public LTDescr setId( uint id ){
  		this._id = id;
  		this.counter = global_counter;
  		return this;
  	}
  
  	/**
  	* Set the tween to repeat a number of times.
  	* @method setRepeat
  	* @param {int} repeatNum:int the number of times to repeat the tween. -1 to repeat infinite times
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setRepeat( 10 ).setLoopPingPong();
  	*/
  	public LTDescr setRepeat( int repeat ){
  		this.loopCount = repeat;
  		if((repeat>1 && this.loopType == LeanTweenType.once) || (repeat < 0 && this.loopType == LeanTweenType.once)){
  			this.loopType = LeanTweenType.clamp;
  		}
  		return this;
  	}
  
  	public LTDescr setLoopType( LeanTweenType loopType ){
  		this.loopType = loopType;
  		return this;
  	}
  
  	/**
  	* Use estimated time when tweening an object. Great for pause screens, when you want all other action to be stopped (or slowed down)
  	* @method setUseEstimatedTime
  	* @param {bool} useEstimatedTime:bool whether to use estimated time or not
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setRepeat( 2 ).setUseEstimatedTime( true );
  	*/
  	public LTDescr setUseEstimatedTime( bool useEstimatedTime ){
  		this.useEstimatedTime = useEstimatedTime;
  		return this;
  	}
  
  	/**
  	* Use frames when tweening an object, when you don't want the animation to be time-frame independent...
  	* @method setUseFrames
  	* @param {bool} useFrames:bool whether to use estimated time or not
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setRepeat( 2 ).setUseFrames( true );
  	*/
  	public LTDescr setUseFrames( bool useFrames ){
  		this.useFrames = useFrames;
  		return this;
  	}
  
  	public LTDescr setLoopCount( int loopCount ){
  		this.loopCount = loopCount;
  		return this;
  	}
  
  	/**
  	* No looping involved, just run once (the default)
  	* @method setLoopOnce
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setLoopOnce();
  	*/
  	public LTDescr setLoopOnce(){ this.loopType = LeanTweenType.once; return this; }
  
  	/**
  	* When the animation gets to the end it starts back at where it began
  	* @method setLoopClamp
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setRepeat(2).setLoopClamp();
  	*/
  	public LTDescr setLoopClamp(){ 
  		this.loopType = LeanTweenType.clamp; 
  		if(this.loopCount==0)
  			this.loopCount = -1;
  		return this;
  	}
  
  	/**
  	* When the animation gets to the end it then tweens back to where it started (and on, and on)
  	* @method setLoopPingPong
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setRepeat(2).setLoopPingPong();
  	*/
  	public LTDescr setLoopPingPong(){ 
  		this.loopType = LeanTweenType.pingPong;
  		if(this.loopCount==0)
  			this.loopCount = -1;
  		return this; 
  	}
  
  	/**
  	* Have a method called when the tween finishes
  	* @method setOnComplete
  	* @param {Action} onComplete:Action the method that should be called when the tween is finished ex: tweenFinished(){ }
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setOnComplete( tweenFinished );
  	*/
  	public LTDescr setOnComplete( Action onComplete ){
  		this.onComplete = onComplete;
  		return this;
  	}
  
  	/**
  	* Have a method called when the tween finishes
  	* @method setOnComplete (object)
  	* @param {Action<object>} onComplete:Action<object> the method that should be called when the tween is finished ex: tweenFinished( object myObj ){ }
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setOnComplete( tweenFinished );
  	*/
  	public LTDescr setOnComplete( Action<object> onComplete ){
  		this.onCompleteObject = onComplete;
  		return this;
  	}
  	public LTDescr setOnComplete( Action<object> onComplete, object onCompleteParam ){
  		this.onCompleteObject = onComplete;
  		if(onCompleteParam!=null)
  			this.onCompleteParam = onCompleteParam;
  		return this;
  	}
  
  	/**
  	* Pass an object to along with the onComplete Function
  	* @method setOnCompleteParam
  	* @param {object} onComplete:object an object that 
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setOnComplete( tweenFinished );
  	*/
  	public LTDescr setOnCompleteParam( object onCompleteParam ){
  		this.onCompleteParam = onCompleteParam;
  		return this;
  	}
  
  
  	/**
  	* Have a method called on each frame that the tween is being animated (passes a float value)
  	* @method setOnUpdate
  	* @param {Action<float>} onUpdate:Action<float> a method that will be called on every frame with the float value of the tweened object
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setOnUpdate( tweenMoved );<br>
  	* <br>
  	* void tweenMoved( float val ){ }<br>
  	*/
  	public LTDescr setOnUpdate( Action<float> onUpdate ){
  		this.onUpdateFloat = onUpdate;
  		return this;
  	}
  	
  	public LTDescr setOnUpdateObject( Action<float,object> onUpdate ){
  		this.onUpdateFloatObject = onUpdate;
  		return this;
  	}
  	public LTDescr setOnUpdateVector3( Action<Vector3> onUpdate ){
  		this.onUpdateVector3 = onUpdate;
  		return this;
  	}
  
  	#if !UNITY_FLASH
  	/**
  	* Have a method called on each frame that the tween is being animated (passes a float value and a object)
  	* @method setOnUpdate (object)
  	* @param {Action<float,object>} onUpdate:Action<float,object> a method that will be called on every frame with the float value of the tweened object, and an object of the person's choosing
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setOnUpdate( tweenMoved ).setOnUpdateParam( myObject );<br>
  	* <br>
  	* void tweenMoved( float val, object obj ){ }<br>
  	*/
  	public LTDescr setOnUpdate( Action<float,object> onUpdate, object onUpdateParam = null ){
  		this.onUpdateFloatObject = onUpdate;
  		if(onUpdateParam!=null)
  			this.onUpdateParam = onUpdateParam;
  		return this;
  	}
  
  	public LTDescr setOnUpdate( Action<Vector3,object> onUpdate, object onUpdateParam = null ){
  		this.onUpdateVector3Object = onUpdate;
  		if(onUpdateParam!=null)
  			this.onUpdateParam = onUpdateParam;
  		return this;
  	}
  
  	/**
  	* Have a method called on each frame that the tween is being animated (passes a float value)
  	* @method setOnUpdate (Vector3)
  	* @param {Action<Vector3>} onUpdate:Action<Vector3> a method that will be called on every frame with the float value of the tweened object
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setOnUpdate( tweenMoved );<br>
  	* <br>
  	* void tweenMoved( Vector3 val ){ }<br>
  	*/
  	public LTDescr setOnUpdate( Action<Vector3> onUpdate, object onUpdateParam = null ){
  		this.onUpdateVector3 = onUpdate;
  		if(onUpdateParam!=null)
  			this.onUpdateParam = onUpdateParam;
  		return this;
  	}
  	#endif
  	
  
  	/**
  	* Have an object passed along with the onUpdate method
  	* @method setOnUpdateParam
  	* @param {object} onUpdateParam:object an object that will be passed along with the onUpdate method
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.moveX(gameObject, 5f, 2.0f ).setOnUpdate( tweenMoved ).setOnUpdateParam( myObject );<br>
  	* <br>
  	* void tweenMoved( float val, object obj ){ }<br>
  	*/
  	public LTDescr setOnUpdateParam( object onUpdateParam ){
  		this.onUpdateParam = onUpdateParam;
  		return this;
  	}
  
  	/**
  	* While tweening along a curve, set this property to true, to be perpendicalur to the path it is moving upon
  	* @method setOrientToPath
  	* @param {bool} doesOrient:bool whether the gameobject will orient to the path it is animating along
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.move( ltLogo, path, 1.0f ).setEase(LeanTweenType.easeOutQuad).setOrientToPath(true).setAxis(Vector3.forward);<br>
  	*/
  	public LTDescr setOrientToPath( bool doesOrient ){
  		if(this.type==TweenAction.MOVE_CURVED || this.type==TweenAction.MOVE_CURVED_LOCAL){
  			if(this.path==null)
  				this.path = new LTBezierPath();
  			this.path.orientToPath = doesOrient;
  		}else{
  			this.spline.orientToPath = doesOrient;
  		}
  		return this;
  	}
  
  	public LTDescr setRect( LTRect rect ){
  		this.ltRect = rect;
  		return this;
  	}
  
  	public LTDescr setRect( Rect rect ){
  		this.ltRect = new LTRect(rect);
  		return this;
  	}
  
  	public LTDescr setPath( LTBezierPath path ){
  		this.path = path;
  		return this;
  	}
  
  	/**
  	* Set the point at which the GameObject will be rotated around
  	* @method setPoint
  	* @param {Vector3} point:Vector3 point at which you want the object to rotate around (local space)
  	* @return {LTDescr} LTDescr an object that distinguishes the tween
  	* @example
  	* LeanTween.rotateAround( cube, Vector3.up, 360.0f, 1.0f ) .setPoint( new Vector3(1f,0f,0f) ) .setEase( LeanTweenType.easeInOutBounce );<br>
  	*/
  	public LTDescr setPoint( Vector3 point ){
  		this.point = point;
  		return this;
  	}
  
  	public LTDescr setDestroyOnComplete( bool doesDestroy ){
  		this.destroyOnComplete = doesDestroy;
  		return this;
  	}
  
  	public LTDescr setAudio( object audio ){
  		this.onCompleteParam = audio;
  		return this;
  	}
  	
  }
  
  /**
  * Animate GUI Elements by creating this object and passing the *.rect variable to the GUI method<br><br>
  * <strong>Example Javascript: </strong><br>var bRect:LTRect = new LTRect( 0, 0, 100, 50 );<br>
  * LeanTween.scale( bRect, Vector2(bRect.rect.width, bRect.rect.height) * 1.3, 0.25 );<br>
  * function OnGUI(){<br>
  * &nbsp; if(GUI.Button(bRect.rect, "Scale")){ }<br>
  * }<br>
  * <br>
  * <strong>Example C#: </strong> <br>
  * LTRect bRect = new LTRect( 0f, 0f, 100f, 50f );<br>
  * LeanTween.scale( bRect, new Vector2(150f,75f), 0.25f );<br>
  * void OnGUI(){<br>
  * &nbsp; if(GUI.Button(bRect.rect, "Scale")){ }<br>
  * }<br>
  *
  * @class LTRect
  * @constructor
  * @param {float} x:float X location
  * @param {float} y:float Y location
  * @param {float} width:float Width
  * @param {float} height:float Height
  * @param {float} alpha:float (Optional) initial alpha amount (0-1)
  * @param {float} rotation:float (Optional) initial rotation in degrees (0-360) 
  */
  
  [System.Serializable]
  public class LTRect : System.Object{
  	/**
  	* Pass this value to the GUI Methods
  	* 
  	* @property rect
  	* @type {Rect} rect:Rect Rect object that controls the positioning and size
  	*/
  	public Rect _rect;
  	public float alpha = 1f;
  	public float rotation;
  	public Vector2 pivot;
  	public Vector2 margin;
  	public Rect relativeRect = new Rect(0f,0f,float.PositiveInfinity,float.PositiveInfinity);
  
  	public bool rotateEnabled;
  	[HideInInspector]
  	public bool rotateFinished;
  	public bool alphaEnabled;
  	public string labelStr;
  	public LTGUI.Element_Type type;
  	public GUIStyle style;
  	public bool useColor = false;
  	public Color color = Color.white;
  	public bool fontScaleToFit;
  	public bool useSimpleScale;
  	public bool sizeByHeight;
  
  	public Texture texture;
  
  	private int _id = -1;
  	[HideInInspector]
  	public int counter;
  
  	public static bool colorTouched;
  
  	public LTRect(){
  		reset();
  		this.rotateEnabled = this.alphaEnabled = true;
  		_rect = new Rect(0f,0f,1f,1f);
  	}
  
  	public LTRect(Rect rect){
  		_rect = rect;
  		reset();
  	}
  
  	public LTRect(float x, float y, float width, float height){
  		_rect = new Rect(x,y,width,height);
  		this.alpha = 1.0f;
  		this.rotation = 0.0f;
  		this.rotateEnabled = this.alphaEnabled = false;
  	}
  
  	public LTRect(float x, float y, float width, float height, float alpha){
  		_rect = new Rect(x,y,width,height);
  		this.alpha = alpha;
  		this.rotation = 0.0f;
  		this.rotateEnabled = this.alphaEnabled = false;
  	}
  
  	public LTRect(float x, float y, float width, float height, float alpha, float rotation){
  		_rect = new Rect(x,y,width,height);
  		this.alpha = alpha;
  		this.rotation = rotation;
  		this.rotateEnabled = this.alphaEnabled = false;
  		if(rotation!=0.0f){
  			this.rotateEnabled = true;
  			resetForRotation();
  		}
  	}
  
  	public bool hasInitiliazed{
  		get{ 
  			return _id!=-1;
  		}
  	}
  
  	public int id{
  		get{ 
  			int toId = _id | counter << 16;
  
  			/*uint backId = toId & 0xFFFF;
  			uint backCounter = toId >> 16;
  			if(_id!=backId || backCounter!=counter){
  				Debug.LogError("BAD CONVERSION toId:"+_id);
  			}*/
  
  			return toId;
  		}
  	} 
  
  	public void setId( int id, int counter){
  		this._id = id;
  		this.counter = counter;
  	}
  
  	public void reset(){
  		this.alpha = 1.0f;
  		this.rotation = 0.0f;
  		this.rotateEnabled = this.alphaEnabled = false;
  		this.margin = Vector2.zero;
  		this.sizeByHeight = false;
  		this.useColor = false;
  	}
  
  	public void resetForRotation(){
  		Vector3 scale = new Vector3(GUI.matrix[0,0], GUI.matrix[1,1], GUI.matrix[2,2]);
          if(pivot==Vector2.zero){
              pivot = new Vector2((_rect.x+((_rect.width)*0.5f )) * scale.x + GUI.matrix[0,3], (_rect.y+((_rect.height)*0.5f )) * scale.y + GUI.matrix[1,3]);
          }
  	}
  
  	public float x{
  		get{ return _rect.x; }
  		set{ _rect.x = value; }
  	}
  
  	public float y{
  		get{ return _rect.y; }
  		set{ _rect.y = value; }
  	}
  
  	public float width{
  		get{ return _rect.width; }
  		set{ _rect.width = value; }
  	}
  
  	public float height{
  		get{ return _rect.height; }
  		set{ _rect.height = value; }
  	}
  
  	public Rect rect{
  
  		get{
  			if(colorTouched){
  				colorTouched = false;
  				GUI.color = new Color(GUI.color.r,GUI.color.g,GUI.color.b,1.0f);
  			}
  			if(rotateEnabled){
  				 if(rotateFinished){
                      rotateFinished = false;
                      rotateEnabled = false;
                      //this.rotation = 0.0f;
                      pivot = Vector2.zero;
                  }else{
                      GUIUtility.RotateAroundPivot(rotation, pivot);
                  }
  			}
  			if(alphaEnabled){
  				GUI.color = new Color(GUI.color.r,GUI.color.g,GUI.color.b,alpha);
  				colorTouched = true;
  			}
  			if(fontScaleToFit){
  				if(this.useSimpleScale){
  					style.fontSize = (int)(_rect.height*this.relativeRect.height);
  				}else{
  
gt: 					style.fontSize = (int)_rect.height;