<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <link rel="stylesheet" href="style.css">
  <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap-combined.min.css" rel="stylesheet">
  <script>document.write("<base href=\"" + document.location + "\" />");</script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
  <script src="http://code.angularjs.org/1.0.2/angular-resource.js"></script>
  <script src="app.js"></script>
  <script src="modal.js"></script>
  <script src="loading.js"></script>
</head>
<body>
<div ng-app="project">
  <h2>JavaScript Projects</h2>
  <div data-loading></div>
  <div ng-view></div>

  <!-- CACHE FILE: list.html -->
  <script type="text/ng-template" id="list.html">
    <input type="text" ng-model="search" class="search-query" placeholder="Search">
    <table>
      <thead>
      <tr>
        <th>Project</th>
        <th>Description</th>
        <th><a href="#/new"><i class="icon-plus-sign"></i></a></th>
      </tr>
      </thead>
      <tbody>
      <tr ng-repeat="project in projects | filter:search | orderBy:'name'">
        <td><a href="{{project.site}}" target="_blank">{{project.name}}</a></td>
        <td>{{project.description}}</td>
        <td>
          <a href="#/edit/{{project._id.$oid}}"><i class="icon-pencil"></i></a>
        </td>
      </tr>
      </tbody>
    </table>
  </script>



  <!-- CACHE FILE: detail.html -->
  <script type="text/ng-template" id="detail.html">
    <form name="myForm">
      <div class="control-group" ng-class="{error: myForm.name.$invalid}">
        <label>Name</label>
        <input type="text" name="name" ng-model="project.name" required>
        <span ng-show="myForm.name.$error.required" class="help-inline">
            Required</span>
      </div>
    
      <div class="control-group" ng-class="{error: myForm.site.$invalid}">
        <label>Website</label>
        <input type="url" name="site" ng-model="project.site" required>
        <span ng-show="myForm.site.$error.required" class="help-inline">
            Required</span>
        <span ng-show="myForm.site.$error.url" class="help-inline">
            Not a URL</span>
      </div>
    
      <label>Description</label>
      <textarea name="description" ng-model="project.description"></textarea>
    
      <br>
      <a href="#/list" class="btn">Cancel</a>
      <button ng-click="save()" ng-disabled="isClean() || myForm.$invalid"
              class="btn btn-primary">Save</button>
      <button ng-click="destroy()"
              ng-show="project._id" class="btn btn-danger">Delete</button>
    </form>
  </script>
</div>
</body>
</html>
angular.module('project', ['mongolab', 'LoadingModule']).
  config(function($routeProvider) {
    $routeProvider.
       when('/list', {controller:ListCtrl, templateUrl:'list.html'}).
      when('/edit/:projectId', {controller:EditCtrl, templateUrl:'detail.html'}).
      when('/new', {controller:CreateCtrl, templateUrl:'detail.html'}).
      otherwise({redirectTo:'/list'});
  });


function ListCtrl($scope, Project) {
  $scope.projects = Project.query();
}


function CreateCtrl($scope, $location, Project) {
  $scope.save = function() {
    Project.save($scope.project, function(project) {
      $location.path('/edit/' + project._id.$oid);
    });
  };
}

function EditCtrl($scope, $location, $routeParams, Project) {
  var self = this;

  Project.get({id: $routeParams.projectId}, function(project) {
    self.original = project;
    $scope.project = new Project(self.original);
  });

  $scope.isClean = function() {
    return angular.equals(self.original, $scope.project);
  };

  $scope.destroy = function() {
    self.original.destroy(function() {
      $location.path('/list');
    });
  };

  $scope.save = function() {
    $scope.project.update(function() {
      $location.path('/list');
    });
  };
}

// This is a module for cloud persistance in mongolab - https://mongolab.com
angular.module('mongolab', ['ngResource']).
    factory('Project', function($resource) {
      var Project = $resource('https://api.mongolab.com/api/1/databases' +
          '/angularjs/collections/projects/:id',
          { apiKey: '4f847ad3e4b08a2eed5f3b54' }, {
            update: { method: 'PUT' }
          }
      );

      Project.prototype.update = function(cb) {
        return Project.update({id: this._id.$oid},
            angular.extend({}, this, {_id:undefined}), cb);
      };

      Project.prototype.destroy = function(cb) {
        return Project.remove({id: this._id.$oid}, cb);
      };

      return Project;
    });
/* Put your css in here */

#Loading {
    display: none;
    line-height: 108px;
    font-size: 20px;
    font-weight: bold;
    text-align: center;
    height: 150px;
    width: 300px;
    border: 1px solid gray;

  left:50%;
	top:50%;
}
  angular.module('LoadingModule', ['ui.bootstrap.modal'])
           .config(function ($httpProvider) {
               $httpProvider.responseInterceptors.push('onCompleteInterceptor');
           })
           .factory('onCompleteInterceptor', function ($q, $window, LoadingSrv) {
               return function (promise) {
                   return promise.then(function (response) {
                       // do something on success
                       LoadingSrv.requestCount--;
                       return response;

                   }, function (response) {
                       // do something on error
                       LoadingSrv.requestCount--;
                       return $q.reject(response);
                   });
               };
           })
           .service('onStartInterceptor', function (LoadingSrv) {
               this.startSending = function (data, headersGetter) {
                   LoadingSrv.requestCount++;
                   return data;
               };
           })
           .factory('LoadingSrv', function () {
               return {
                   requestCount: 0,
                   isLoadingShown: function () {
                       return this.requestCount > 0;
                   }
               };
           })
           .run(function ($http, onStartInterceptor) {
               $http.defaults.transformRequest.push(onStartInterceptor.startSending);
           })
           .directive('loading', function (LoadingSrv) {
               return {
                   restrict: 'A',
                   replace: true,
                   template: '<div modal width="250" height="140" show="isshown" options="options" id="Loading"><div class="modal-body">Loading</div></div>',
                   controller: function ($scope, $element, $attrs, LoadingSrv) {
                       $scope.$watch(function () { return LoadingSrv.requestCount; }, function (newVal) {
                           $scope.isshown = LoadingSrv.isLoadingShown();
                       }, true);
                       $scope.options = {
                           backdrop: true,
                           escape: false
                       };
                   }
               };
           });
   // Angular UI  , Warning this is not the official version. It is customized. -maxisam
angular.module('ui.bootstrap.modal', []).directive('modal', ['$parse', function ($parse) {

            var body = angular.element(document.getElementsByTagName('body')[0]);
            var defaultOpts = {
                backdrop: true,
                escape: true
            };
            return {
                restrict: 'ECA',
                link: function (scope, elm, attrs) {
                    var backdropEl;
                    var opts = angular.extend(defaultOpts, scope.$eval(attrs.uiOptions || attrs.bsOptions || attrs.options));
                    var shownExpr = attrs.modal || attrs.show;
                    var setClosed;
                    if (attrs.close) {
                        setClosed = function () {
                            scope.$apply(attrs.close);
                        };
                    } else {
                        setClosed = function () {
                            scope.$apply(function () {
                                $parse(shownExpr).assign(scope, false);
                            });
                        };
                    }
                    elm.addClass('modal');
                    if (opts.backdrop && !backdropEl) {
                        backdropEl = angular.element('<div class="modal-backdrop ngModal"></div>');
                        backdropEl.css('display', 'none');
                        elm.parent().append(backdropEl);
                    }
                    function setSize(scope, elm, width, height) {

                        var footerH = $(elm).find('.modal-footer').outerHeight();
                        width && elm.css({ 'width': width + 'px', 'margin-left': (-width / 2) + 'px' });
                        height && elm.css({ 'height': height + 'px', 'margin-top': (-height / 2) + 'px' });
                        //console.log(headerFooterH);

                        height && scope.$watch(function (s) {
                            return elm.find('.modal-header').height();
                        }, function (newVal) {
                            elm.find('.modal-body').css({
                                'height': function () {
                                    return (height - footerH - $(elm).find('.modal-header').outerHeight(true) - 30) + 'px';
                                }
                            });
                        }, true);
                        height || scope.$watch(function (s) {
                            return elm.height();
                        }, function (newVal) {
                            elm.css({
                                'margin-top': function () {
                                    return (-newVal / 2) + 'px';
                                }
                            });
                        }, true);

                    }
                    function setShown(shown) {
                        scope.$apply(function () {
                            model.assign(scope, shown);
                        });
                    }

                    function escapeClose(evt) {
                        if (evt.which === 27) { setClosed(); }
                    }
                    function clickClose() {
                        setClosed();
                    }

                    function close() {
                        if (opts.escape) { body.unbind('keyup', escapeClose); }
                        if (opts.backdrop) {
                            backdropEl.css('display', 'none').removeClass('in');
                            backdropEl.unbind('click', clickClose);
                        }
                        elm.css('display', 'none').removeClass('in');
                        body.removeClass('modal-open');
                    }
                    function open() {
                        if (opts.escape) { body.bind('keyup', escapeClose); }

                        if (opts.backdrop) {
                            backdropEl.css('display', 'block').addClass('in');
                            backdropEl.bind('click', clickClose);
                        }
                        elm.css('display', 'block').addClass('in');
                        body.addClass('modal-open');
                        setSize(scope, elm, attrs.width, attrs.height);
                    }
                    scope.$watch(shownExpr, function (isShown, oldShown) {
                        if (isShown) {
                            open();
                        } else {
                            close();
                        }
                    });
                }
            };
        }]);