public int image_opacity(int frame_id, int tick, int data_index)
        {
            Battle_Frame_Image_Data frame = Frames[frame_id].image_data(data_index);
            int opacity = frame.opacity + (int)layer_offset(Frame_Tween_Types.Opacity, frame_id, tick, data_index);

            return(opacity);
        }
        public int image_index(int frame_id, int tick, int data_index)
        {
            Battle_Frame_Image_Data frame = Frames[frame_id].image_data(data_index);
            int index = frame.frame_id + (int)layer_offset(Frame_Tween_Types.Frame_Index, frame_id, tick, data_index);

            return(index);
        }
        public float image_rotation(int frame_id, int tick, int data_index)
        {
            Battle_Frame_Image_Data frame = Frames[frame_id].image_data(data_index);
            float rotation = frame.rotation + layer_offset(Frame_Tween_Types.Rotation, frame_id, tick, data_index);

            if (modifiers != null)
            {
                foreach (var modifier in modifiers.Where(x => x.layer_id == data_index && x.type == Frame_Tween_Types.Rotation))
                {
                    rotation += modifier.magnitude;
                }
            }

            int j = Frames[frame_id].frame_parent_index(data_index, frame.parent_index);

            while (j != -1)
            {
                Battle_Frame_Image_Data parent_frame = Frames[frame_id].image_data(j);
                rotation += parent_frame.rotation + layer_offset(Frame_Tween_Types.Rotation, frame_id, tick, j);
                if (modifiers != null)
                {
                    foreach (var modifier in modifiers.Where(x => x.layer_id == j && x.type == Frame_Tween_Types.Rotation))
                    {
                        rotation += modifier.magnitude;
                    }
                }
                j = Frames[frame_id].frame_parent_index(j, parent_frame.parent_index);
            }
            return(rotation);
        }
        public Vector2 image_location(int frame_id, int tick, int data_index)
        {
            Battle_Frame_Image_Data frame = Frames[frame_id].image_data(data_index);
            Vector2 loc      = Vector2.Zero;
            Vector2 temp_loc = frame.loc + new Vector2(layer_offset(Frame_Tween_Types.X_Pos, frame_id, tick, data_index),
                                                       layer_offset(Frame_Tween_Types.Y_Pos, frame_id, tick, data_index));

            int j = Frames[frame_id].frame_parent_index(data_index, frame.parent_index);

            while (j != -1)
            {
                Battle_Frame_Image_Data parent_frame = Frames[frame_id].image_data(j);
                float rotation = parent_frame.rotation + layer_offset(Frame_Tween_Types.Rotation, frame_id, tick, j);
                if (modifiers != null)
                {
                    foreach (var modifier in modifiers.Where(x => x.layer_id == j && x.type == Frame_Tween_Types.Rotation))
                    {
                        rotation += modifier.magnitude;
                    }
                }

                Matrix m1 = Matrix.Identity * Matrix.CreateScale(parent_frame.scale.X, parent_frame.scale.Y, 1f) *
                            Matrix.CreateRotationZ(rotation / 180 * MathHelper.Pi);
                Matrix m2 = Matrix.Identity * Matrix.CreateRotationZ(rotation / 180 * MathHelper.Pi);

                loc      = Vector2.Transform(loc, m2) + Vector2.Transform(temp_loc, m1);
                temp_loc = parent_frame.loc + new Vector2(layer_offset(Frame_Tween_Types.X_Pos, frame_id, tick, j),
                                                          layer_offset(Frame_Tween_Types.Y_Pos, frame_id, tick, j));
                j = Frames[frame_id].frame_parent_index(j, parent_frame.parent_index);
            }
            loc += temp_loc;
            return(loc);
        }
        /// <summary>
        /// Returns the parent index of a layer.
        /// If the parent chain working up from the layer is cyclical, returns -1 instead.
        /// </summary>
        /// <param name="data_index">Index of layer to test</param>
        /// <param name="parent_index">Theoretical parent index as stored in the layer's data</param>
        public int frame_parent_index(int data_index, int parent_index)
        {
            if (parent_index == -1 || parent_index >= Lower_Frames.Count + Upper_Frames.Count)
            {
                return(-1);
            }

            HashSet <int> tested_data = new HashSet <int>();

            tested_data.Add(data_index);
            data_index = parent_index;
            while (true)
            {
                if (tested_data.Contains(data_index))
                {
                    return(-1);
                }
                tested_data.Add(data_index);
                Battle_Frame_Image_Data image_data = this.image_data(data_index);
                if (image_data.parent_index == -1)
                {
                    return(parent_index);
                }
                data_index = image_data.parent_index;
            }
        }
        public Vector2 image_scale(int frame_id, int tick, int data_index)
        {
            Battle_Frame_Image_Data frame = Frames[frame_id].image_data(data_index);
            Vector2 scale = frame.scale + (new Vector2(layer_offset(Frame_Tween_Types.X_Scale, frame_id, tick, data_index),
                                                       layer_offset(Frame_Tween_Types.Y_Scale, frame_id, tick, data_index)) / 100f);

            return(scale);
        }
 private void fix_switch_to_upper_parent(int data_index, ref Battle_Frame_Image_Data image_data)
 {
     if (image_data.parent_index == data_index)
     {
         image_data.parent_index = Upper_Frames.Count + Lower_Frames.Count - 1;
     }
     else if (image_data.parent_index > data_index)
     {
         image_data.parent_index--;
     }
 }
 private void fix_switch_to_lower_parent(int data_index, ref Battle_Frame_Image_Data image_data)
 {
     if (image_data.parent_index == data_index)
     {
         image_data.parent_index = Lower_Frames.Count;
     }
     else if (image_data.parent_index < data_index && image_data.parent_index >= Lower_Frames.Count)
     {
         image_data.parent_index++;
     }
 }
 private void fix_switch_position_parent(int data_index1, int data_index2, ref Battle_Frame_Image_Data image_data)
 {
     if (image_data.parent_index == data_index1)
     {
         image_data.parent_index = data_index2;
     }
     else if (image_data.parent_index == data_index2)
     {
         image_data.parent_index = data_index1;
     }
 }
 private void fix_delete_parent(int data_index, ref Battle_Frame_Image_Data image_data)
 {
     if (image_data.parent_index == data_index)
     {
         image_data.parent_index = this.image_data(data_index).parent_index; //-1; // Set the parent value to the parent of the removed layer
     }
     if (image_data.parent_index >= data_index)
     {
         image_data.parent_index--;
     }
 }
 /// <summary>
 /// Fixes the parent indices of layers to account for a layer being switched from lower to upper
 /// </summary>
 /// <param name="data_index">Index of the layer being switched to upper</param>
 public void fix_switch_to_upper_parent(int data_index)
 {
     for (int i = 0; i < Lower_Frames.Count; i++)
     {
         Battle_Frame_Image_Data image_data = Lower_Frames[i];
         fix_switch_to_upper_parent(data_index, ref image_data);
         Lower_Frames[i] = image_data;
     }
     for (int i = 0; i < Upper_Frames.Count; i++)
     {
         Battle_Frame_Image_Data image_data = Upper_Frames[i];
         fix_switch_to_upper_parent(data_index, ref image_data);
         Upper_Frames[i] = image_data;
     }
 }
        public static Battle_Frame_Image_Data read(BinaryReader reader)
        {
            Battle_Frame_Image_Data image_data = new Battle_Frame_Image_Data();

            image_data.parent_index = reader.ReadInt32();
            image_data.frame_id     = reader.ReadInt32();
            image_data.loc          = new Vector2().read(reader);
            image_data.scale        = new Vector2().read(reader);
            image_data.rotation     = (float)reader.ReadDouble();
            image_data.flipped      = reader.ReadBoolean();
            image_data.opacity      = reader.ReadInt32();
            image_data.blend_mode   = reader.ReadInt32();

            return(image_data);
        }