wm: java

Download patch

ref: fd5476ab0c29f10d063c9f829f0cb2c57692d38f
parent: 1434af4cd218fa6b2c7e09acf0720a3421f778c7
author: mkf <mkf@d510>
date: Mon May 29 17:41:42 EDT 2023

god knows what i did

--- a/Main.java
+++ b/Main.java
@@ -1,25 +1,27 @@
 //package BookProj;
 
-// XXX get rid of *s
 // handle throws
 // make whatever you can final
 
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.TreeMap;
 
-/*
-import java.util.regex.Pattern; // Pattern, Matcher
-import java.util.Matcher; // Scanner, ArrayList
 import java.util.Scanner;
-*/
-import java.util.*;
-import java.time.LocalDateTime;
 
+import java.util.NoSuchElementException;
+import java.io.IOException;
+
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 
 import java.io.Console;
 import java.io.File;
+import java.io.FileWriter;
 
-enum Err
+import java.time.LocalDateTime;
+
+enum TakeErr
 {
 	Ok,
 
@@ -29,10 +31,19 @@
 
 	NoUser, /* no such user has found */
 	UserHasABook, /* User has already registered a book */
-	UserHasNoBook,
 	Age; /* age doesn't match */
 }
 
+/* used in DelAdmin, DelUser and DelBook */
+enum DelErr
+{
+	Ok,
+	BookReserved, /* book we are trying to delete has been reserved by someone */
+	UserHasABook, /* user we are trying to delete has a book */
+	NoBook,
+	NoUser;
+}
+
 enum Role
 {
 	Admin,
@@ -74,50 +85,47 @@
 
 interface Library 
 {
-	/* admin */
-	boolean Login(Admin a, String pass);
-	void Logout(Admin a);
-
 	Admin NewAdmin(String user, String pass);
-	void DelAdmin(Admin a);
+	User NewUser(String user, int age);
+	Book NewBook(String isbn, String name, String author, int agegroup, String abst);
 
-	boolean CheckAdmin(String a);
-	Admin MatchAdmin(String un);
-	boolean FindAdmin(AdminAttr k, Pattern p);
+	DelErr DelAdmin(Admin a);
+	DelErr DelUser(User u);
+	DelErr DelBook(Book b);
 
-	/* user */
+	boolean Login(Admin a, String pass);
 	boolean Login(User u);
-	// void Logout(User u);
 
-	// User NewUser();
-	// void DelUser(User u);
+	void Logout(Admin a);
+	void Logout(User u);
 
+	boolean CheckAdmin(String a);
 	boolean CheckUser(String u);
+	boolean CheckBook(String isbn);
+
+	Admin MatchAdmin(String un);
 	User MatchUser(String un);
+	Book MatchBook(String isbn);
+
+	boolean FindAdmin(AdminAttr k, Pattern p);
 	boolean FindUser(UserAttr k, Pattern p);
+	boolean FindBook(BookAttr k, Pattern p);
 
-	/* books */
-	Err TakeBook(String un, String isbn);
-	Err TakeBook(Admin u, Book b);
-	Err TakeBook(User u, Book b);
+	TakeErr TakeBook(String un, String isbn);
+	TakeErr TakeBook(Admin u, Book b);
+	TakeErr TakeBook(User u, Book b);
 
-	Err ReturnBook(User u);
-	Err ReturnBook(Admin u);
+	TakeErr ReturnBook(User u);
+	TakeErr ReturnBook(Admin u);
 
-	Book NewBook(String isbn, String name, String author, int agegroup, String abst);
-	void DelBook(Book b);
+	void SaveLog(String fp, String in);
 
-	boolean CheckBook(String ISBN);
-	Book MatchBook(String isbn);
-	boolean FindBook(BookAttr k, Pattern p);
-
 	/*
-	Err ReturnBook(Book b);
-	boolean WriteStatus();
-	boolean FindBook(boolean q);  for Status value searchs 
+	String LoadLog(File fd, int n);
+	void LoadState(File fd);
+	void SaveState(File fd);
 	*/
 
-
 	interface UI
 	{
 		void Program();
@@ -124,22 +132,17 @@
 		void LoginMenu();
 
 		/* checks password with user, gets input from GetPassword */
-		// boolean AskPass(Admin u);
+		boolean AskPass(Admin u);
 		// boolean AskPass(User u);
 
 		/* different Menus, for different Users to handle */
 		void Menu(Admin u);
-		// void Menu(User u);
+		void Menu(User u);
 
 		/* Gets a String, either console or scanner, checks if it's valid or not, and encrypt it */
 		String GetUsername();
 		String GetPassword();
 		
-		/* asks for user/book info, returns username/isbn if it exists */
-		// String AskAdmin();
-		// String AskUser();
-		// String AskBook();
-
 		/* search foolan menu */
 		void SearchAdmin();
 		void SearchUser();
@@ -147,13 +150,13 @@
 
 		/* add foolan menu */
 		void AddAdmin();
-		// void AddUser();
+		void AddUser();
 		void AddBook();
 
 		/* remove foolan menu */
-		// void RemAdmin();
-		// void RemUser();
-		// void RemBook(); // maybe it's stolen
+		void RemAdmin();
+		void RemUser();
+		void RemBook(); // maybe it's stolen
 
 		/* list foolan menu */
 		void ListAdmin();
@@ -163,11 +166,13 @@
 		/* take and return book menus */
 		void TakeMenu(Admin a);
 		void TakeMenu(User u);
-		// void ReturnMenu(Admin a);
-		// void ReturnMenu(User u);
+		void ReturnMenu(Admin a);
+		void ReturnMenu(User u);
 
-		/* handles result of Take/Return menu */
-		void Result(Err res);
+		/* handles result of Take/IO/Del Funcations */
+		void Result(TakeErr res);
+		void Result(DelErr res);
+		void Result(IOErr res);
 	}
 }
 
@@ -195,8 +200,6 @@
 	private String Abstract, Author, Name, ISBN;
 	private String Owner = ""; /* Username of user who reserved it */
 	private int AgeGroup;
-	/* should a register be a constractor? XXX
-		 should it even named register? */
 
 	Book(String isbn, String name, String author, int age, String abs)
 	{
@@ -219,23 +222,18 @@
 	boolean setOwner(String u)
 	{
 		if(!this.Owner.isEmpty())
-		{
-			System.err.println("A User (ID:" + this.getOwner() + ") already got the book");
 			return false;
-		}
+
 		this.Owner = u;
 		return true;
 	}
 
-	boolean setStatus(boolean b)
+	void setStatus(boolean b)
 	{
 		if(this.Status == b)
-		{
-			System.err.println("book (ISBN: " + this.getISBN() + ") status already set to: " + this.Status);
-			return false;  
-		}
+			throw new IllegalStateException("Status already set!");
+
 		this.Status = b;
-		return true;
 	}
 
 	boolean getStatus()
@@ -292,7 +290,10 @@
 abstract class BasicUser
 {
 	private Role role;
-	private String Username, Reserved;
+	private String Username;
+
+	/* we will use isEmpty, even if it's not init-ed */
+	private String Reserved = new String();
 	private int ID;
 	private LocalDateTime RegTime;
 	public boolean Active = false;
@@ -322,29 +323,19 @@
 		return this.ID;
 	}
 
-	boolean setReserved(String ISBN)
+
+	void clearReserved()
 	{
-		/* ensure he has no books */
-		if(this.Reserved == null)
-		{
-			/* ensure book is not taken by someone else 
-			if(
-			return true; */
-			return true;
-		}
-		else
-		{
-			System.err.println("the user already have a book");
-			return false;
-		}	
+		this.Reserved = "";
 	}
 
-	boolean hasReserved()
+	void setReserved(String isbn)
 	{
-		if(this.Reserved.isEmpty())
-			return false;
-		else
-			return true;
+		/* ensure he has no books */
+		if(!this.getReserved().isEmpty() && !isbn.equals(""))
+			throw new IllegalStateException("User already has a book!");
+
+		this.Reserved = isbn;
 	}
 
 	String getReserved()
@@ -373,15 +364,6 @@
 		this.setPassword(Pass);
 	}
 
-	boolean setReserved(String ISBN)
-	{
-		return false; /* XXX */
-	}
-
-	boolean isReserved(String ISBN)
-	{
-		return false; /* XXX */
-	}
 	boolean checkPass(String pass)
 	{
 		if(this.Password.equals(pass))
@@ -389,7 +371,9 @@
 		else
 			return false;
 	}
-	void setPassword(String pass)
+
+	/* passwords should be unchangeable... for now */
+	private void setPassword(String pass)
 	{
 		this.Password = pass;
 	}
@@ -425,18 +409,12 @@
 
 	boolean IsReserved(Book b)
 	{
-		if(this.getReserved().equals(b.getISBN()))
-			return true;
-		else
-			return false;
+		return (this.getReserved().equals(b.getISBN()));
 	}
 
 	boolean IsReserved(String ISBN)
 	{
-		if(this.getReserved() == ISBN)
-			return true;
-		else
-			return false;
+		return (this.getReserved().equals(ISBN));
 	}
 
 	TreeMap<UserAttr, String> toMap()
@@ -468,45 +446,22 @@
 
 	static Admin adm;
 	static User usr;
+	static String logfile = "Log.txt";
 	int ResCount = 0;
 
 
-	/* is hasNextLine is of any of use? i wonder, says timmy */
-	public int readint(Scanner s, String errmsg, String inputmsg)
-	{
-		System.out.println(inputmsg);
-		while(!s.hasNextLine())
-		{
-			System.err.println(errmsg);
-			System.out.print(inputmsg);
-			s.nextLine();
-		}
-		return s.nextInt();
-	}
-
-	public String readstr(Scanner s, String errmsg, String inputmsg)
-	{
-		System.out.println(inputmsg);
-		while(!s.hasNextLine())
-		{
-			System.err.println(errmsg);
-			System.out.print(inputmsg);
-			s.nextLine();
-		}
-		return s.nextLine();
-	}
-
 	public boolean Login(Admin u, String pass)
 	{
 			/* clear null */
 			adm = null;
 			if(u.Active)
-				throw new IllegalStateException("Admin is already active?");
+				throw new IllegalStateException("Admin is already active");
+
 			/* maybe later i want to do more stuff here */
 			if(u.checkPass(pass))
 			{
 				u.Active = true;
-				adm = u;
+				this.adm = u;
 				return true;
 			}
 			else
@@ -514,20 +469,15 @@
 			
 	}
 
-	public void Logout(Admin u)
+	public void Logout(Admin a)
 	{
-		boolean b = false;
-
-		for(Admin i : this.AdminList.values())
-		{
-			if(i == u)
-				b = true;
-		}
-
-		if(!b)
+		if(!CheckAdmin(a.getUsername()))
 			throw new NoSuchElementException("No such Admin exists.");
 
-		u.Active = false;
+		if(!a.Active)
+			throw new IllegalStateException("Admin is already inactive");
+
+		a.Active = false;
 	}
 
 	public boolean Login(User u)
@@ -536,74 +486,102 @@
 			throw new IllegalStateException("Admin is already active?");
 		/* maybe later i want to do more stuff here */
 		u.Active = true;
+		usr = u;
 		return true;
 	}
 
+	public void Logout(User u)
+	{
+		if(!CheckUser(u.getUsername()))
+			throw new NoSuchElementException("No such User exists.");
+
+		if(!u.Active)
+			throw new IllegalStateException("User is already inactive.");
+
+		u.Active = false;
+	}
+
 	public Admin NewAdmin(String user, String pass)
 	{
 		Admin a;
-		for(Admin i : this.AdminList.values())
-		{
-			if(i.getUsername().equals(user))
-				throw new IllegalArgumentException("Admin already exists");
-		}
+		if(CheckUser(user))
+			throw new IllegalArgumentException("Admin already exists");
 
 		/* if user is "admin", use defaults */
 		if(user.equals("admin"))
-			a = new Admin("admin", "pass");
-		else
-			a = new Admin(user, pass);
+		{
+			pass = "pass";
+			pass = Integer.toString(pass.hashCode());
+		}
+		a = new Admin(user, pass);
 
-		if(this.AdminList.size() == 0)
-			adm = a;
-
 		this.AdminList.put(a.getUsername(), a);
 		return a;
 	}
 
-	/* i could've made them overload,
-		however, this might led to unwanted results */
-	public void DelAdmin(Admin u)
+	public DelErr DelAdmin(Admin u)
 	{
 		if(!u.getReserved().isEmpty())
-		{
-			System.err.println("Admin " + u.getUsername() + " has a reserved book.");
-			return;
-		}
+			return DelErr.UserHasABook;
+
 		this.AdminList.remove(u.getUsername(), u);
+		return DelErr.Ok;
 	}
 
-	public void DelUser(User u)
+	public User NewUser(String user, int age)
 	{
+		User u;
+		if(CheckUser(user))
+			throw new IllegalArgumentException("User already exists");
+
+		u = new User(user, age);
+
+		this.UserList.put(user, u);
+		return u;
+	}
+
+	public DelErr DelUser(User u)
+	{
 		if(!u.getReserved().isEmpty())
-		{
-			System.err.println("User " + u.getUsername() + " has a reserved book.");
-			return;
-		}
+			return DelErr.UserHasABook;
 		this.UserList.remove(u.getUsername(), u);
+		return DelErr.Ok;
 	}
 
 	public Book NewBook(String isbn, String name, String author, int agegroup, String abst)
 	{
-		for(Book b : this.BookList.values())
-		{
-			if(b.getISBN().equals(isbn))
+		Book b;
+		if(CheckBook(isbn))
 				throw new IllegalStateException("Book already exist");
-		}
 
-		Book b = new Book(isbn, name, author, agegroup,  abst);
+		if(agegroup > 99)
+			agegroup = 99;
+		if(agegroup < 2)
+			agegroup = 3;
+
+		b = new Book(isbn, name, author, agegroup, abst);
 		this.BookList.put(isbn, b);
 		return b;
 	}
 
-	public void DelBook(Book b)
+	/* we shouldn't use MatchBook on UI, input is taken from user in string form */
+	public DelErr DelBook(String isbn)
 	{
+		if(!CheckBook(isbn))
+			return DelErr.NoBook;
+
+		return DelBook(MatchBook(isbn));
+	}
+
+	public DelErr DelBook(Book b)
+	{
 		if(!b.getOwner().isEmpty())
-		{
 			// System.err.println("User " + b.getOwner() + " have reserved this book.");
-			throw new IllegalStateException("Book is reserved.");
-		}
+			// throw new IllegalStateException("Book is reserved.");
+			return DelErr.UserHasABook;
+
 		this.BookList.remove(b.getISBN());
+		return DelErr.Ok;
 	}
 
 	public boolean CheckBook(String isbn)
@@ -616,10 +594,6 @@
 				b = true;
 		}
 
-		if(!b)
-		{
-			System.err.println("No such user found, try again");
-		}
 		return b;
 	}
 
@@ -634,10 +608,11 @@
 		}
 
 		if(b == null)
-			throw new NoSuchElementException("No such Admin exists.");
+			throw new NoSuchElementException("No such book exists.");
 
 		return b;
 	}
+
 /*
 	public boolean FindBook(BookAttr k, Pattern p)
 	{
@@ -646,7 +621,6 @@
 		Matcher m;
 		switch(k)
 		{
-			// XXX should i use i.getFoolan.contains()?
 			case AgeGroup:
 				for(Book i : BookList.values())
 				{
@@ -813,7 +787,7 @@
 		this.BookQuery.clear();
 		for(Book i : BookList.values())
 		{
-			if(i.getStatus())
+			if(i.getStatus() == q)
 				this.BookQuery.add(i);
 		}
 		if(this.BookQuery.size() == 0)
@@ -823,7 +797,7 @@
 	}
 
 	/* user/admin's ID, ISBN */
-	public Err TakeBook(String un, String isbn)
+	public TakeErr TakeBook(String un, String isbn)
 	{
 		Book b = this.BookList.get(isbn);
 		if(this.CheckUser(un))
@@ -831,84 +805,182 @@
 		else if(this.CheckAdmin(un))
 			return TakeBook(MatchAdmin(un), b);
 		else
-			return Err.NoUser;
+			return TakeErr.NoUser;
 	}
 
 	/* they shouldn't be able to get a book, but still */
-	public Err TakeBook(Admin u, Book b)
+	public TakeErr TakeBook(Admin a, Book b)
 	{
 		/* check if book is taken */
 		if(b.getStatus())
-			return Err.BookReserved;
+			return TakeErr.BookReserved;
 
 		/* he has some book? blasmphy! */
-		if(!u.getReserved().isEmpty())
-			return Err.UserHasABook;
+		if(!a.getReserved().isEmpty())
+			return TakeErr.UserHasABook;
 
 		/* check if ages match admin has no age anyway
-		if(!b.AgeOk(u.getAge()))
-			return Err.Age; */
+		if(!b.AgeOk(a.getAge()))
+			return TakeErr.Age; */
 
-		u.setReserved(b.getISBN());
-		b.setOwner(u.getUsername());
+		a.setReserved(b.getISBN());
+
+		b.setOwner(a.getUsername());
+		b.setStatus(true);
+
 		this.ResCount++;
-		return Err.Ok;
+		SaveLog(logfile, "[Take] " + b.getISBN() + " by " + a.getUsername() + '\n');
+		return TakeErr.Ok;
 	}
 
-	public Err TakeBook(User u, Book b)
+	public TakeErr TakeBook(User u, Book b)
 	{
 		/* check if book is taken */
 		if(b.getStatus())
-			return Err.BookReserved;
+			return TakeErr.BookReserved;
 
 		/* he has some book? blasmphy! */
 		if(!u.getReserved().isEmpty())
-			return Err.UserHasABook;
+			return TakeErr.UserHasABook;
 
 		/* check if ages match */
 		if(!b.AgeOk(u.getAge()))
-			return Err.Age;
+			return TakeErr.Age;
 
 		u.setReserved(b.getISBN());
+
 		b.setOwner(u.getUsername());
+		b.setStatus(true);
+
 		this.ResCount++;
-		return Err.Ok;
+		SaveLog(logfile, "[Take] " + b.getISBN() + " by " + u.getUsername() + '\n');
+		return TakeErr.Ok;
 	}
 
-	public Err ReturnBook(Admin u)
+	public TakeErr ReturnBook(Admin a)
 	{
 		Book b;
-		if(u.getReserved().isEmpty())
-			return Err.NoBookReserved;
+		if(a.getReserved().isEmpty())
+			return TakeErr.NoBookReserved;
 
-		if(!CheckBook(u.getReserved()))
-			return Err.NoBook;
+		if(!CheckBook(a.getReserved()))
+			return TakeErr.NoBook;
 
-		b = MatchBook(u.getReserved());
+		b = MatchBook(a.getReserved());
 
-		u.setReserved(null);
+		a.clearReserved();
+
 		b.setOwner(null);
+		b.setStatus(false);
+
 		this.ResCount--;
-		return Err.Ok;
+		SaveLog(logfile, "[Return] " + b.getISBN() + " by " + a.getUsername() + '\n');
+		return TakeErr.Ok;
 	}
 
-	public Err ReturnBook(User u)
+	public TakeErr ReturnBook(User u)
 	{
 		Book b;
 		if(u.getReserved().isEmpty())
-			return Err.NoBookReserved;
+			return TakeErr.NoBookReserved;
 
 		if(!CheckBook(u.getReserved()))
-			return Err.NoBook;
+			return TakeErr.NoBook;
 
 		b = MatchBook(u.getReserved());
 
-		u.setReserved(null);
+		u.clearReserved();
+
 		b.setOwner(null);
+		b.setStatus(false);
+
 		this.ResCount--;
-		return Err.Ok;
+		SaveLog(logfile, "[Return] " + b.getISBN() + " by " + u.getUsername() + '\n');
+		return TakeErr.Ok;
 	}
 
+	/*
+	public IOErr CheckFile(String fp) throws IOException
+	{
+		File fd = new File(fp);
+
+		if(!fd.isFile())
+			return IOErr.NotAFile;
+
+		if(!fd.canWrite() || !fd.canRead())
+			return IOErr.PermissionDenied;
+
+		return IOErr.Ok;
+	}
+
+
+	public File OpenFile(String fp)
+	{
+		File fd = new File(fp);
+		fd.createNewFile();
+		return fd;
+	}
+	*/
+
+	public void SaveLog(String fp, String in)
+	{
+		try
+		{
+			FileWriter fw = new FileWriter(fp, true);
+			fw.append(in);
+			fw.flush();
+		}
+		catch(IOException e)
+		{
+			e.printStackTrace();
+		}
+	}
+/*
+	public String LoadLog(File fd, int n) throws FileNotFoundException
+	{
+		int i = n;
+		String temp;
+		Scanner s = new Scanner(fd);
+
+		while(s.hasNextLine() && i > 0)
+		{
+			temp += s.nextLine();
+			i--;
+		}
+		return temp;
+	}
+
+	public void SaveState(File fd) throws IOException
+	{
+		FileWriter fw = new FileWriter(fd, false);
+
+		for(Book i : BookList.values())
+		{
+			for(BookAttr a : i.toMap().keySet())
+					fw.append(i.toMap().get(a) + '\n');
+		}
+		fw.flush();
+	}
+
+	public void LoadState(File fd) throws FileNotFoundException
+	{
+		int agegroup;
+		String isbn, name, author, abs;
+		Scanner s = new Scanner(fd);
+
+		while(!s.hasNextLine())
+		{
+			isbn = s.nextLine();
+			name = s.nextLine();
+			author = s.nextLine();
+			agegroup = s.nextInt();
+			s.nextLine();
+			abs = s.nextLine();
+		}
+		NewBook(isbn, name, author, agegroup, abs);
+	}
+*/
+
 class conUI implements UI
 {
 	public void Program()
@@ -917,19 +989,9 @@
 		{
 			/* there is no admin! */
 			if(AdminList.size() == 0)
-			{
 				AddAdmin();
-				adm.Active = true;
-			}
 			else
 				this.LoginMenu();
-
-			/* only exits if user either logs out or smh */
-			this.Menu(adm);
-
-			/* user wants to quit */
-			if(adm.Active)
-				return;
 		}
 	}
 
@@ -948,7 +1010,7 @@
 			if(Login(a, pass))
 			{
 				System.out.println("Auth as " + a.getUsername() + " sucessful");
-				return;
+				this.Menu(adm);
 			}
 			else
 			{
@@ -962,6 +1024,7 @@
 			if(Login(u))
 			{
 				System.out.println("Login sucessful");
+				this.Menu(usr);
 			}
 		}
 		else
@@ -1009,17 +1072,17 @@
 			"13) take book\n" +
 			"14) return book\n\n" +
 
-			"15) logout\n" +
-			"99) quit!\n");
+			"15) logout\n");
 
 			System.out.print("Admin Menu> ");
 			while(!s.hasNextInt())
 			{
-				System.err.println("Please enter a valid input");
-				System.out.print("Admin Menu> ");
+				System.err.print("Please enter a valid input");
 				s.nextLine();
+				System.out.print("Admin Menu> ");
 			}
 			in = s.nextInt();
+			s.nextLine();
 
 			switch(in)
 			{
@@ -1029,13 +1092,12 @@
 					else
 						System.err.println("Incorrect Password.");
 					break;
-/*				case 2:
+				case 2:
 					if(this.AskPass(adm))
 						this.AddUser();
 					else
 						System.err.println("Incorrect Password.");
 					break;
-*/
 				case 3:
 					this.AddBook();
 					break;
@@ -1059,22 +1121,22 @@
 					break;
 
 				case 10:
-					// System.out.println("This action requires admin password");
-					// if(this.AskPass(adm)) /* current admin */
-					//	this.RemAdmin();
-					// else
-					//	System.err.println("Incorrect Password.");
+					System.out.println("This action requires admin password");
+					if(this.AskPass(adm)) /* current admin */
+						this.RemAdmin();
+					else
+						System.err.println("Incorrect Password.");
 					break;
 
 				case 11:
 					System.out.println("This action requires admin password");
-					// if(this.AskPass(adm)) /* current admin */
-					//	this.RemUser();
-					// else
-					//	System.err.println("Incorrect Password.");
+					if(this.AskPass(adm)) /* current admin */
+						this.RemUser();
+					else
+						System.err.println("Incorrect Password.");
 					break;
 				case 12:
-					// this.RemBook();
+					this.RemBook();
 					break;
 
 				case 13:
@@ -1081,7 +1143,7 @@
 					this.TakeMenu(adm);
 					break;
 				case 14:
-					// this.ReturnMenu();
+					this.ReturnMenu(adm);
 					break;
 
 				case 15:
@@ -1090,10 +1152,9 @@
 					return;
 				/* quit */
 				case 99:
-						System.out.print("Are you sure? (y/N)> ");
-						s.nextLine();
+						System.out.print("Quit> Are you sure? (y/N)> ");
 						if(s.nextLine().equals("y"))
-							return;
+							System.exit(0);
 						break;
 				default:
 					System.out.println("Invalid answer!, please try again.");
@@ -1102,6 +1163,58 @@
 		}
 	}
 
+	public void Menu(User u)
+	{
+		int in;
+		Scanner s = new Scanner(System.in);
+		System.out.println("Hello, " + u.getUsername() + "!");
+		while(true)
+		{
+			System.out.print(
+			"\n" +
+			" 1) search book\n" +
+			" 2) list book\n\n" +
+
+			" 3) take book\n" +
+			" 4) return book\n\n" +
+
+			" 5) logout\n");
+
+			System.out.print("User Menu> ");
+			while(!s.hasNextInt())
+			{
+				System.err.println("Please enter a valid input");
+				System.out.print("User Menu> ");
+				s.nextLine();
+			}
+			in = s.nextInt();
+			s.nextLine();
+
+			switch(in)
+			{
+				case 1:
+					this.SearchBook();
+					break;
+				case 2:
+					this.ListBook();
+					break;
+				case 3:
+					this.TakeMenu(usr);
+					break;
+				case 4:
+					this.ReturnMenu(usr);
+					break;
+				case 5:
+					System.out.println("Logging out...");
+					Logout(usr);
+					return;
+				default:
+					System.out.println("Invalid answer!, please try again.");
+					break;
+			}
+		}
+	}
+
 	public String GetUsername()
 	{
 		Scanner s = new Scanner(System.in);
@@ -1126,7 +1239,7 @@
 			do
 			{
 				pass = new String(c.readPassword("Password?> "));
-			}while(pass.contains(" "));
+			}while(pass.equals(""));
 		}
 		else
 		{
@@ -1136,7 +1249,7 @@
 			{
 				System.out.print("Password?> ");
 				pass = s.nextLine();
-			}while(pass.contains(" "));
+			}while(pass.equals(""));
 		}
 
 		/* encrypt it! */
@@ -1177,19 +1290,16 @@
 
 		if(FindAdmin(ua, pattern))
 		{
-			for(Admin i : AdminList.values())
-			{
-				for(AdminAttr j : AdminAttr.values())
-					System.out.print(j + " | ");
+				for(AdminAttr i : AdminAttr.values())
+					System.out.print(i + " | ");
 				System.out.println();
 
-				for(Admin j : AdminQuery)
+				for(Admin i : AdminQuery)
 				{
 					for(AdminAttr a : i.toMap().keySet())
-						System.out.print(j.toMap().get(a) + " | ");
+						System.out.print(i.toMap().get(a) + " | ");
 					System.out.println();
 				}
-			}
 		}
 		else
 			System.err.println("No match has found");
@@ -1224,7 +1334,7 @@
 			return;
 		}
 
-		System.out.print("Find User> Pattern?> ");
+		System.out.print("Find User> Pattern> ");
 		patt = s.nextLine();
 		pattern = Pattern.compile(patt, Pattern.CASE_INSENSITIVE);
 
@@ -1231,19 +1341,16 @@
 
 		if(FindUser(ua, pattern))
 		{
-			for(User i : UserList.values())
-			{
-				for(UserAttr j : UserAttr.values())
-					System.out.print(j + " | ");
+				for(UserAttr i : UserAttr.values())
+					System.out.print(i + " | ");
 				System.out.println();
 
-				for(User j : UserQuery)
+				for(User i : UserQuery)
 				{
 					for(UserAttr a : i.toMap().keySet())
-						System.out.print(j.toMap().get(a) + " | ");
+						System.out.print(i.toMap().get(a) + " | ");
 					System.out.println();
 				}
-			}
 		}
 		else
 			System.err.println("No match has found");
@@ -1260,7 +1367,9 @@
 		System.out.print("Find Book> What?> ");
 		attr = s.nextLine();
 
-		if(attr.equalsIgnoreCase("Status"))
+		if(attr.equalsIgnoreCase("ISBN"))
+			ba = BookAttr.ISBN;
+		else if(attr.equalsIgnoreCase("Status"))
 			ba = BookAttr.Status;
 		else if(attr.equalsIgnoreCase("Name"))
 			ba = BookAttr.Name;
@@ -1268,8 +1377,6 @@
 			ba = BookAttr.Author;
 		else if(attr.equalsIgnoreCase("Abstract"))
 			ba = BookAttr.Abstract;
-		else if(attr.equalsIgnoreCase("ISBN"))
-			ba = BookAttr.ISBN;
 		else if(attr.equalsIgnoreCase("AgeGroup"))
 			ba = BookAttr.AgeGroup;
 		else
@@ -1284,19 +1391,15 @@
 
 		if(FindBook(ba, pattern))
 		{
-			// XXX add isRegistered()
-			for(Book i : BookList.values())
+			for(BookAttr j : BookAttr.values())
+				System.out.print(j + " | ");
+			System.out.println();
+
+			for(Book j : BookQuery)
 			{
-				for(BookAttr j : BookAttr.values())
-					System.out.print(j + " | ");
+				for(BookAttr a : j.toMap().keySet())
+					System.out.print(j.toMap().get(a) + " | ");
 				System.out.println();
-
-				for(Book j : BookQuery)
-				{
-					for(BookAttr a : j.toMap().keySet())
-						System.out.print(j.toMap().get(a) + " | ");
-					System.out.println();
-				}
 			}
 		}
 		else
@@ -1313,21 +1416,49 @@
 		/* ensure there is no admin with the same username */
 		do
 		{
-			System.out.print("Add admin> ");
+			System.out.print("Add Admin> ");
 			user = this.GetUsername();
 
 			if(user.equals(""))
 				return;
-		}while(CheckAdmin(user));
+		}while(CheckUser(user) || CheckAdmin(user));
 
+		pass = this.GetPassword();
+
+		NewAdmin(user, pass);
+	}
+
+	public void AddUser()
+	{
+		int age;
+		String user;
+		Scanner s = new Scanner(System.in);
+
+		System.out.println("Setting up User:");
+
+		/* ensure there is no admin with the same username */
 		do
 		{
-			pass = this.GetPassword();
-		}while(pass.equals(""));
+			System.out.print("Add User> ");
+			user = this.GetUsername();
 
-		NewAdmin(user, pass);
+			if(user.equals(""))
+				return;
+		}while(CheckUser(user) || CheckAdmin(user));
+
+		System.out.print("Add User> Age> ");
+		while(!s.hasNextInt())
+		{
+				System.err.println("Please enter a valid input");
+				System.out.print("Add User> Age> ");
+				s.nextLine();
+		}
+		age = s.nextInt();
+
+		NewUser(user, age);
 	}
 
+
 	/* make checks better, reject empty input etc,
 		regex perhaps? */
 	public void AddBook()
@@ -1336,15 +1467,16 @@
 		String name, isbn, author, abs;
 		Scanner s = new Scanner(System.in);
 
+		System.out.print("Book> ISBN?> ");
+		isbn = s.nextLine();
+		if(isbn.equals(""))
+			return;
+
 		System.out.print("Book> Name?> ");
 		name = s.nextLine();
 		if(name.equals(""))
 			return;
 
-		System.out.print("Book> ISBN?> ");
-		isbn = s.nextLine();
-		if(isbn.equals(""))
-			return;
 
 		System.out.print("Book> Author?> ");
 		author = s.nextLine();
@@ -1357,23 +1489,100 @@
 		if(abs.equals(""))
 			return;
 
-		System.out.print("Book> Age Group?> ");
-		while(!s.hasNextInt())
+		do
 		{
-			System.out.println("Please enter a valid input");
 			System.out.print("Book> Age Group?> ");
-			s.nextLine();
-		}
-		agegroup = s.nextInt();
+			while(!s.hasNextInt())
+			{
+				System.err.println("Please enter a valid input");
+				System.out.print("Book> Age Group?> ");
+				s.nextLine();
+			}
+			agegroup = s.nextInt();
+		}while((agegroup > 99) || (agegroup < 2));
+		/* ensure it's valid ^ */
 
 		Book b = NewBook(isbn, name, author, agegroup, abs);
 	}
 
-	public void Rembook()
+	public void RemAdmin()
 	{
+		String un;
+		Scanner s = new Scanner (System.in);
 
+		System.out.print("Remove Admin> Username> ");
+		un = s.nextLine();
+
+		if(un.equals(""))
+			return;
+
+		if(!CheckAdmin(un))
+		{
+			System.err.println("No such Admin has found.");
+			return;
+		}
+
+		if(adm.getUsername().equals(un))
+		{
+			System.err.println("You can't remove yourself.");
+			return;
+		}
+
+		System.out.println("Remove Admin> Are you sure? (y/N)> ");
+		if(!s.nextLine().equals("y"))
+			return;
+
+		Result(DelAdmin(MatchAdmin(un)));
 	}
 
+	public void RemUser()
+	{
+		String un;
+		Scanner s = new Scanner (System.in);
+
+		System.out.print("Remove User> Username> ");
+		un = s.nextLine();
+
+		if(un.equals(""))
+			return;
+
+		if(!CheckUser(un))
+		{
+			System.err.println("No such user has found.");
+			return;
+		}
+
+		System.out.println("Remove User> Are you sure? (y/N)> ");
+		if(!s.nextLine().equals("y"))
+			return;
+
+		Result(DelUser(MatchUser(un)));
+	}
+
+	public void RemBook()
+	{
+		String isbn;
+		Scanner s = new Scanner (System.in);
+
+		System.out.print("Remove Book> isbn> ");
+		isbn = s.nextLine();
+
+		if(isbn.equals(""))
+			return;
+
+		if(!CheckBook(isbn))
+		{
+			System.err.println("No such book has found.");
+			return;
+		}
+
+		System.out.println("Remove Book> Are you sure? (y/N)> ");
+		if(!s.nextLine().equals("y"))
+			return;
+
+		Result(DelBook(isbn));
+	}
+
 	public void ListAdmin()
 	{
 		for(AdminAttr i : AdminAttr.values())
@@ -1416,14 +1625,14 @@
 		}
 	}
 
-	public void TakeMenu(Admin u)
+	public void TakeMenu(Admin a)
 	{
 		String isbn;
 		Scanner s = new Scanner(System.in);
 
-		if(!u.getReserved().isEmpty())
+		if(!a.getReserved().isEmpty())
 		{
-			System.err.println("Current Admin has already has a book (ISBN: " + u.getReserved() + ").");
+			System.err.println("Current Admin has already has a book (ISBN: " + a.getReserved() + ").");
 			return;
 		}
 
@@ -1442,7 +1651,7 @@
 
 		}while(isbn.contains(" ") || !CheckBook(isbn));
 
-		Result(TakeBook(u, MatchBook(isbn)));
+		Result(TakeBook(a, MatchBook(isbn)));
 	}
 
 	public void TakeMenu(User u)
@@ -1474,8 +1683,44 @@
 		Result(TakeBook(u, MatchBook(isbn)));
 	}
 
-	public void Result(Err res)
+	public void ReturnMenu(Admin a)
 	{
+		Scanner s = new Scanner(System.in);
+
+		if(a.getReserved().isEmpty())
+		{
+			System.err.println("You have no books reserved.");
+			return;
+		}
+
+		System.out.print("Return> Are you sure? (y/N)> ");
+
+		if(s.nextLine().equals("y"))
+			Result(ReturnBook(a));
+		else
+			System.out.println("Thought so.");
+	}
+
+	public void ReturnMenu(User u)
+	{
+		Scanner s = new Scanner(System.in);
+
+		if(u.getReserved().isEmpty())
+		{
+			System.err.println("You have no books reserved.");
+			return;
+		}
+
+		System.out.print("Return> Are you sure (y/N)?> ");
+
+		if(s.nextLine().equals("y"))
+			Result(ReturnBook(u));
+		else
+			System.out.println("Thought so.");
+	}
+
+	public void Result(TakeErr res)
+	{
 		switch(res)
 		{
 			case NoBook:
@@ -1491,18 +1736,58 @@
 				System.err.println("No such User has found");
 				break;
 			case UserHasABook:
-				System.err.println("User has already registered a book");
+				System.err.println("User has already reserved a book");
 				break;
-			case UserHasNoBook:
-				System.err.println("User has no book");
-				break;
 			case Age:
 				System.err.println("Age doesn't match!");
 				break;
 			case Ok:
+				System.out.println("Done!");
+				break;
 			default:
+				throw new IllegalStateException("Invalid TakeErr");
+		}
+	}
+
+	public void Result(DelErr res)
+	{
+		switch(res)
+		{
+			case UserHasABook:
+				System.err.println("User has reserve a book, return it");
+				break;
+			case BookReserved:
+				System.err.println("This book is reserved by someone else");
+				break;
+			case NoBook:
+				System.err.println("No such book has found");
+				break;
+			case NoUser:
+				System.err.println("No such user has found");
+				break;
+			case Ok:
 				System.out.println("Done!");
 				break;
+			default:
+				throw new IllegalStateException("Invalid DelErr");
+		}
+	}
+
+	public void Result(IOErr res)
+	{
+		switch(res)
+		{
+			case NotAFile:
+				System.err.println("Not a File");
+				break;
+			case PermissionDenied:
+				System.err.println("Permission denied");
+				break;
+			case Ok:
+				System.out.println("Done!");
+				break;
+			default:
+				throw new IllegalStateException("Invalid TakeErr");
 		}
 	}