public static void ApplyScaleTransformToObject(PointF fixedPoint, float scaleX, float scaleY, LayerInfo layerItem, 
		                                                ContentPackItem.ItemSize itemSize = ContentPackItem.ItemSize.Small)
        {
            foreach (DrawingInfo eachDrawingInfo in layerItem.DrawingItems.Values)
            {

                switch (eachDrawingInfo.DrawingType)
                {

                case DrawingLayerType.Drawing:

                    for (int i = 0; i < eachDrawingInfo.PathPoints.Count; i++)
                    {

                        PointF point = eachDrawingInfo.PathPoints [i];

                        point.X = scaleX * (point.X + (-fixedPoint.X)) + fixedPoint.X;
                        point.Y = scaleY * (point.Y + (-fixedPoint.Y)) + fixedPoint.Y;

                        eachDrawingInfo.PathPoints [i] = point;

                    }//end for

                    break;

                case DrawingLayerType.Image:
                case DrawingLayerType.Comix:
                case DrawingLayerType.Stamp:
                case DrawingLayerType.Callout:

                    RectangleF imgFrame = eachDrawingInfo.ImageFrame;
                    imgFrame.Width *= scaleX;
                    imgFrame.Height *= scaleY;
                    imgFrame.X = scaleX * (imgFrame.X + (-fixedPoint.X)) + fixedPoint.X;
                    imgFrame.Y = scaleY * (imgFrame.Y + (-fixedPoint.Y)) + fixedPoint.Y;

                    eachDrawingInfo.ImageFrame = imgFrame;
                    eachDrawingInfo.RotatedImageBox = eachDrawingInfo.ImageFrame.Rotate(eachDrawingInfo.RotationAngle);

                    if (eachDrawingInfo.DrawingType == DrawingLayerType.Callout)
                    {

                        eachDrawingInfo.CalloutTextRect = GetCalloutTextRect(imgFrame, itemSize);

                    }//end if

                    break;

                }//end switch

            }//end foreach
        }
        public static void ScaleGraphicsObject(PointF touchLocation, 
		                                       PointF prevTouchLocation, 
		                                       LayerInfo layerItem, 
		                                       CanvasControlPoint controlPoint, 
		                                       bool aspectRatioLocked,
		                                       ContentPackItem.ItemSize itemSize = ContentPackItem.ItemSize.Small)
        {
            RectangleF boundingBox = layerItem.GetBoundingBox ();

            bool scaleUpOnly = boundingBox.Width < 10f || boundingBox.Height < 10f;

            float sx = 0;
            float sy = 0;

            PointF fixedPoint = PointF.Empty;

            switch (controlPoint) {

            case CanvasControlPoint.TopLeft:

                // Fixed point is bottom-right
                fixedPoint = new PointF (boundingBox.Right, boundingBox.Bottom);
                sx = boundingBox.Width / (boundingBox.Width + (touchLocation.X - prevTouchLocation.X));
                sy = aspectRatioLocked ?
                    sx :
                        boundingBox.Height / (boundingBox.Height + (touchLocation.Y - prevTouchLocation.Y));

                break;

            case CanvasControlPoint.TopRight:

                // Fixed point is bottom-left
                fixedPoint = new PointF (boundingBox.Left, boundingBox.Bottom);

                sx = boundingBox.Width / (boundingBox.Width - (touchLocation.X - prevTouchLocation.X));
                sy = aspectRatioLocked ?
                    sx :
                        boundingBox.Height / (boundingBox.Height + (touchLocation.Y - prevTouchLocation.Y));

                break;

            case CanvasControlPoint.BottomRight:

                // Fixed point is top-left
                fixedPoint = boundingBox.Location;

                sx = boundingBox.Width / (boundingBox.Width - (touchLocation.X - prevTouchLocation.X));
                sy = aspectRatioLocked ?
                    sx :
                        boundingBox.Height / (boundingBox.Height - (touchLocation.Y - prevTouchLocation.Y));

                break;

            case CanvasControlPoint.BottomLeft:

                // Fixed point is top-right
                fixedPoint = new PointF (boundingBox.Right, boundingBox.Top);

                sx = boundingBox.Width / (boundingBox.Width + (touchLocation.X - prevTouchLocation.X));
                sy = aspectRatioLocked ?
                    sx :
                        boundingBox.Height / (boundingBox.Height - (touchLocation.Y - prevTouchLocation.Y));

                break;

            }//end switch

            if (scaleUpOnly &&
                sx < 1) {
                sx = 1;
            }//end if

            if (scaleUpOnly &&
                sy < 1) {
                sy = 1;
            }//end if

            foreach (DrawingInfo eachDrawingInfo in layerItem.DrawingItems.Values) {

                if (eachDrawingInfo.DrawingType == DrawingLayerType.Drawing) {

                    for (int i = 0; i < eachDrawingInfo.PathPoints.Count; i++) {

                        PointF point = eachDrawingInfo.PathPoints [i];
                        point.X = sx * (point.X + (-fixedPoint.X)) + fixedPoint.X;
                        point.Y = sy * (point.Y + (-fixedPoint.Y)) + fixedPoint.Y;

                        eachDrawingInfo.PathPoints [i] = point;

                    }//end for

                } else if (eachDrawingInfo.DrawingType == DrawingLayerType.Image ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Comix ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Stamp ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Callout) {

                    RectangleF imgFrame = eachDrawingInfo.ImageFrame;
                    imgFrame.Width *= sx;
                    imgFrame.Height *= sy;

                    switch (controlPoint) {

                    case CanvasControlPoint.BottomLeft:

                        imgFrame.X += touchLocation.X - prevTouchLocation.X;

                        break;

                    case CanvasControlPoint.BottomRight:

                        //NOTE: Location is ok, when the only item in the layer is the image.

                        break;

                    case CanvasControlPoint.TopLeft:

                        imgFrame.X += touchLocation.X - prevTouchLocation.X;
                        imgFrame.Y += touchLocation.Y - prevTouchLocation.Y;

                        break;

                    case CanvasControlPoint.TopRight:

                        imgFrame.Y += touchLocation.Y - prevTouchLocation.Y;

                        break;

                    }//end switch

                    eachDrawingInfo.ImageFrame = imgFrame;
                    eachDrawingInfo.RotatedImageBox = eachDrawingInfo.ImageFrame.Rotate (eachDrawingInfo.RotationAngle);

                    if (eachDrawingInfo.DrawingType == DrawingLayerType.Callout)
                    {
                        eachDrawingInfo.CalloutTextRect = GetCalloutTextRect (eachDrawingInfo.ImageFrame, itemSize);
                    }//end if

                }//end if else

            }//end foreach
        }
        public static void RotateGraphicsObjectByAngle(double degAngle, LayerInfo layerItem)
        {
            RectangleF boundingBox = layerItem.GetBoundingBox ();
            //			PointF center = new PointF (boundingBox.GetMidX (), boundingBox.GetMidY ());
            PointF center = boundingBox.GetCenterOfRect();

            double radAngle = degAngle * DegToRad;
            float angleCos = (float)Math.Cos (radAngle);
            float angleSin = (float)Math.Sin (radAngle);

            foreach (DrawingInfo eachDrawingInfo in layerItem.DrawingItems.Values) {

                if (eachDrawingInfo.DrawingType == DrawingLayerType.Drawing) {

                    for (int i = 0; i < eachDrawingInfo.PathPoints.Count; i++) {

                        PointF point = eachDrawingInfo.PathPoints [i];

                        // Translate point
                        float tx = point.X - center.X;
                        float ty = point.Y - center.Y;

                        // Rotate it
                        float rx = (tx * angleCos) - (ty * angleSin);
                        float ry = (ty * angleCos) + (tx * angleSin);

                        // Translate back
                        rx += center.X;
                        ry += center.Y;

                        point.X = rx;
                        point.Y = ry;

                        eachDrawingInfo.PathPoints [i] = point;

                    }//end for

                } else if (eachDrawingInfo.DrawingType == DrawingLayerType.Image ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Comix ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Stamp) {

                    RectangleF imgFrame = eachDrawingInfo.ImageFrame;
                    eachDrawingInfo.RotatedImageBox = imgFrame.Rotate (degAngle);
                    eachDrawingInfo.RotationAngle = degAngle;

                } else if (eachDrawingInfo.DrawingType == DrawingLayerType.Callout) {

                    RectangleF imgFrame = eachDrawingInfo.ImageFrame;
                    eachDrawingInfo.RotatedImageBox = imgFrame.Rotate (degAngle);
                    eachDrawingInfo.RotationAngle = degAngle;

                }//end if else if

            }//end foreach
        }
        public static void RotateGraphicsObject(PointF touchLocation, LayerInfo layerItem, ref double prevRadAngle)
        {
            RectangleF boundingRect = layerItem.GetBoundingBox ();
            //			PointF center = new PointF (boundingRect.GetMidX (), boundingRect.GetMidY ());
            PointF center = boundingRect.GetCenterOfRect();

            double deltaX = touchLocation.X - center.X;
            double deltaY = touchLocation.Y - center.Y;

            double radAngle = Math.Atan2 (deltaY, deltaX);
            double angleDiff = radAngle - prevRadAngle;

            float angleCos = (float)Math.Cos (angleDiff);
            float angleSin = (float)Math.Sin (angleDiff);

            foreach (DrawingInfo eachDrawingInfo in layerItem.DrawingItems.Values) {

                if (eachDrawingInfo.DrawingType == DrawingLayerType.Drawing) {

                    for (int i = 0; i < eachDrawingInfo.PathPoints.Count; i++) {

                        PointF point = eachDrawingInfo.PathPoints [i];

                        // Translate point
                        float tx = point.X - center.X;
                        float ty = point.Y - center.Y;

                        // Rotate it
                        float rx = (tx * angleCos) - (ty * angleSin);
                        float ry = (ty * angleCos) + (tx * angleSin);

                        // Translate back
                        rx += center.X;
                        ry += center.Y;

                        point.X = rx;
                        point.Y = ry;

                        eachDrawingInfo.PathPoints [i] = point;

                    }//end for

                } else if (eachDrawingInfo.DrawingType == DrawingLayerType.Image ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Comix ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Stamp ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Callout) {

                    double degAngle = radAngle * RadToDeg;
                    RectangleF imgFrame = eachDrawingInfo.ImageFrame;
                    eachDrawingInfo.RotatedImageBox = imgFrame.Rotate (degAngle);

                }//end if else if

                eachDrawingInfo.RotationAngle = radAngle * RadToDeg;

            }//end foreach

            prevRadAngle = radAngle;
        }
        public static void MoveGraphicsObject(PointF touchLocation, PointF prevTouchLocation, LayerInfo layerItem)
        {
            foreach (DrawingInfo eachDrawingInfo in layerItem.DrawingItems.Values) {

                if (eachDrawingInfo.DrawingType == DrawingLayerType.Drawing) {

                    for (int i = 0; i < eachDrawingInfo.PathPoints.Count; i++) {

                        PointF point = eachDrawingInfo.PathPoints [i];
                        float xDiff = touchLocation.X - prevTouchLocation.X;
                        float yDiff = touchLocation.Y - prevTouchLocation.Y;

                        point.X += xDiff;
                        point.Y += yDiff;

                        eachDrawingInfo.PathPoints [i] = point;

                    }//end for

                } else if (eachDrawingInfo.DrawingType == DrawingLayerType.Image ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Comix ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Stamp ||
                    eachDrawingInfo.DrawingType == DrawingLayerType.Callout)
                {

                    RectangleF imgFrame = eachDrawingInfo.ImageFrame;

                    float xDiff = touchLocation.X - prevTouchLocation.X;
                    float yDiff = touchLocation.Y - prevTouchLocation.Y;

                    imgFrame.X += xDiff;
                    imgFrame.Y += yDiff;

                    eachDrawingInfo.ImageFrame = imgFrame;
                    eachDrawingInfo.RotatedImageBox = eachDrawingInfo.ImageFrame.Rotate (eachDrawingInfo.RotationAngle);

                    if (eachDrawingInfo.DrawingType == DrawingLayerType.Callout)
                    {

                        RectangleF calloutTextRect = eachDrawingInfo.CalloutTextRect;

                        calloutTextRect.X += xDiff;
                        calloutTextRect.Y += yDiff;

                        eachDrawingInfo.CalloutTextRect = calloutTextRect;

                    }//end if

                }//end if else if

            }//end foreach
        }
        public static AnimationTypesTransitionEffectType CreateTransitionEffect(LayerInfo guideLayer, TransitionInfo transitionItem)
        {
            AnimationTypesTransitionEffectType toReturn = AnimationTypesTransitionEffectType.None;

            RectangleF layerBox = guideLayer.GetBoundingBox ();
            RectangleF trBox = new RectangleF (transitionItem.EndLocation, transitionItem.EndSize);

            // Check for Move transition
            if (layerBox.Location != transitionItem.EndLocation) {
                toReturn = AnimationTypesTransitionEffectType.Move;
            }//end if

            // Check for Rotation transition
            double guideRotationAngle = guideLayer.DrawingItems.Select (s => s.Value.RotationAngle).Max ();
            if (guideRotationAngle != transitionItem.RotationAngle)
            {
                if (toReturn == AnimationTypesTransitionEffectType.None)
                {
                    toReturn = AnimationTypesTransitionEffectType.Rotate;
                } else
                {
                    toReturn |= AnimationTypesTransitionEffectType.Rotate;
                }//end if else

            }//end if

            // Check for Scale transition
            if (layerBox.Size != transitionItem.EndSize)
            {
                if (toReturn == AnimationTypesTransitionEffectType.None)
                {
                    toReturn = AnimationTypesTransitionEffectType.Scale;
                } else
                {
                    toReturn |= AnimationTypesTransitionEffectType.Scale;
                }//end if else

            }//end if

            return toReturn;
        }
 public void AddLayer(LayerInfo layer)
 {
     this.Layers[layer.ID] = layer;
 }
        public static LayerInfo Clone(LayerInfo layerInfo, bool withoutTransitions)
        {
            Dictionary<int, TransitionInfo> transitions = new Dictionary<int, TransitionInfo>();

            if (!withoutTransitions)
            {

                foreach (KeyValuePair<int, TransitionInfo> eachTransition in layerInfo.Transitions)
                {

                    TransitionInfo trObj = new TransitionInfo(eachTransition.Value.ID);
                    trObj.SetEndFadeValue(eachTransition.Value.FadeOpacity);
                    trObj.SetEndLocation(eachTransition.Value.EndLocation);
                    trObj.SetEndScaleValue(eachTransition.Value.EndSize);
                    trObj.SetRotationValue(eachTransition.Value.RotationAngle);
            //					trObj.EffectType = eachTransition.Value.EffectType;
                    foreach (KeyValuePair<AnimationTypesTransitionEffectType, TransitionEffectSettings> eachItem in eachTransition.Value.Settings)
                    {
                        trObj.Settings[eachItem.Key] = eachItem.Value;
                    }//end foreach

                    transitions.Add(trObj.ID, trObj);

                }//end foreach

            }//end if

            LayerInfo toReturn = new LayerInfo(layerInfo.ID, layerInfo.CanvasSize, transitions);

            foreach (KeyValuePair<int, DrawingInfo> eachDrawingItem in layerInfo.DrawingItems)
            {

                DrawingInfo drawingItem = null;
                if (eachDrawingItem.Value.DrawingType == DrawingLayerType.Drawing)
                {

                    drawingItem =
                        new DrawingInfo(eachDrawingItem.Key,
                                        new List<PointF>(eachDrawingItem.Value.PathPoints),
                                        eachDrawingItem.Value.Brush, eachDrawingItem.Value.LineColor);

                } else
                {

                    drawingItem =
                        new DrawingInfo(eachDrawingItem.Key, eachDrawingItem.Value.ImageBuffer, eachDrawingItem.Value.ImageFrame);

                }//end if else

                switch (eachDrawingItem.Value.DrawingType)
                {

                case DrawingLayerType.Drawing:

                    drawingItem =
                        new DrawingInfo(eachDrawingItem.Key,
                                        new List<PointF>(eachDrawingItem.Value.PathPoints),
                                        eachDrawingItem.Value.Brush, eachDrawingItem.Value.LineColor);

                    break;

                case DrawingLayerType.Image:

                    drawingItem =
                        new DrawingInfo(eachDrawingItem.Key, eachDrawingItem.Value.ImageBuffer, eachDrawingItem.Value.ImageFrame);
                    drawingItem.RotationAngle = eachDrawingItem.Value.RotationAngle;
                    drawingItem.RotatedImageBox = eachDrawingItem.Value.RotatedImageBox;

                    break;

                case DrawingLayerType.Callout:
                case DrawingLayerType.Comix:
                case DrawingLayerType.Stamp:

                    drawingItem =
                        new DrawingInfo(eachDrawingItem.Key,
                                        eachDrawingItem.Value.ContentPackItemID,
                                        eachDrawingItem.Value.DrawingType,
                                        eachDrawingItem.Value.ImageBuffer,
                                        eachDrawingItem.Value.ImageFrame,
                                        eachDrawingItem.Value.LineColor);
                    drawingItem.RotationAngle = eachDrawingItem.Value.RotationAngle;
                    drawingItem.RotatedImageBox = eachDrawingItem.Value.RotatedImageBox;
                    drawingItem.CalloutText = eachDrawingItem.Value.CalloutText;
                    drawingItem.CalloutTextRect = eachDrawingItem.Value.CalloutTextRect;

                    break;

                }//end switch

                toReturn.AddOrReplaceDrawingInfo(drawingItem);

            }//end foreach

            return toReturn;
        }