<!--
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
-->
<!DOCTYPE html>
<html>
<head>
<title>Sample: PubSub</title>
<!-- default container look and feel -->
<link rel="stylesheet" href="gadgets.css">
<script type="text/javascript" src="/gadgets/js/shindig-container:pubsub.js?c=1&debug=1"></script>
<script type="text/javascript">
var my = {};

my.gadgetSpecUrls = [
  'http://' + window.location.host + '/container/sample-pubsub-publisher.xml',
  'http://' + window.location.host + '/container/sample-pubsub-subscriber.xml',
  'http://' + window.location.host + '/container/sample-pubsub-subscriber.xml'
];

my.LayoutManager = function() {
  shindig.LayoutManager.call(this);
};

my.LayoutManager.inherits(shindig.LayoutManager);

my.LayoutManager.prototype.getGadgetChrome = function(gadget) {
  var chromeId = 'gadget-chrome-' + gadget.id;
  return chromeId ? document.getElementById(chromeId) : null;
};

my.init = function() {
  gadgets.pubsubrouter.init(function(id) {
    var gadgetId = shindig.container.gadgetService.getGadgetIdFromModuleId(id);
    var gadget = shindig.container.getGadget(gadgetId);
    return gadget.specUrl;
  }, {
    onSubscribe: function(sender, channel) {
      log(sender + " subscribes to channel '" + channel + "'");
      // return true to reject the request.
      return false;
    },
    onUnsubscribe: function(sender, channel) {
      log(sender + " unsubscribes from channel '" + channel + "'");
      // return true to reject the request.
      return false;
    },
    onPublish: function(sender, channel, message) {
      log(sender + " publishes '" + message + "' to channel '" + channel + "'");
      // return true to reject the request.
      return false;
    }
  });
  shindig.container.layoutManager = new my.LayoutManager();
};

my.renderGadgets = function() {
  shindig.container.setParentUrl("http://" + window.location.host + "/");
  for (var i = 0; i < my.gadgetSpecUrls.length; ++i) {
    var gadget = shindig.container.createGadget(
        {debug:1,specUrl: my.gadgetSpecUrls[i], title: (i ? "Subscriber" : "Publisher")});
    shindig.container.addGadget(gadget);
    shindig.container.renderGadget(gadget);
   
  }
};

function log(message) {
  document.getElementById("output").innerHTML += gadgets.util.escapeString(message) + "<br/>";
}
</script>
</head>
<body onLoad="my.init();my.renderGadgets();">
  <h2>Sample: PubSub</h2>
  <div id="gadget-chrome-0" class="gadgets-gadget-chrome"></div>
  <div id="gadget-chrome-1" class="gadgets-gadget-chrome"></div>
  <div id="gadget-chrome-2" class="gadgets-gadget-chrome"></div>
  <div id="output" style="clear: left;">
  </div>
</body>
</html>
