GUI: adding LoadingService module.

Change-Id: I73f479965416a2e48506854c6b4ea543e6a37ad5
diff --git a/web/gui/src/main/webapp/app/fw/layer/loading.css b/web/gui/src/main/webapp/app/fw/layer/loading.css
new file mode 100644
index 0000000..9c8d354
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/layer/loading.css
@@ -0,0 +1,27 @@
+/*
+ *  Copyright 2015 Open Networking Laboratory
+ *
+ *  Licensed 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.
+ */
+
+/*
+ ONOS GUI -- Loading Service -- CSS file
+ */
+
+#loading-anim {
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    -webkit-transform: translate(-50%, -50%);
+    transform: translate(-50%, -50%);
+}
diff --git a/web/gui/src/main/webapp/app/fw/layer/loading.js b/web/gui/src/main/webapp/app/fw/layer/loading.js
new file mode 100644
index 0000000..7691f09
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/layer/loading.js
@@ -0,0 +1,86 @@
+/*
+ *  Copyright 2015 Open Networking Laboratory
+ *
+ *  Licensed 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.
+ */
+
+/*
+ ONOS GUI -- Layer -- Loading Service
+
+ Provides a mechanism to start/stop the loading animation, center screen.
+ */
+(function () {
+    'use strict';
+
+    // injected references
+    var $log, $timeout, ts;
+
+    // constants
+    var id = 'loading-anim',
+        dir = 'data/img/loading/',
+        pfx = '/load-',
+        speed = 100;
+
+    // internal state
+    var div,
+        img,
+        th,
+        idx,
+        task;
+
+    function fname(i) {
+        var z = i > 9 ? '' : '0';
+        return dir + th + pfx + z + i + '.png';
+    }
+
+    function nextFrame() {
+        idx = idx === 16 ? 1 : idx + 1;
+        img.attr('src', fname(idx));
+        task = $timeout(nextFrame, speed);
+    }
+
+    // start displaying 'loading...' animation (idempotent)
+    function start() {
+        th = ts.theme();
+        div = d3.select('#'+id);
+        if (div.empty()) {
+            div = d3.select('body').append('div').attr('id', id);
+            img = div.append('img').attr('src', fname(1));
+            idx = 1;
+            task = $timeout(nextFrame, speed);
+        }
+    }
+
+    // stop displaying 'loading...' animation (idempotent)
+    function stop() {
+        if (task) {
+            $timeout.cancel(task);
+            task = null;
+        }
+        d3.select('#'+id).remove();
+    }
+
+    angular.module('onosLayer')
+        .factory('LoadingService', ['$log', '$timeout', 'ThemeService',
+        function (_$log_, _$timeout_, _ts_) {
+            $log = _$log_;
+            $timeout = _$timeout_;
+            ts = _ts_;
+
+            return {
+                start: start,
+                stop: stop
+            };
+        }]);
+
+}());
\ No newline at end of file
diff --git a/web/gui/src/main/webapp/app/fw/remote/websocket.js b/web/gui/src/main/webapp/app/fw/remote/websocket.js
index 1c03d6f..3fef75f 100644
--- a/web/gui/src/main/webapp/app/fw/remote/websocket.js
+++ b/web/gui/src/main/webapp/app/fw/remote/websocket.js
@@ -21,7 +21,7 @@
     'use strict';
 
     // injected refs
-    var $log, $loc, fs, ufs, wsock, vs;
+    var $log, $loc, fs, ufs, wsock, vs, ls;
 
     // internal state
     var webSockOpts,            // web socket options
@@ -105,6 +105,7 @@
         var gsucc;
 
         $log.info('Web socket closed');
+        ls.stop();
         wsUp = false;
 
         if (gsucc = findGuiSuccessor()) {
@@ -301,15 +302,16 @@
     angular.module('onosRemote')
     .factory('WebSocketService',
         ['$log', '$location', 'FnService', 'UrlFnService', 'WSock',
-            'VeilService',
+            'VeilService', 'LoadingService',
 
-        function (_$log_, _$loc_, _fs_, _ufs_, _wsock_, _vs_) {
+        function (_$log_, _$loc_, _fs_, _ufs_, _wsock_, _vs_, _ls_) {
             $log = _$log_;
             $loc = _$loc_;
             fs = _fs_;
             ufs = _ufs_;
             wsock = _wsock_;
             vs = _vs_;
+            ls = _ls_;
 
             bindHandlers(builtinHandlers);
 
diff --git a/web/gui/src/main/webapp/index.html b/web/gui/src/main/webapp/index.html
index 7e0d9b7..de70334 100644
--- a/web/gui/src/main/webapp/index.html
+++ b/web/gui/src/main/webapp/index.html
@@ -76,6 +76,7 @@
     <script src="app/fw/layer/flash.js"></script>
     <script src="app/fw/layer/quickhelp.js"></script>
     <script src="app/fw/layer/veil.js"></script>
+    <script src="app/fw/layer/loading.js"></script>
 
     <!-- Framework and library stylesheets included here -->
     <!-- TODO: use a single catenated-minified file here -->
@@ -88,6 +89,7 @@
     <link rel="stylesheet" href="app/fw/layer/flash.css">
     <link rel="stylesheet" href="app/fw/layer/quickhelp.css">
     <link rel="stylesheet" href="app/fw/layer/veil.css">
+    <link rel="stylesheet" href="app/fw/layer/loading.css">
     <link rel="stylesheet" href="app/fw/nav/nav.css">
     <link rel="stylesheet" href="app/fw/widget/button.css">
     <link rel="stylesheet" href="app/fw/widget/toolbar.css">