<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="CodeRunner" 
               description="This gadget shows and lets you run sample code that uses the OpenSocial API"
               thumbnail="http://opensocial-resources.googlecode.com/svn/samples/coderunner/trunk/coderunner.jpg">
    <Require feature="opensocial-0.5" />
    <Require feature="dynamic-height" />
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
      <!-- Generic Styles -->
      <style type="text/css">
        p, div, span {
          font: 12px Verdana;
        }
        code, var, .code, #output {
          font: 12px Courier New;
        }
        code {
          color: #090;
        }
        var {
          color: #00d;
        }
        .code {
          background: #fffeee;
          color: #333222;
          padding: 5px;
        }
        p, .code {
          margin: 2px, 0;
        }
        #output {
          background: #333;
          color: #fff;
          padding: 5px;
          margin: 5px 0;
        }
        .status {
          color: #999;
        }
        #link_container {
          background: #e0ecff;
          font: 14px Arial;
          margin: 10px;
          padding: 5px;
        }
        textarea {
          width: 100%;
          height: auto;
        }
        #code_exec {
          height: 400px;
        }
      </style>

      <!-- Javascript utility methods -->
      <script type="text/javascript">
        //Implement console.log for users without firebug
        var console = console || { log : function(data) { } };

        //Alias document.getElementById
        function $(id) { 
          return document.getElementById(id);
        };
        
        //Stores the string values to display in the output field
        var output_buffer = [];
        
        //Surfaces that this application may occupy
        var modes = { profile : 1, canvas : 2 };
        
        //Pages that this application offers (for paging by URL)
        var pages = { editor : "Editor", 
                      people : "People", 
                      data : "Data", 
                      activities : "Activities" };
         /**
         * Returns the supplied arguments object as an array
         * @param {Object} args Function.arguments object
         * @return {Array} An array corresponding to the items in args
         */
        function getArgsAsArray(args) {
          var result = [];
          for (var i=0; i < args.length; i++) {
            result.push(args[i]);
          }
          return result;
        };
        
        /**
         * Method to print data to this application's output container
         * @param args Takes a variable number of arguments.  Each argument
         *   is printed to the output.
         */
        function output() {
          var args = getArgsAsArray(output.arguments);
          var out_element = $("output");
          console.log("output", args);
          output_buffer.push(args.join(" "));
          while (output_buffer.length > 400) {
            output_buffer.shift();
          }
          out_element.innerHTML = output_buffer.join("<br />");
          out_element.scrollTop = out_element.scrollHeight;
          if (out_element.style.display == "none") {
            out_element.style.display = "block";
          }
        };

        /**
         * Clears the output container
         */
        function cls() {
          output_buffer = [];
          var out_element = $("output");
          out_element.innerHTML = "";
          out_element.style.display = "none";
          _IG_AdjustIFrameHeight();
        };

        /**
         * Executes any javascript contained in the element with the
         * supplied target_id
         * @param {String} target_id Id of the page element that contains
         *   the code to execute
         * @param {Element} button Button that was pressed to execute
         *   the code - the output container will be inserted directly
         *   after this element
         */
        function runcode(target_id, button) {
          var element = $(target_id);
          var out_element = $("output");
          button.parentNode.appendChild(out_element);
          if (element.value) {
            eval(element.value);
          } else {
            eval(element.innerHTML);
          }
        };

        /**
         * Returns the current surface that this application occupies.
         * @return {Number} one of the modes.{value} modes.  Defaults
         *   to mode.canvas if this parameter is not parsed correctly.
         */
        function getMode() {
          return modes[_args()["mode"]] || modes.canvas;
        };

       /**
        * Returns the page that was specified to this application.
        * @return {String} the name of the tab corresponding with 
        *   the current page.  Defaults to "People" if no page is
        *   specified via the up_page querystring parameter.
        */
       function getPage() {
          return pages[_args()["up_page"]] || pages.people;
        };

        /**
         * Initializes the application.  Builds the tabs and renders
         * the correct elements based off of the page mode.  If a page
         * was specified in the querystring, this method displays the 
         * corresponding tab
         */
        function init() {
          cls();
          var tabs = new _IG_Tabs(__MODULE_ID__, getPage(), $("tabs"));
          tabs.addTab("People", 
            { contentContainer : _gel("sample_001"),
              callback : cls });
          tabs.addTab("Data",     
            { contentContainer : _gel("sample_002"),
              callback : cls });
          tabs.addTab("Activities", 
            { contentContainer : _gel("sample_004"),
              callback : cls });       
          tabs.addTab("Editor",
            { contentContainer : _gel("sample_exec"),
              callback : cls });
 
          var mode = getMode();
          if (mode == modes.profile) {
            renderProfileMode();
          } else if (mode == modes.canvas) {
            renderCanvasMode();
          }
          _IG_AdjustIFrameHeight();
        };
        
        /**
         * Shows only items needed for profile mode, hides the rest
         */
        function renderProfileMode() {
          $("tabs").style.display = "none";
          $("sample_profile").style.display = "block";
        };

        /**
         * Shows only items needed for canvas mode, hides the rest
         */
        function renderCanvasMode() {
          $("tabs").style.display = "block";
          $("sample_profile").style.display = "none";
        };

        //When the application is loaded, then call the init function
        _IG_RegisterOnloadHandler(init);
      </script>
      
      <div id="tabs"></div> 

      <div id="sample_exec">
        <p><strong>Live OpenSocial editor</strong></p>
        <p>
          You can type in the field below and press the button to execute OpenSocial code.  This is a good place to copy and paste code examples for experimenting with the OpenSocial API.
        </p>
        <p>
          In addition to the standard JavaScript and OpenSocial methods, you may also call the <code>output</code> method to print output text.  <code>output</code> can take a variable number of arguments, so you can print several variables on the same line without needing to construct the string yourself.  If you have firebug installed and enabled, output will also echo output to the firebug console.
        </p>
        <div id="dom_handle">This <code>div</code> has an id of <code>dom_handle</code> that you can use to insert DOM elements into</div>
        <textarea class="code" id="code_exec">
function response(data) {
  //Prints your name
  output(data.get("viewer_profile").getData().getDisplayName());
  //Adjust the height of this application
  _IG_AdjustIFrameHeight();
};

function request() {
  var req = opensocial.newDataRequest();
  // Add request code here
  req.add(req.newFetchPersonRequest("VIEWER"), "viewer_profile");
  req.send(response);
};

request();
        </textarea>
        <p><button onclick="runcode('code_exec', this);">Click here to run</button></p>
      </div> 
        

       <!-- Scrolling output buffer -->
      <div id="output"></div>  
 ]]>
  </Content>
</Module>

