[ease/json: 1/2] JSON parser and generator for loading and saving files.



commit d9955a1c49b4b15fe6e739cb01f4d506fa4b1ce5
Author: Nate Stedman <natesm gmail com>
Date:   Sat May 29 03:54:02 2010 -0400

    JSON parser and generator for loading and saving files.
    
    Seems to work properly - should be tested more before merging to master.

 Examples/Example.ease/Document.json     |  111 ++++
 Examples/Example.ease/Document.xml      |   18 -
 Examples/Transitions.ease/Document.json |  834 +++++++++++++++++++++++++++++++
 Examples/Transitions.ease/Document.xml  |   95 ----
 Makefile.am                             |    4 +-
 configure.ac                            |    4 +-
 src/Document.vala                       |  216 +-------
 src/EditorWindow.vala                   |   21 +-
 src/Element.vala                        |    7 +-
 src/ElementMap.vala                     |   19 +
 src/JSONParser.vala                     |  173 +++++++
 src/Main.vala                           |   51 ++-
 src/Slide.vala                          |   49 ++-
 13 files changed, 1278 insertions(+), 324 deletions(-)
---
diff --git a/Examples/Example.ease/Document.json b/Examples/Example.ease/Document.json
new file mode 100644
index 0000000..52d4135
--- /dev/null
+++ b/Examples/Example.ease/Document.json
@@ -0,0 +1,111 @@
+{
+  "height" : "480",
+  "slides" : [
+    {
+      "background_image" : "Media/Themes/Pink/Background.svg",
+      "variant" : "Left",
+      "transition" : "Spin Contents",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "26",
+          "x" : "41",
+          "element_type" : "text",
+          "font_style" : "Normal",
+          "height" : "188",
+          "text" : "See Ease.
+See Ease Run.",
+          "green" : "255",
+          "align" : "left",
+          "width" : "556",
+          "blue" : "255",
+          "font_weight" : "300",
+          "red" : "255",
+          "ease_name" : "blehhhh",
+          "font_name" : "Myriad Pro",
+          "font_size" : "72"
+        }
+      ]
+    },
+    {
+      "blue" : "0",
+      "green" : "0",
+      "variant" : "Up",
+      "red" : "0",
+      "transition" : "Panel",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "element_type" : "image",
+          "y" : "-1",
+          "x" : "-1",
+          "height" : "482",
+          "scale_y" : "1",
+          "scale_x" : "1",
+          "text" : "",
+          "width" : "641",
+          "filename" : "Media/psyduck.jpg",
+          "ease_name" : "psyduck"
+        }
+      ]
+    },
+    {
+      "background_image" : "Media/Themes/Pink/Background.svg",
+      "variant" : "",
+      "transition" : "Drop",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "element_type" : "image",
+          "y" : "20",
+          "x" : "20",
+          "height" : "240",
+          "scale_y" : "0.25",
+          "scale_x" : "0.25",
+          "text" : "",
+          "width" : "320",
+          "filename" : "Media/psyduck.jpg",
+          "ease_name" : "psyduck"
+        },
+        {
+          "element_type" : "image",
+          "y" : "340",
+          "x" : "20",
+          "height" : "240",
+          "scale_y" : "0.25",
+          "scale_x" : "0.25",
+          "text" : "",
+          "width" : "320",
+          "filename" : "Media/psyduck.jpg",
+          "ease_name" : "psyduck"
+        },
+        {
+          "element_type" : "image",
+          "y" : "20",
+          "x" : "440",
+          "height" : "240",
+          "scale_y" : "0.25",
+          "scale_x" : "0.25",
+          "text" : "",
+          "width" : "320",
+          "filename" : "Media/psyduck.jpg",
+          "ease_name" : "psyduck"
+        },
+        {
+          "element_type" : "image",
+          "y" : "340",
+          "x" : "440",
+          "height" : "240",
+          "scale_y" : "0.25",
+          "scale_x" : "0.25",
+          "text" : "",
+          "width" : "320",
+          "filename" : "Media/psyduck.jpg",
+          "ease_name" : "psyduck"
+        }
+      ]
+    }
+  ],
+  "width" : "640"
+}
diff --git a/Examples/Transitions.ease/Document.json b/Examples/Transitions.ease/Document.json
new file mode 100644
index 0000000..b5f3c20
--- /dev/null
+++ b/Examples/Transitions.ease/Document.json
@@ -0,0 +1,834 @@
+{
+  "height" : "768",
+  "slides" : [
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "",
+      "red" : "34",
+      "transition" : "Slats",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "Up",
+      "red" : "255",
+      "transition" : "Reveal",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "",
+      "red" : "34",
+      "transition" : "Fade",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "",
+      "red" : "255",
+      "transition" : "Open Door",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "Left",
+      "red" : "34",
+      "transition" : "Slide",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "",
+      "red" : "255",
+      "transition" : "Drop",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "Top Right",
+      "red" : "34",
+      "transition" : "Pivot",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "Left to Right",
+      "red" : "255",
+      "transition" : "Flip",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "Left",
+      "red" : "34",
+      "transition" : "Revolving Door",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "",
+      "red" : "255",
+      "transition" : "Fall",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "Center",
+      "red" : "34",
+      "transition" : "Zoom",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "Left",
+      "red" : "255",
+      "transition" : "Panel",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "Left",
+      "red" : "34",
+      "transition" : "Spin Contents",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "",
+      "red" : "255",
+      "transition" : "Swing Contents",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "Left",
+      "red" : "34",
+      "transition" : "Slide Contents",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "Up",
+      "red" : "255",
+      "transition" : "Spring Contents",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "34",
+      "green" : "34",
+      "variant" : "In",
+      "red" : "34",
+      "transition" : "Zoom Contents",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "900",
+          "red" : "255",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "255",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "255",
+          "font_weight" : "500",
+          "red" : "255",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    },
+    {
+      "blue" : "255",
+      "green" : "255",
+      "variant" : "In",
+      "red" : "255",
+      "transition" : "Zoom Contents",
+      "transition_time" : "1",
+      "elements" : [
+        {
+          "font_variant" : "Normal",
+          "y" : "30",
+          "x" : "30",
+          "height" : "200",
+          "font_style" : "Normal",
+          "text" : "Lorem Ipsum Dolor",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "900",
+          "red" : "34",
+          "ease_name" : "header",
+          "font_name" : "Sans",
+          "font_size" : "36"
+        },
+        {
+          "font_variant" : "Normal",
+          "y" : "90",
+          "x" : "30",
+          "height" : "768",
+          "font_style" : "Normal",
+          "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
+          "element_type" : "text",
+          "green" : "34",
+          "align" : "left",
+          "width" : "964",
+          "blue" : "34",
+          "font_weight" : "500",
+          "red" : "34",
+          "ease_name" : "text",
+          "font_name" : "Sans",
+          "font_size" : "16"
+        }
+      ]
+    }
+  ],
+  "width" : "1024"
+}
diff --git a/Makefile.am b/Makefile.am
index 80a596e..eb2b4c4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -26,6 +26,7 @@ ease_SOURCES = \
 	src/Inspector.vala\
 	src/InspectorPane.vala\
 	src/InspectorWindow.vala\
+	src/JSONParser.vala\
 	src/MainToolbar.vala \
 	src/Main.vala \
 	src/OpenDialog.vala \
@@ -57,7 +58,8 @@ VALAFLAGS = --pkg glib-2.0 \
 		--pkg clutter-gtk-0.10 \
 		--pkg cogl-1.0 \
 		--pkg gio-2.0 \
-		--pkg clutter-gst-1.0
+		--pkg clutter-gst-1.0\
+		--pkg json-glib-1.0\
 		$(NULL)
 
 SUBDIRS = po
diff --git a/configure.ac b/configure.ac
index 925b4b3..9f37224 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,9 +27,9 @@ GNOME_COMPILE_WARNINGS([maximum])
 GNOME_MAINTAINER_MODE_DEFINES
 
 dnl FIXME
-pkg_modules="clutter-gtk-0.10 >= 0.10 gee-1.0 >= 0.5.0 libxml-2.0 >= 2.7.6 clutter-gst-1.0 >= 1.0.0"
+pkg_modules="clutter-gtk-0.10 >= 0.10 gee-1.0 >= 0.5.0 libxml-2.0 >= 2.7.6 clutter-gst-1.0 >= 1.0.0 json-glib-1.0 >= 0.7.6"
 
-EASE_PACKAGES="--pkg glib-2.0 --pkg gtk+-2.0 --pkg clutter-1.0 --pkg gdk-2.0 --pkg libxml-2.0 --pkg gee-1.0 --pkg clutter-gtk-0.10 --pkg cogl-1.0 --pkg gio-2.0 --pkg clutter-gst-1.0"
+EASE_PACKAGES="--pkg glib-2.0 --pkg gtk+-2.0 --pkg clutter-1.0 --pkg gdk-2.0 --pkg libxml-2.0 --pkg gee-1.0 --pkg clutter-gtk-0.10 --pkg cogl-1.0 --pkg gio-2.0 --pkg clutter-gst-1.0 --pkg json-glib-1.0"
 
 PKG_CHECK_MODULES(EASE, [$pkg_modules])
 
diff --git a/src/Document.vala b/src/Document.vala
index 83e073d..d4e42d6 100644
--- a/src/Document.vala
+++ b/src/Document.vala
@@ -15,8 +15,6 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-using Xml;
-
 /**
  * The internal representation of Ease documents. Contains { link Slide}s.
  *
@@ -27,9 +25,26 @@ public class Ease.Document : GLib.Object
 {
 	public Gee.ArrayList<Slide> slides { get; set; }
 	public Theme theme { get; set; }
+	
+	/**
+	 * The width of the Document, in pixels.
+	 */
 	public int width { get; set; }
+	
+	/**
+	 * The height of the Document, in pixels.
+	 */
 	public int height { get; set; }
+	
+	/**
+	 * The file path of the Document.
+	 */
 	public string path { get; set; }
+	
+	/**
+	 * The number of { link Slide}s in the Document.
+	 */
+	public int length { get { return slides.size; } }
 
 	/**
 	 * Default constructor, used for new documents.
@@ -41,200 +56,17 @@ public class Ease.Document : GLib.Object
 	{
 		slides = new Gee.ArrayList<Slide>();
 	}
-
-	/**
-	 * Create a document from a file that already exists.
-	 * 
-	 * Used for loading previously saved files. 
-	 *
-	 * @param filename The path to the filename.
-	 */
-	public Document.from_file(string filename)
-	{
-		this();
-		
-		path = filename;
-		
-		var doc = Parser.parse_file(filename + "Document.xml");
-		if (doc == null)
-		{
-			stdout.printf(_("No Document"));
-		}
-		
-		var root = doc->get_root_element();
-		if (root == null)
-		{
-			stdout.printf(_("No root node"));
-		}
-		else
-		{
-			for (Xml.Attr* i = root -> properties; i != null; i = i->next)
-			{
-				switch (i->name)
-				{
-					case "width":
-						width = (i->children->content).to_int();
-						break;
-					case "height":
-						height = (i->children->content).to_int();
-						break;
-				}
-			}
-			parse_xml(root);
-		}
-		
-		delete doc;
-	}
-
-	/**
-	 * Writes the document to a file (currently, a folder).
-	 * 
-	 * to_file() uses the Document's "path" property to determine where the
-	 * file should be written. Currently, if writing fails, a dialog box
-	 * is displayed with the exception.
-	 *
-	 */
-	public void to_file()
-	{
-		string output = "<?xml version=\"1.0\" ?>\n" +
-		                "<document width=\"" + @"$width" + "\" height=\"" + @"$height" + "\">\n" +
-		                "\t<slides>\n";
-		foreach (var s in slides)
-		{
-			output += s.to_xml();
-		}
-		output += "\t</slides>\n</document>\n";
-
-		try
-		{
-			var file = File.new_for_path(path + "Document.xml");
-			var stream = file.replace(null, true, FileCreateFlags.NONE, null);
-			var data_stream = new DataOutputStream(stream);
-			data_stream.put_string(output, null);
-		}
-		catch (GLib.Error e)
-		{
-			var dialog = new Gtk.MessageDialog(null,
-			                                   Gtk.DialogFlags.NO_SEPARATOR,
-			                                   Gtk.MessageType.ERROR,
-			                                   Gtk.ButtonsType.CLOSE,
-			                                   _("Error saving: %s"), e. message);
-			dialog.title = _("Error Saving");
-			dialog.border_width = 5;
-			dialog.run();
-		}
-	}
-
-	/**
-	 * Begins the parsing of an XML document.
-	 * 
-	 * This will be replaced with a JSON file format. 
-	 *
-	 * @param node The initial XML node to begin with.
-	 */
-	private void parse_xml(Xml.Node* node)
-	{
-		for (Xml.Node* iter = node->children; iter != null; iter = iter ->next)
-		{
-			switch (iter->name)
-			{
-				case "slides":
-					parse_slides(iter);
-					break;
-			}
-		}
-	}
-
+	
 	/**
-	 * Parses the slides from an XML document.
-	 * 
-	 * This will be replaced with a JSON file format.
+	 * Inserts a new { link Slide} into the Document
 	 *
-	 * @param node The slides XML node.
+	 * @param s The { link Slide} to insert.
+	 * @param index The position of the new { link Slide} in the Document.
 	 */
-	private void parse_slides(Xml.Node* node)
+	public void add_slide(int index, Slide s)
 	{
-		for (Xml.Node* i = node->children; i != null; i = i->next)
-		{
-			// skip ahead if this isn't a node
-			if (i->type != ElementType.ELEMENT_NODE)
-			{
-				continue;
-			}
-			
-			// create a new slide to be added
-			var slide = new Slide(this);
-			slide.elements = new Gee.ArrayList<Element>();
-			
-			// scan the slide's properties
-			for (Xml.Attr* j = i->properties; j != null; j = j->next)
-			{
-				switch (j->name)
-				{
-					case "transition":
-						slide.transition = j->children->content;
-						break;
-					case "variant":
-						slide.variant = j->children->content;
-						break;
-					case "red":
-						slide.background_color.red = (uchar)(j->children->content.to_int());
-						slide.background_color.alpha = 255;
-						break;
-					case "green":
-						slide.background_color.green = (uchar)(j->children->content.to_int());
-						slide.background_color.alpha = 255;
-						break;
-					case "blue":
-						slide.background_color.blue = (uchar)(j->children->content.to_int());
-						slide.background_color.alpha = 255;
-						break;
-					case "background_image":
-						slide.background_image = j->children->content;
-						break;
-					case "time":
-						slide.transition_time = j->children->content.to_double();
-						break;
-				}
-			}
-					
-			// scan the slide's elements
-			for (Xml.Node* j = i->children; j != null; j = j->next)
-			{					
-				if (j->type != ElementType.ELEMENT_NODE)
-				{
-					continue;
-				}
-
-				// build a list of the element's properties
-				//stdout.printf("\nNew Element:\n");
-				var list = new Gee.ArrayList<string>();
-				for (Xml.Attr* k = j->properties; k != null; k = k->next)
-				{
-					//stdout.printf("\t%s %s\n", k->name, k->children->content);
-					list.add(k->name);
-					list.add(k->children->content);
-				}
-
-				// if the element has text, add that as well
-				if (j->get_content() != null)
-				{
-					list.add("text");
-					list.add(j-> get_content());
-				}
-				
-				// create an appropriate element
-				var element = new Element(slide);
-				for (var index = 0; index < list.size; index += 2)
-				{
-					element.data.set(list[index], list[index + 1]);
-				}
-				
-				slide.elements.add(element);
-			}
-			
-			slides.add(slide);
-		}
+		s.parent = this;
+		slides.insert(index, s);
 	}
 	
 	public void export_to_html(Gtk.Window window)
diff --git a/src/EditorWindow.vala b/src/EditorWindow.vala
index e965213..8d25254 100644
--- a/src/EditorWindow.vala
+++ b/src/EditorWindow.vala
@@ -61,12 +61,12 @@ public class Ease.EditorWindow : Gtk.Window
 	 *
 	 * @param node The initial XML node to begin with.
 	 */
-	public EditorWindow(string filename)
+	public EditorWindow(Document doc)
 	{
-		title = "Ease - " + filename;
+		title = "Ease";
 		set_default_size(1024, 768);
 		
-		document = new Document.from_file(filename);
+		document = doc;
 		
 		// slide display
 		var slides_win = new SlideButtonPanel(document, this);
@@ -143,7 +143,20 @@ public class Ease.EditorWindow : Gtk.Window
 		
 		// save file
 		main_toolbar.save.clicked.connect(() => {
-			document.to_file();
+			try { JSONParser.document_write(document); }
+			catch (GLib.Error e)
+			{
+				var dialog = new Gtk.MessageDialog(null,
+					                               Gtk.DialogFlags.NO_SEPARATOR,
+					                               Gtk.MessageType.ERROR,
+					                               Gtk.ButtonsType.CLOSE,
+					                               _("Error saving: %s"),
+					                               e. message);
+			
+				dialog.title = _("Error Saving");
+				dialog.border_width = 5;
+				dialog.run();
+			}
 		});
 		
 		// play presentation
diff --git a/src/Element.vala b/src/Element.vala
index 4a10771..3f95673 100644
--- a/src/Element.vala
+++ b/src/Element.vala
@@ -37,10 +37,15 @@ public class Ease.Element : GLib.Object
 	
 	/**
 	 * Create a new element.
+	 */
+	public Element() {}
+	
+	/**
+	 * Create a new element.
 	 *
 	 * @param owner The slide that this Element belongs to.
 	 */
-	public Element(Slide owner)
+	public Element.with_owner(Slide owner)
 	{
 		parent = owner;
 	}
diff --git a/src/ElementMap.vala b/src/ElementMap.vala
index de1d2f9..22ba1a9 100644
--- a/src/ElementMap.vala
+++ b/src/ElementMap.vala
@@ -69,6 +69,25 @@ public class Ease.ElementMap
 		     ? "\t\t\t<element " + xml + "/>\n"
 		     : "\t\t\t<element " + xml + ">" + text + "</element>\n";
 	}
+	
+	/**
+	 * Output this ElementData as JSON.
+	 * 
+	 * Returns a JSON object with the element's data.
+	 */
+	public Json.Node to_json()
+	{
+		var node = new Json.Node(Json.NodeType.OBJECT);
+		var obj = new Json.Object();
+		
+		foreach (var key in map.keys)
+		{
+			obj.set_string_member(key, get(key));
+		}
+		
+		node.set_object(obj);
+		return node;
+	}
 
 	/**
 	 * Set a value.
diff --git a/src/JSONParser.vala b/src/JSONParser.vala
new file mode 100644
index 0000000..be4ef51
--- /dev/null
+++ b/src/JSONParser.vala
@@ -0,0 +1,173 @@
+/*  Ease, a GTK presentation application
+    Copyright (C) 2010 Nate Stedman
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * Parses JSON files to load Ease { link Document}s
+ */
+public static class Ease.JSONParser
+{
+	/**
+	 * Parses a JSON file, creating a { link Document}.
+	 *
+	 * @param filename The filename of the { link Document}
+	 */
+	public static Document document(string filename) throws GLib.Error
+	{
+		var document = new Document();
+		document.path = filename;
+	
+		var parser = new Json.Parser();
+		
+		// attempt to load the file
+		parser.load_from_file(filename + "/Document.json");
+		
+		// grab the root object
+		var root = parser.get_root().get_object();
+		
+		// set document properties
+		document.width = (int)root.get_string_member("width").to_int();
+		document.height = (int)root.get_string_member("height").to_int();
+		
+		// add all slides
+		var slides = root.get_array_member("slides");
+		
+		for (var i = 0; i < slides.get_length(); i++)
+		{
+			var node = slides.get_object_element(i);
+			document.add_slide(document.length, document_parse_slide(node));
+		}
+		
+		return document;
+	}
+	
+	private static Slide document_parse_slide(Json.Object obj)
+	{
+		var slide = new Slide();
+		
+		slide.transition = obj.get_string_member("transition");
+		slide.variant = obj.get_string_member("variant");
+		slide.transition_time =
+			obj.get_string_member("transition_time").to_double();
+		
+		if (obj.has_member("background_image"))
+		{
+			slide.background_image = obj.get_string_member("background_image");
+		}
+		else
+		{
+			slide.background_color.red =
+				(uchar)(obj.get_string_member("red").to_int());
+			
+			slide.background_color.green =
+				(uchar)(obj.get_string_member("green").to_int());
+			
+			slide.background_color.blue =
+				(uchar)(obj.get_string_member("blue").to_int());
+			
+			slide.background_color.alpha = 255;
+		}
+		
+		// parse the elements
+		var elements = obj.get_array_member("elements");
+		
+		for (var i = 0; i < elements.get_length(); i++)
+		{
+			var node = elements.get_object_element(i);
+			slide.add_element(slide.count, document_parse_element(node));
+		}
+		
+		return slide;
+	}
+	
+	private static Element document_parse_element(Json.Object obj)
+	{
+		var element = new Element();
+		
+		// set the Element's properties
+		for (unowned List<string>* itr = obj.get_members();
+		     itr != null; itr = itr->next)
+		{
+			string name = itr->data;
+			element.data.set(name, obj.get_member(name).get_string());
+		}
+		
+		return element;
+	}
+	
+	public static void document_write(Document document) throws GLib.Error
+	{
+		var root = new Json.Node(Json.NodeType.OBJECT);
+		var obj = new Json.Object();
+		
+		// set basic document properties
+		obj.set_string_member("width", document.width.to_string());
+		obj.set_string_member("height", document.height.to_string());
+		
+		var slides = new Json.Array();
+		foreach (var s in document.slides)
+		{
+			slides.add_element(document_write_slide(s));
+		}
+		
+		obj.set_array_member("slides", slides);
+		
+		root.set_object(obj);
+	
+		var generator = new Json.Generator();
+		generator.set_root(root);
+		generator.pretty = true;
+		
+		generator.to_file(document.path + "/Document.json");
+	}
+	
+	private static Json.Node document_write_slide(Slide slide)
+	{
+		var node = new Json.Node(Json.NodeType.OBJECT);
+		var obj = new Json.Object();
+		
+		obj.set_string_member("transition", slide.transition);
+		obj.set_string_member("variant", slide.variant);
+		obj.set_string_member("transition_time",
+		                      slide.transition_time.to_string());
+		
+		if (slide.background_image != null)
+		{
+			obj.set_string_member("background_image", slide.background_image);
+		}
+		else
+		{
+			obj.set_string_member("red",
+			                      slide.background_color.red.to_string());
+			obj.set_string_member("green",
+			                      slide.background_color.green.to_string());
+			obj.set_string_member("blue",
+			                      slide.background_color.blue.to_string());
+		}
+		
+		var elements = new Json.Array();
+		foreach (var e in slide.elements)
+		{
+			elements.add_element(e.data.to_json());
+		}
+		
+		obj.set_array_member("elements", elements);
+		
+		node.set_object(obj);
+		return node;
+	}
+}
+
diff --git a/src/Main.vala b/src/Main.vala
index 778dfa2..0093c37 100644
--- a/src/Main.vala
+++ b/src/Main.vala
@@ -95,15 +95,31 @@ public static class Ease.Main : GLib.Object
 		// if --play is specified, play the presentation
 		if (play_filename != null)
 		{
-			var doc = new Document.from_file(play_filename);
-			player = new Player(doc);
+			try
+			{
+				var doc = JSONParser.document(play_filename);
+				player = new Player(doc);
 			
-			// if no editor windows are specified, quit when done
-			if (filenames == null)
+				// if no editor windows are specified, quit when done
+				if (filenames == null)
+				{
+					player.stage.hide.connect(() => {
+						Gtk.main_quit();
+					});
+				}
+			}
+			catch (Error e)
 			{
-				player.stage.hide.connect(() => {
-					Gtk.main_quit();
-				});
+				var dialog = new Gtk.MessageDialog(null,
+					                               Gtk.DialogFlags.NO_SEPARATOR,
+					                               Gtk.MessageType.ERROR,
+					                               Gtk.ButtonsType.CLOSE,
+					                               _("Error playing: %s"),
+					                               e.message);
+			
+				dialog.title = _("Error Playing");
+				dialog.border_width = 5;
+				dialog.run();
 			}
 		}
 		
@@ -139,7 +155,26 @@ public static class Ease.Main : GLib.Object
 			}
 		}
 		
-		add_window(new EditorWindow(path));
+		try
+		{
+			var doc = JSONParser.document(path);
+			add_window(new EditorWindow(doc));
+		}
+		catch (Error e)
+		{
+			var dialog = new Gtk.MessageDialog(null,
+			                                   Gtk.DialogFlags.NO_SEPARATOR,
+			                                   Gtk.MessageType.ERROR,
+			                                   Gtk.ButtonsType.CLOSE,
+			                                   _("Error loading: %s"),
+			                                   e.message);
+			
+			dialog.title = _("Error Loading");
+			dialog.border_width = 5;
+			dialog.run();
+			
+			return;
+		}
 	}
 
 	/**
diff --git a/src/Slide.vala b/src/Slide.vala
index db62544..a53dc29 100644
--- a/src/Slide.vala
+++ b/src/Slide.vala
@@ -24,26 +24,69 @@
  */
 public class Ease.Slide
 {
-	public Gee.ArrayList<Element> elements { get; set; }
+	/**
+	 * The { link Element}s contained by this Slide
+	 */
+	public Gee.ArrayList<Element> elements = new Gee.ArrayList<Element>();
+	
+	/**
+	 * The Slide's transition
+	 */
 	public string transition { get; set; }
+	
+	/**
+	 * The variant (if any) of the Slide's transition
+	 */
 	public string variant { get; set; }
+	
+	/**
+	 * The duration of this Slide's transition
+	 */
+	public double transition_time { get; set; }
+	
+	/**
+	 * The background color, if there is no background image
+	 */
 	public Clutter.Color background_color;
+	
+	/**
+	 * The background image, if one is set
+	 */
 	public string background_image { get; set; }
+	
+	/**
+	 * The { link Document} that this Slide is part of
+	 */
 	public Document parent { get; set; }
-	public double transition_time { get; set; }
+	
+	/**
+	 * The number of { link Element}s on this Slide
+	 */
+	public int count { get { return elements.size; } }
 	
 	/**
 	 * Create a new Slide.
+	 */
+	public Slide() {}
+	
+	/**
+	 * Create a new Slide assigned to a { link Document}.
 	 * 
 	 * Used for loading previously saved files. 
 	 *
 	 * @param owner The { link Document} this slide is a part of.
 	 */
-	public Slide(Document owner)
+	public Slide.with_owner(Document owner)
 	{
 		parent = owner;
 	}
 	
+	public void add_element(int index, Element e)
+	{
+		e.parent = this;
+		elements.insert(index, e);
+	}
+	
 	/**
 	 * Outputs this Slide to XML.
 	 * 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]