public CRectangleF OffsetClip(CRectangleF inRect, CRectangleF outRect)
        {
            CRectangleF intersection = new CRectangleF(inRect);
            intersection.Position -= outRect.Position;

            return outRect.Intersect(intersection);
        }
        public void UpdateOffset(CRectangleF offset, CRectangleF content)
        {
            if (this.velocity != 0)
            {
                offset.Position.X += this.velocity;
                if (this.deccelerator != 0)
                {
                    this.UpdateVelocity(this.velocity - deccelerator);
                    this.deccelerator *= (1 - baseDecelerator);
                    if (this.velocity * this.lastVel <= 0)
                    {
                        this.UpdateVelocity(0f);
                        this.deccelerator = 0;
                        this.deDecel = 0;
                    }
                }
                else
                {
                    this.UpdateVelocity(0f);
                }
            }

            if (offset.Position.X > 0)
            {
                if (offset.Position.X > maxBounces)
                {
                    offset.Position.X = maxBounces;
                    this.UpdateVelocity(0f);
                    this.deccelerator = 0;
                }
                else
                {
                    offset.Position.X -= baseReconstructDecel * offset.Position.X;
                }

                if (offset.Position.X <= capVel)
                {
                    offset.Position.X = 0;
                }
            }

            if (offset.Right < content.Width)
            {
                if (offset.Right < content.Width - maxBounces)
                {
                    offset.Position.X = content.Width - maxBounces - offset.Size.X;
                    this.UpdateVelocity(0f);
                    this.deccelerator = 0;
                }
                else
                {
                    offset.Position.X -= baseReconstructDecel * (offset.Right - content.Width);
                }

                if (offset.Position.X >= content.Width - capVel)
                {
                    offset.Position.X = content.Width;
                }
            }
        }
        public bool Clip(ICanvas canvas, CRectangleF clipRect)
        {
            if (canvas.Bound.Left < clipRect.Left)
            {
                canvas.Bound.Left = clipRect.Left;
                canvas.Content.Left = clipRect.Left - canvas.Bound.Left;
            }

            if (canvas.Bound.Top < clipRect.Top)
            {
                canvas.Bound.Top = clipRect.Top;
                canvas.Content.Top = clipRect.Top - canvas.Bound.Top;
            }

            if (canvas.Bound.Right < clipRect.Right)
            {
                canvas.Bound.Right = clipRect.Right;
                canvas.Content.Right = clipRect.Right - canvas.Bound.Right;
            }

            if (canvas.Bound.Bottom < clipRect.Bottom)
            {
                canvas.Bound.Bottom = clipRect.Bottom;
                canvas.Content.Bottom = clipRect.Bottom - canvas.Bound.Bottom;
            }

            return !canvas.Bound.IsEmpty;
        }
        public bool GrowPlant(string plantName, CRectangleF growRect)
        {
            // call on release touch
            if (!_gameBoard.Bound.Contains(new Point((int)growRect.Center.X, (int)growRect.Center.Y)))
            {
                return false;
            }

            if (getPlantAt(growRect) != null)
                return false;

            CRectangleF rect = _gameBoard.GetRectAtPoint(growRect.Center);

            ////Debug.WriteLine("GrowPlant at " + rect.X + " " + rect.Y);

            var plant = PZObjectFactory.Instance.createPlant(plantName, new Vector2(rect.Left, rect.Bottom));
            if (plant != null)
            {
                PZObjectManager.Instance.AddObject(plant);

                return true;
            }

            return false;
        }
        public CRectangleF CellContains(CRectangleF growRect)
        {
            if (!_gameBoard.Bound.Contains(new Point((int)growRect.Center.X, (int)growRect.Center.Y)))
            {
                return null;
            }

            if (getPlantAt(growRect) != null)
                return null;

            CRectangleF rect = _gameBoard.GetRectAtPoint(growRect.Center);
            ////Debug.WriteLine("CellContains at " + rect.X + " " + rect.Y);
            //rect.Center.Y += rect.Size.Y;
            return rect;
        }
        public CRectangleF CellContains(CRectangleF growRect)
        {
            if (!_gameBoard.Bound.Contains(new Point((int)growRect.Position.X, (int)growRect.Position.Y)))
            {
                return null;
            }

            if (isExistPlant(growRect))
                return null;

            CRectangleF rect = _gameBoard.GetRectAtPoint(growRect.Position);
            ////Debug.WriteLine("CellContains at " + rect.X + " " + rect.Y);
            //rect.Position.Y += rect.Size.Y;
            return rect;
        }
 public void UpdateOffset(CRectangleF offset)
 {
     if (this.velocity != 0)
     {
         Debug.WriteLine("Offset:{0} - Velocity:{1} - Decel:{2}", offset.Position, velocity, deccelerator);
         offset.Position.X += this.velocity;
         this.lastVel = this.velocity;
         if (this.deccelerator != 0)
         {
             this.velocity /= this.deccelerator;
             if (Math.Abs(this.velocity) <= minVel)
             {
                 this.velocity = 0;
                 this.deccelerator = 0;
             }
         }
         else
         {
             this.velocity = 0;
         }
     }
 }
        public void UpdateOffset(CRectangleF offset)
        {
            if (this.velocity != 0)
            {
                offset.Position.Y += this.velocity;
                float oldVel = this.velocity;
                this.velocity -= this.deccelerator;

                if (oldVel * this.velocity <= 0)
                {
                    this.velocity = 0;
                    this.deccelerator = 0;
                }
            }
        }
        public void UpdateOffset(CRectangleF offset, CRectangleF content)
        {
            if (this.velocity != 0)
            {
                //Debug.WriteLine("Offset:{0} - Velocity:{1} - Decel:{2}", offset.Position, velocity, deccelerator);
                offset.Position.Y += this.velocity;
                this.lastVel = this.velocity;
                if (this.deccelerator != 0)
                {
                    this.velocity *= (1f - baseDecelerator);
                    if (Math.Abs(this.velocity) <= capVel)
                    {
                        this.velocity = 0;
                        this.deccelerator = 0;
                    }
                }
                else
                {
                    this.velocity = 0;
                }
            }

            if (offset.Position.Y > 0)
            {
                offset.Position.Y -= baseReconstructDecel * offset.Position.X;
            }

            if (offset.Right < content.Width)
            {
                offset.Position.Y -= baseReconstructDecel * (offset.Right - content.Width);
            }
        }
        private ObjectEntity getPlantAt(CRectangleF rect)
        {
            IDictionary<ulong, ObjectEntity> fullList = PZObjectManager.Instance.GetObjects();
            IDictionary<ulong, ObjectEntity> listPlant = new Dictionary<ulong, ObjectEntity>();

            foreach (var item in fullList)
            {
                if (item.Value.ObjectType != eObjectType.PLANT)
                    continue;
                PhysicComponent phyCom = item.Value.GetComponent(typeof(PhysicComponent)) as PhysicComponent;
                Rectangle frame = phyCom.Frame;

                if (frame.Contains((int)rect.Center.X, (int)rect.Center.Y))
                    return item.Value;
            }
            return null;
        }
        private bool isExistPlant(CRectangleF rect)
        {
            IDictionary<ulong, ObjectEntity> fullList = PZObjectManager.Instance.GetObjects();
            IDictionary<ulong, ObjectEntity> listPlant = new Dictionary<ulong, ObjectEntity>();

            foreach (var item in fullList)
            {
                if (item.Value.ObjectType != eObjectType.PLANT)
                    continue;
                PhysicComponent phyCom = item.Value.GetComponent(typeof(PhysicComponent)) as PhysicComponent;
                Rectangle frame = phyCom.Frame;
                ////Debug.WriteLine(rect.Position.X + " - " + rect.Position.Y + " || " + frame.X + " - " + frame.Y);
                if (frame.Contains((int)rect.Position.X, (int)rect.Position.Y))
                    return true;
            }
            return false;
        }
        private void OnGrowButtonTouchLeaved(PvZGrowButton button, SCSEngine.GestureHandling.Implements.Events.FreeTap leaveGesture)
        {
            CRectangleF contentInBound = new CRectangleF(this.Canvas.Content);
            contentInBound.Position += this.Canvas.Bound.Position;
            if (!contentInBound.Contains(leaveGesture.Current))
            {
                //create plant-shadow
                var shadow = button.ShadowFactory.CreatePlantShadow();
                shadow.CreatorButton = button;
                shadow.Canvas.Bound.Position = leaveGesture.Current;
                shadow.Canvas.Bound.Size = new Vector2(shadow.PlanShadowImage.CurrentFrame.Width,
                    shadow.PlanShadowImage.CurrentFrame.Height);
                shadow.OnGrowNewPlant += this.OnGrowPlant;

                // add p-s to ui manager (g-dispatcher)
                this.uiManager.Add(shadow);
                this.uiManager.SetHandleTarget<FreeTap>(leaveGesture, shadow);
            }
        }