// [...] - boilerplate code to connect to Crossbar.io

function main (session) {
   // subscribe to future vote event
   session.subscribe("http://crossbar.io/crossbar/demo/vote#onvote",
      function(topicUri, event) {
         document.getElementById("votes" + event.subject).value =
            event.votes;
      });

   // get the current vote count
   session.call("http://crossbar.io/crossbar/demo/vote#get").then(
      function(res){
         for(var i = 0; i < res.length; i++) {
            document.getElementById("votes" + res[i].subject).value =
               res[i].votes;
         }
   }, ab.log);

   // wire up vote buttons
   var voteButtons = document.getElementById("voteContainer").
      getElementsByTagName("button");
   for(var i = 0; i < voteButtons.length; i++) {
      voteButtons[i].onclick = function(evt) {
         session.call("http://crossbar.io/crossbar/demo/vote#vote",
               evt.target.id).then(ab.log, ab.log);
      }
   }

   // subscribe to vote reset event
   session.subscribe("http://crossbar.io/crossbar/demo/vote#onreset",
      function() {
         var voteCounters = document.getElementById("voteContainer").
            getElementsByTagName("input");
         for(var i = 0; i < voteCounters.length; i++) {
            voteCounters[i].value = 0;
         }
      });

   // wire up reset button
   document.getElementById("resetVotes").onclick = function() {
      session.call("http://crossbar.io/crossbar/demo/vote#reset").
         then(ab.log, ab.log);
   };
}
         
CREATE or REPLACE PACKAGE BODY votes_api
AS

   FUNCTION get RETURN JSON_LIST
   AS
      l_res       SYS_REFCURSOR;
   BEGIN
      -- open cursor from query
      --
      OPEN l_res FOR
         SELECT subject AS "subject",
                votes   AS "votes"
           FROM votes ORDER BY subject;

      -- transform result set into JSON list of object
      --
      RETURN json_dyn.executeList(l_res);
   END get;


   FUNCTION vote (p_subject VARCHAR2) RETURN NUMBER
   IS
      l_votes     NUMBER;
      l_res       JSON := JSON();
   BEGIN
      -- check args
      --
      IF p_subject NOT IN ('Banana', 'Lemon',
         'Chocolate') THEN
         -- raise custom exception, this gets transformed
         -- into a proper RPC error return
         --
         webmq.raise(BASEURI || 'invalid_argument',
            'No subject "' || p_subject || '" to vote on.');
      END IF;

      -- update votes, returing new count
      --
      UPDATE votes SET votes = votes + 1
         WHERE subject = p_subject
            RETURNING votes INTO l_votes;
      COMMIT;

      -- create and publish PubSub event
      --
      l_res.put('subject', p_subject);
      l_res.put('votes', l_votes);
      webmq.publish(BASEURI || 'onvote', l_res);

      RETURN l_votes;
   END vote;


   PROCEDURE reset
   AS
   BEGIN
      -- reset all votes
      --
      UPDATE votes SET votes = 0;
      COMMIT;

      -- publish event with no payload
      --
      webmq.publish(BASEURI || 'onreset');
   END reset;

END;