<!DOCTYPE html>
<html class="no-js">

  <head>
    <meta charset="utf-8" />
    <title></title>
    <meta name="description" content="" />
    <meta name="viewport" content="width=device-width" />
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
  </head>

  <body ng-app="angNewsApp">
    <!--[if lt IE 7]>
    <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
  <![endif]-->
    <!-- Add your site or application content here -->
    <div class="container">
      <div ng-include="'nav.html'"></div>
      <div ng-view=""></div>
      <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
      <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-resource.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-cookies.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-sanitize.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-animate.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-touch.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-route.js"></script>
      <script src="https://cdn.firebase.com/v0/firebase.js"></script>
      <script src="https://cdn.firebase.com/libs/angularfire/0.8.2/angularfire.min.js"></script>
      <script src="https://cdn.firebase.com/js/simple-login/1.6.3/firebase-simple-login.js"></script>
      <!-- App files -->
      <script src="app.js"></script>
      <script src="posts.controller.js"></script>
      <script src="postview.controller.js"></script>
      <script src="auth.controller.js"></script>
      <script src="profile.controller.js"></script>
      <script src="nav.controller.js"></script>
      <script src="post.service.js"></script>
      <script src="auth.service.js"></script>
      <script src="user.service.js"></script>
      <script src="url.filter.js"></script>
      <script src="checkusername.directive.js"></script>
    </div>
  </body>

</html>
/* global app:true */

var app = angular.module('angNewsApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch',
		'firebase'
  ])
	.constant('FIREBASE_URL', 'https://angfirenews.firebaseio.com/');

app.config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'posts.html',
        controller: 'PostsCtrl'
      })
      .when('/posts/:postId', {
        templateUrl: 'showpost.html',
        controller: 'PostViewCtrl'
      })
      .when('/register', {
        templateUrl: 'register.html',
        controller: 'AuthCtrl'
      })
      .when('/login', {
        templateUrl: 'login.html',
        controller: 'AuthCtrl'
      })
      .when('/users/:username', {
        templateUrl: 'profile.html',
        controller: 'ProfileCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
});
app.controller('PostsCtrl', function($scope, $location, $routeParams, Post) {

	if($location.path() === '/') {
		$scope.posts = Post.all;
	}

	$scope.post = {url: 'http://', title: ''};

	$scope.deletePost = function(post) {
		Post.delete(post);
	};

	$scope.comments = Post.comments($routeParams.postId).$asArray();

	$scope.addComment = function() {
		Post.addComment($routeParams.postId, $scope.comment);
		$scope.comment = '';
	};

	$scope.removeComment = function (comment) {
		Post.deleteComment($scope.post, comment);
	};

});
app.controller('PostViewCtrl', function($scope, $routeParams, Post) {
	$scope.post = Post.find($routeParams.postId);
});
app.controller('AuthCtrl',
  function ($scope, $location, Auth, User) {
    if (Auth.signedIn()) {
      $location.path('/');
    }
 
		$scope.$on('firebaseSimpleLogin:login', function() {
      $location.path('/');
		});

		$scope.login = function() {
			Auth.login($scope.user).then(function() {
				$location.path('/');
			}, function(error) {
				$scope.error = error.toString();
			});
		};

  });
app.controller('ProfileCtrl',
  function ($scope, $routeParams, Post, User) {
    $scope.user = User.findByUsername($routeParams.username);

		$scope.posts = {};
		$scope.commentedPosts = {};
		$scope.comments = {};

    $scope.user.$loaded(function () {
      populatePosts();
      populateComments();
    });

    function populatePosts () {
      var posts = User.posts($routeParams.username).$asArray();

      posts.$loaded(function (){
        angular.forEach(posts, function (post){
          $scope.posts[post.$id] = Post.find(post.$id);
        });
      });
    }

		function populateComments () {
			var comments = User.comments($routeParams.username).$asArray();

			comments.$loaded(function () {
				angular.forEach(comments, function (comment) {
					var post = Post.find(comment.$value);

					post.$loaded(function () {
						var postComments = Post.comments(comment.$value).$asObject();

						postComments.$loaded(function () {
							$scope.commentedPosts[comment.$id] = post;
							$scope.comments[comment.$id] = postComments[comment.$id];
						});
					});
				});
			});
		}

  });
app.controller('NavCtrl', function($scope, $location, Post, Auth) {
	$scope.post = {url: 'http://', title: ''};

	$scope.submitPost = function () {
		Post.create($scope.post).then(function (postId) {
			$scope.post = {url: 'http://', title: ''};
			$location.path('/posts/' + postId);
		});
	};

	$scope.logout = function() {
		Auth.logout();
	};

});
app.factory('Post', function($firebase, FIREBASE_URL, User){
	var ref = new Firebase(FIREBASE_URL + 'posts');
	var posts = $firebase(ref).$asArray();

	var Post = {
		all: posts,
		create: function(post) {
			if(User.signedIn()) {
				var user = User.getCurrent();
				post.owner = user.username;

				return posts.$add(post).then(function(ref) {
					var postId = ref.name();

					User.posts(user.username).$set(postId, postId);

					return postId;
				});
			}
		},
		find: function(postId) {
			return $firebase(ref.child(postId)).$asObject();
		},
		delete: function (post) {
			if (User.signedIn()){
				var user = User.getCurrent();
				if (user.username === post.owner) {
					posts.$remove(post).then(function () {
						User.posts(user.username).$remove(post.$id);
						console.log(post.$id);
					});
				}
			}
		},
		comments: function(postId) {
			return $firebase(new Firebase(FIREBASE_URL + 'comments/' + postId));
		},
		addComment: function (postId, comment) {
			if (User.signedIn()) {
				var user = User.getCurrent();

				comment.username = user.username;
				
				console.log('postID = ' + postId);

				Post.comments(postId).$push(comment).then(function() {
					var commentId = ref.name();
					console.log('commentID = ' + commentId);

					User.comments(user.username).$set(commentId, postId);
				});
			}
		},
		deleteComment: function (postId, comment) {
			if (User.signedIn()) {
				var user = User.findByUsername(comment.username);
				var commentId = comment.$id;

				Post.comments(postId).$remove(commentId).then(function () {
					User.comments(user.username).$remove(commentId);
				});
			}
		}
	};

	return Post;

});
app.factory('Auth',
  function ($firebaseSimpleLogin, FIREBASE_URL, $rootScope) {
    var ref = new Firebase(FIREBASE_URL);
 
    var auth = $firebaseSimpleLogin(ref);
 
    var Auth = {
      signedIn: function () {
        return auth.user !== null;
      },
			login: function(user) {
				return auth.$login('password', user);				
			},
      logout: function () {
        auth.$logout();
      }
    };
 
    $rootScope.signedIn = function () {
      return Auth.signedIn();
    };
 
    return Auth;
  });
app.factory('User', function ($firebase, FIREBASE_URL, $rootScope, $log) {
  var ref = new Firebase(FIREBASE_URL + 'users');
  var users = $firebase(ref);

	function setCurrentUser(username) {
		$rootScope.currentUser = User.findByUsername(username);
	}

	$rootScope.$on('$firebaseSimpleLogin:login', function (event, authUser) {
		var query = $firebase(ref.startAt(authUser.uid).endAt(authUser.uid)).$asArray();
	 
		query.$loaded(function () {
			setCurrentUser(query[0].username);
		});

	});

	$rootScope.$on('$firebaseSimpleLogin:logout', function() {
		delete $rootScope.currentUser;
	});
 
  var User = {
    create: function (authUser, username) {
			var user = $firebase(ref.child(username)).$asObject();

			return user.$loaded(function() {
				user.username = username;
				/*jshint camelcase: false */
        user.md5_hash = authUser.md5_hash;
        user.$priority = authUser.uid;
				user.$save();
			});

			$log.debug(users);
    },
		findByUsername: function (username) {
			if (username) {
				return $firebase(ref.child(username)).$asObject();
			}
		},
		getCurrent: function () {
			return $rootScope.currentUser;
		},
		signedIn: function () {
			return $rootScope.currentUser !== undefined;
		},
		posts: function(username) {
			return $firebase(new Firebase(FIREBASE_URL + 'user_posts/' + username));
		},
		comments: function (username) {
			return $firebase(new Firebase(FIREBASE_URL + 'user_comments/' + username));
		}
  };
	
  return User;
});
app.filter('hostnameFromUrl', function() {
	return function(str) {
		var url = document.createElement('a');

		url.href = str;

		return url.hostname;
	};
});
angular.module('angNewsApp').directive('checkUsername', function(User) {
  var usernameRegexp = /^[^.$\[\]#\/\s]+$/;

  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.push(function(viewValue) {
        if (usernameRegexp.test(viewValue)) {
          User.findByUsername(viewValue).$loaded(function (user){
            if (user.$value === null){
              ctrl.$setValidity('taken', true);
              ctrl.$setValidity('invalid', true);
            } else {
              ctrl.$setValidity('taken', false);
              ctrl.$setValidity('invalid', true);
            }
          });

          return viewValue;
        } else {
          ctrl.$setValidity('taken', true);
          ctrl.$setValidity('invalid', false);

          return viewValue;
        }
      });
    }
  };
});
<div class="container posts-page">
 
  <div class="post row" ng-repeat="(postId, post) in posts">
    <div class="col-xs-1">
 
    </div>
    <div class="col-md-9 col-xs-11">
 
      <div class="info">
        <a href="{{ post.url }}">
          {{ post.title }}
					<span class="url">({{post.url | hostnameFromUrl}})</span>
        </a>
      </div>
      <div>
				<span>{{ post.score || 0 }} votes</span>
        &mdash;
				<span>submitted by <a href="#/users/{{post.owner}}" >{{ post.owner }}</a></span>
        &mdash;
        <a href="#/posts/{{ post.$id }}">comments</a>
        <a ng-click="deletePost(post)" ng-show="signedIn() && post.owner === currentUser.username">delete</a>
      </div>
    </div>
    <div class="col-md-2">
      
    </div>
 
  </div>


</div>
<div class="container posts-page">

  <div class="post row">
    <div class="col-xs-1">

    </div>
    <div class="col-md-9 col-xs-11">

      <div class="info">
        <a href="{{ post.url }}">
          {{ post.title }}
          <span class="url">({{ post.url | hostnameFromUrl }})</span>
        </a>
      </div>
      <div>
        <span>submitted by <a href="#/users/{{ post.owner }}">{{ post.owner }}</a></span>
      </div>
    </div>
    <div class="col-md-2">

    </div>

  </div>

 <div ng-repeat="comment in comments" class="row cmt">
    <div class="col-md-12">
      <p>{{ comment.text }}</p>
      <p class="author">posted by <a href="#/users/{{ comment.username }}">{{ comment.username }}</a></p>
    </div>
  </div>


  <div class="cmt-form">
    <div ng-hide="signedIn()">
      <p><a href="#/login">Sign in</a> to post a comment</p>
    </div>

    <form ng-show="signedIn()">
      <textarea ng-model="comment.text" placeholder="Post a Comment" class="form-control"></textarea><br />
      <input type="submit" ng-click="addComment()" value="Post Comment" class="btn btn-primary" />
    </form>
  </div>

</div>
<div class="auth-forms">
 
  <h2>Register</h2>
 
	<form ng-submit="register()" name="form">
		<div ng-show="error || form.username.$error">
			<p ng-show="error" class="text-danger"></p>
			<p ng-show="form.username.$error.taken" class="text-danger">Username is already taken.</p>
			<p ng-show="form.username.$error.invalid" class="text-danger">Username contains invalid characters.</p>
		</div>
		<input type="email" ng-model="user.email" placeholder="Email" class="form-control"><br>
		<input type="text" ng-model="user.username" placeholder="Username" name="username" check-username class="form-control"><br>
		<input type="password" ng-model="user.password" placeholder="Password" class="form-control"><br>
		<input type="submit" value="Register" class="btn btn-primary" />
	</form>

</div>
<div class="auth-forms">
 
  <h2>Log In</h2>
 
  <form ng-submit="login()">
		<p ng-show="error" class="text-danger">{{error}}</p>
    <input type="email" ng-model="user.email" placeholder="Email" class="form-control"><br>
    <input type="password" ng-model="user.password" placeholder="Password" class="form-control"><br>
    <input type="submit" value="Log in" class="btn btn-primary" />
  </form>
 
</div>
<div class="container profile">

  <div class="row">
    <div class="col-sm-1">
      <img ng-src="http://www.gravatar.com/avatar/{{ user.md5_hash }}" class="prof-img" />
    </div>

    <div class="col-sm-10">
      <span class="name">
        {{ user.username }}
      </span>
    </div>

  </div>


  <div class="row">

    <ul class="nav nav-tabs">
      <li class="active"><a data-target="#submissions" data-toggle="tab">Submissions</a></li>
      <li><a data-target="#comments" data-toggle="tab">Comments</a></li>
    </ul>

  </div>

</div>

<div class="tab-content">
  <div ng-include="'views/posts.html'" class="tab-pane active" id="submissions" ng-controller="PostsCtrl"></div>
  <div class="container posts-page tab-pane" id="comments">
    <div class="post row" ng-repeat="(commentId, comment) in comments">
      <div class="col-xs-1">

      </div>
      <div class="col-md-9 col-xs-11">
        <div class="info">
          <a href="{{ commentedPosts[commentId].url }}">{{ commentedPosts[commentId].title }}</a>
          <span class="url">({{ commentedPosts[commentId].url | hostnameFromUrl }})</span>
        </div>

        <a href="#/posts/{{ commentedPosts[commentId].$id }}">comments</a>
        <p>{{ comment.text }}</p>
      </div>
      <div class="col-md-2">

      </div>
    </div>
  </div>
</div>
<nav class="navbar navbar-default" role="navigation">
  <!-- Brand and toggle get grouped for better mobile display -->
  <div class="navbar-header">
    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
      <span class="sr-only">Toggle navigation</span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
      <span class="icon-bar"></span>
    </button>
    <a class="navbar-brand" href="#">ng-news</a>
  </div>
 
  <!-- Collect the nav links, forms, and other content for toggling -->
  <div ng-controller="NavCtrl" class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
    <form class="navbar-form navbar-left" role="search" ng-submit="submitPost()" ng-show="signedIn()">
      <div class="form-group">
        <input type="text" class="form-control" placeholder="Title" ng-model="post.title">
      </div>
      <div class="form-group">
      <input type="text" class="form-control" placeholder="Link" ng-model="post.url">
      </div>
      <button type="submit" class="btn btn-default">Submit</button>
    </form>
		<ul class="nav navbar-nav navbar-right" ng-show="signedIn()">
			<li>
				<a href="#/users/{{ currentUser.username }}">
					<img ng-src="http://www.gravatar.com/avatar/{{ currentUser.md5_hash }} class="nav-pic" />
					{{ currentUser.username }}
				</a>
			</li>
			<li>
				<a href="#" ng-click="logout()">Logout</a>
			</li>
		</ul>
		<ul class="nav navbar-nav navbar-right" ng-hide="signedIn()">
			<li>
				<a href="#/login">Log In</a>
			</li>
		</ul>
  </div><!-- /.navbar-collapse -->
</nav>