import webapp2
import random
import hashlib
from datetime import datetime

from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from cStringIO import StringIO

from google.appengine.ext import db

import cgi

# These classes (Model classes) define the kinds of entities that are used in the datastore

# This defines a book entity, it represents a specific book that exists in the library program
class Books(db.Model):
    Title = db.StringProperty()
    Author = db.StringProperty()
    Summary = db.StringProperty(multiline=True)
    Year = db.IntegerProperty()
    Publisher = db.StringProperty()
    Genre = db.StringProperty()
    FilePath = db.StringProperty()
    Country = db.StringProperty()
    Language = db.StringProperty()
    Reads = db.IntegerProperty()

# This defines the user who will be making use of the program
class BookUsers(db.Model):
    Email = db.EmailProperty()
    PasswordHash = db.StringProperty()

# This entity defines a book that the user has placed on his/her shelf
# It's parent entity will be the user that has bookmarked the book and the
# key name (ISBN number) refers to the book being shelf
class Shelf(db.Model):
    Favourite = db.BooleanProperty()
    TimeStamp = db.DateTimeProperty()

# This entity describes an admin user. There can only be one of these at any time.
# This is used to access the server side interface for controlling the datastore
class Admin(db.Model):
    Username = db.StringProperty()
    PasswordHash = db.StringProperty()
    LoggedIn = db.BooleanProperty()

# This describes how to use each handler - please ignore
class Main(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.write("""This page describes the handlers that have been coded so far

Search: This is the handler for searching through the database of books and can be accessed through
"comp3001teamd.appspot.com/search?title=xyz&author=xyz&year=x&ISBN=xyz&publisher=xyz&genre=xyz
&country=xyz&language=xyz&callback=xyz". Each field in the query string is optional except the callback.
An empty query string will return an empty list of books. It returns a JSONP object containing a list
of books. It is accessed using the get method

Login: For logging users in to the app. This returns a JSONP object. It has one field called "success"
containing 1 or 0 indicating whether the user was authenticated or not respectively. This is accessed
through "comp3001teamd.appspot.com/login?username=xyz&password=xyz&callback=xyz" using the post method

AddAdmin: Just for adding a user to test the app. Username: Am, email: am@am.am, password: 12345
Accessed from "comp3001teamd.appspot.com/addAdmin". In order to do this, you will need to go to
the url from your browser. Do not use it in your code as it will be removed in the final version.

GetList: For returning a list of books the user had bookmarked. Returns a JSONP object containing a
list of books. Can be accessed through "comp3001teamd.appspot.com/getUserList?username=xyz&callback=xyz"
Accessed using the get method

GetAll: Returns a list of all books in the library. It returns a JSONP object containing a list of books.
Can be accessed through "comp3001teamd.appspot.com/getAll?callback=xyz" using the get method

AddBooks: For populating the books entity. Used for testing purposes. (should only need to run once)
Can be accessed through "comp3001teamd.appspot.com/addBooks". This will also need to be run from the
browser. Do not use it as it will be removed in the final version.

Register: This is for registering a user. It can be accessed using the post method. It requires the username,
password and email address to exist in the query string. It returns a JSONP object as a response.
It contains a success field containing 0 if the username already exists and 1 if it doesn't and has been
added to the database The url for this is
"comp3001teamd.appspot.com/register?name=xyz&password=xyz&email=xyz@xyz.xyz&callback=xyz".

AddToShelf: This is for a user to be able to bookmark books and add them to their shelf. It is
accessed using the get method from the url "comp3001teamd.appspot.com/addToShelf?username=xyz&ISBN=xyz&callback=xyz"
This returns a JSONP object with the usual success field indicating 1 for success and 0 for failure

MakeFavourite: This is for changing the favourite value of a book that has been added to the shelf.
It can be accessed using the get method at "comp3001teamd.appspot.com/makeFav?username=xyz&ISBN=xyz&callback=xyz"
It returns a JSONP object containing a success field which will contain a "1" if it is successful or
"0" if the book does not exist on the shelf. If the favourite value is false, this will change it to
true and vice versa

GetSummary: This is for obtaining the summary for a particular book. It returns a JSONP object containing
the said summary. It can be accessed through "comp3001teamd,appspot.com/getSummary?ISBN=xyz&callback=xyz"

Get Book: This is for retrieving the contents of a book. It uses the get method and is accesses from the following
url: "comp3001teamd.appspot.com/getBook?ISBN=xyz&callback=xyz". It return a JSONP object that contains a single
field called "content". This contains a text string with all the content in it.

Note: In order to view/edit the contents of the datastore by hand, you will need to log into google
using our group account and go onto the dashboard for the app at "appengine.google.com"

Note: comp3001teamd.appspot.com on it's own should not return anything in future, so don't use it.

Good luck and good night.""")

# This handler is for searching through the books, there are several properties that can be searched upon.
# The search method works using a point system, any matching field results in point being allocated to the book
# The resutls are returned in descending order of points, exluding any books with 0 points
class Search(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        title = self.request.get('title')
        author = self.request.get('author')
        year = self.request.get('year')
        ISBN = self.request.get('ISBN')
        publisher = self.request.get('publisher')
        genre = self.request.get('genre')
        country = self.request.get('country')
        language = self.request.get('language')
	callback = self.request.get('callback')
        booksquery = db.GqlQuery("SELECT * FROM Books")
        number = booksquery.count()
        books = [0] * number
        for x in range(number):
            books[x] = booksquery[x]
        scores = [0] * number
        for x in range(number):
            if title != "":
                tt = title.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                tc = books[x].Title.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                if tt == tc:
                    scores[x] += 2
                elif tc.find(tt) != -1:
                    scores[x] += 1
            if country != "":
                ct = country.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                cc = books[x].Country.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                if ct == cc:
                    scores[x] += 2
                elif cc.find(ct) != -1:
                    scores[x] += 1
            if language != "":
                lt = language.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                lc =books[x].Language.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                if lt == lc:
                    scores[x] += 2
                elif tc.find(lt) != -1:
                    scores[x] += 1
            if author != "":
                at = author.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                ac = books[x].Author.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                if at == ac:
                    scores[x] += 2
                elif ac.find(at) != -1:
                    scores[x] += 1
            if year != "":
                year = int(year)
                if year == books[x].Year:
                    scores[x] += 2
            if ISBN != "":
                if ISBN == books[x].key().name():
                    scores[x] += 2
                elif books[x].key().name().find(ISBN) != -1:
                    scores[x] += 1
            if publisher != "":
                pt = publisher.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                pc=books[x].Publisher.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                if pt == pc:
                    scores[x] += 2
                elif pc.find(pt) != -1:
                    scores[x] += 1
            if genre != "":
                gt = genre.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                gc = books[x].Genre.lower().replace(" ","").replace(".","").replace(",","").replace("-","").replace(":","")
                if gc.find(gt) != -1:
                    scores[x] += 2
        for x in range(number):
            highest = x
            for y in range(x, number):
                if scores[y] > scores[highest]:
                    highest = y
            if highest != x:
                temp = scores[x]
                scores[x] = scores[highest]
                scores[highest] = temp
                temp = books[x]
                books[x] = books[highest]
                books[highest] = temp
        self.response.write(callback + '({ "books": [')
        c = 0;
        x = 0;
        while (x < number) and (scores[x] != 0):
            if c == 0:
                c = 1
            else:
                self.response.write(",")
            self.response.write('{"title": "' + books[x].Title + '",')
            self.response.write('"author": "' + books[x].Author + '",')
            self.response.write('"year": "' + str(books[x].Year) + '",')
            self.response.write('"ISBN": "' + books[x].key().name() + '",')
            self.response.write('"publisher": "' + books[x].Publisher + '",')
            self.response.write('"genres": "' + books[x].Genre + '",') 
            self.response.write('"country": "' + books[x].Country + '",')
            self.response.write('"language": "' + books[x].Language + '"}')
            x += 1
        self.response.write("]})")

# Authenticating a user, it compares the hash of the provided password with the stores hash
class Login(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        username = self.request.get('username')
        passhash = hashlib.sha1(self.request.get('password')).hexdigest()
	callback = self.request.get('callback')
	self.response.write(callback + '({ "success": "')
        user = BookUsers.get_by_key_name(username);
        if user is None:
            self.response.write("0")
        elif passhash != user.PasswordHash:
            self.response.write("0")
        else:
            self.response.write("1")
	self.response.write('"})')

# This is to allow a user to add a book to their shelf. It creates shelf identity if the books
# requested exists
class AddToShelf(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        username = self.request.get('username')
	callback = self.request.get('callback')
        user = BookUsers.get_by_key_name(username)
        ISBN = self.request.get('ISBN')
        book = Books.get_by_key_name(ISBN)
	self.response.write(callback + '({ "success" : "')
        if book is None or user is None:
            self.response.write("0")
        else:
            s = Shelf(parent = user, key_name = ISBN)
            s.Favourite = False
            s.TimeStamp = datetime.today()
            s.put()
            self.response.write("1")
	self.response.write('"})')

# This is to allow the user to mark/unmark a shelved book as a favourite.
# It uses an XOR operator to toggle the value
class MakeFavourite(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        username = self.request.get('username')
	callback = self.request.get('callback')
        user = BookUsers.get_by_key_name(username)
        ISBN = self.request.get('ISBN')
        books = db.GqlQuery("SELECT * FROM Shelf WHERE ANCESTOR IS :1", user)
	self.response.write(callback + '({ "success": "')
        for book in books:
            if book.key().name() == ISBN:
                book.Favourite = (book.Favourite ^ True)
                book.put()
                self.response.write("1")
		self.response.write('"})')
                return
	self.response.write("0")
	self.response.write('"})')

# This is to fetch the books on the users shelf
class GetList(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        username = self.request.get('username')
	callback = self.request.get('callback')
        user = BookUsers.get_by_key_name(username)
	if user is None:
	    self.response.write(callback + '({ "books": "error" })')
	else:
            books = db.GqlQuery("SELECT * FROM Shelf WHERE ANCESTOR IS :1", user)
            c = 0
            self.response.write(callback + '({ "books": [')
            for book in books:
                bookrec = Books.get_by_key_name(book.key().name())
                if c == 0:
                    c = 1
                else:
                    self.response.write(',')
                self.response.write('{"title": "' + bookrec.Title + '",')
                self.response.write('"author": "' + bookrec.Author + '",')
                self.response.write('"year": "' + str(bookrec.Year) + '",')
                self.response.write('"ISBN": "' + bookrec.key().name() + '",')
                self.response.write('"publisher": "' + bookrec.Publisher + '",')
                self.response.write('"genres": "' + bookrec.Genre + '",')
                self.response.write('"country": "' + bookrec.Country + '",')
	        self.response.write('"favourite": "' + str(book.Favourite) + '",')
		self.response.write('"reads": "' + str(bookrec.Reads) + '",')
                self.response.write('"language": "' + bookrec.Language + '"}')
            self.response.write("]})")

# This is to increment the number of times a book has been read. It finds a book by
# ISBN number and increases the value by 1 if the book exists.
class IncrementRead(webapp2.RequestHandler):
    def get(self):
	self.response.headers['Content-Type'] = 'application/javascript'
        ISBN = self.request.get('ISBN')
        callback = self.request.get('callback')
        book = Books.get_by_key_name(ISBN)
        if book is None:
            self.response.write(callback + '({ "success" : "0" })')
        else:
            book.Reads += 1
            book.put()
            self.response.write(callback + '({ "success" : "1" })')

# This is to retrieve the books in the library in the order of the number of times
# each book has been read in descending order
class GetReadOrder(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        callback = self.request.get('callback')
        self.response.write(callback + '({ "books" : [')
        books = db.GqlQuery("SELECT * FROM Books ORDER BY Reads DESC")
        c = 0;
        for book in books:
            if c == 0:
                c = 1
            else:
                self.response.write(",\n")
            self.response.write('{"title": "' + book.Title + '",')
            self.response.write('"author": "' + book.Author + '",')
            self.response.write('"year": "' + str(book.Year) + '",')
            self.response.write('"ISBN": "' + book.key().name() + '",')
            self.response.write('"publisher": "' + book.Publisher + '",')
            self.response.write('"genres": "' + book.Genre + '",')
            self.response.write('"country": "' + book.Country + '",')
            self.response.write('"reads": "' + str(book.Reads) + '",')
            self.response.write('"language": "' + book.Language + '"}')
        self.response.write(']})')

# This is for adding a user, it is for testing purposes only and should be removed in deployment
class AddAdmin(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        e = BookUsers(key_name = "Am")
        e.Email = "am@am.am"
        e.PasswordHash = hashlib.sha1("12345").hexdigest()
        e.put()
        self.response.write("Done")

# This handler is for registering a new user. It checks if the username is unique
# and if so, will create a BookUser entity with the username, the password hash and
# his/her email address
class Register(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        username = self.request.get('name')
	callback = self.request.get('callback')
        user = BookUsers.get_by_key_name(username)
        self.response.write(callback + '({ "success": "')
        if user is None:
            password = self.request.get('password');
            email = self.request.get('email');
            e = BookUsers(key_name = username)
            e.Email = email
            e.PasswordHash = hashlib.sha1(password).hexdigest()
            e.put()
            self.response.write("1")
        else:
            self.response.write("0")
        self.response.write('"})')

# This is a test handler for adding a specific set of books, should be removed in deployment
class AddBooks(webapp2.RequestHandler): # TODO test handler, delete in final
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        b = Books(key_name = "0747532699")
        b.Title = "Philosopher's Stone"
        b.Author = "J. K. Rowling"
        b.Year = 1997
        b.Publisher = "Bloomsbury"
        b.Genre = "Fantasy"
        b.Summary = "abcde"
        b.FilePath = "a/b"
        b.Country = "UK"
        b.Language = "English"
	b.Reads = 0
        b.put()

        b = Books(key_name = "0747538492")
        b.Title = "Harry Potter"
        b.Author = "J. K. Rowling"
        b.Year = 1998
        b.Publisher = "Bloomsbury"
        b.Genre = "Fantasy"
        b.Summary = "abcde"
        b.FilePath = "a/b"
        b.Country = "UK"
        b.Language = "English"
	b.Reads = 0
        b.put()

        b = Books(key_name = "0670899623")
        b.Title = "Artemis Fowl"
        b.Author = "Eoin Colfer"
        b.Year = 2001
        b.Publisher = "Viking Press"
        b.Genre = "Young-Adult Fantasy"
        b.Summary = "abc"
        b.FilePath = "a/c"
        b.Country = "Ireland"
        b.Language = "English"
	b.Reads = 0
        b.put()

        b = Books(key_name = "0786808551")
        b.Title = "Artemis Fowl: The Arctic Incident"
        b.Author = "Eoin Colfer"
        b.Year = 2002
        b.Publisher = "Hyperion Books"
        b.Genre = "Childrens Fantasy"
        b.Summary = "abc"
        b.FilePath = "a/c"
        b.Country = "Ireland"
        b.Language = "English"
	b.Reads = 0
        b.put() 

        b = Books(key_name = "000000000001")
        b.Title = "The Hobbit"
        b.Author = "J. R. R. Tolkien"
        b.Year = 1937
        b.Publisher = "George Allen & Unwin"
        b.Genre = "High-fantasy Adventure"
        b.Summary = "abcd"
        b.FilePath = "books/TheHobbit.pdf"
        b.Country = "UK"
        b.Language = "English"
	b.Reads = 0
        b.put()

        b = Books(key_name = "000000000002")
        b.Title = "A Christmas Carol"
        b.Author = "Charles Dickens"
        b.Year = 1843
        b.Publisher = "Chapman & Hall"
        b.Genre = "Ghost-Story Christmas"
        b.Summary = "abcdef"
        b.FilePath = "books/AChristmasCarol.pdf"
        b.Country = "UK"
        b.Language = "English"
	b.Reads = 0
        b.put()

        self.response.write("done")

# This is a handler for retrieving all the books that exist within the system.
class GetAll(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
	callback = self.request.get('callback')
        self.response.write(callback + '({ "books" : [')
        books = db.GqlQuery("SELECT * FROM Books")
        c = 0;
        for book in books:
            if c == 0:
                c = 1
            else:
                self.response.write(",")
            self.response.write('{"title": "' + book.Title + '",')
            self.response.write('"author": "' + book.Author + '",')
            self.response.write('"year": "' + str(book.Year) + '",')
            self.response.write('"ISBN": "' + book.key().name() + '",')
            self.response.write('"publisher": "' + book.Publisher + '",')
            self.response.write('"genres": "' + book.Genre + '",')
            self.response.write('"country": "' + book.Country + '",')
            self.response.write('"reads": "' + str(book.Reads) + '",')
            self.response.write('"language": "' + book.Language + '"}')
        self.response.write(']})')

# This handler is for retrieving the summary of a particular book
class GetSummary(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        ISBN = self.request.get('ISBN')
	callback = self.request.get('callback')
        book = Books.get_by_key_name(ISBN)
        self.response.write(callback + '({ "summary": "' + book.Summary + '"})')

# This handler is for retrieving all books that begin with a specific letter
# This was specifically so as to split the books by letter into multiple tabs
class GetByLetter(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        letter = self.request.get('letter').lower()
	callback = self.request.get('callback')
	books = db.GqlQuery("SELECT * FROM Books")
	self.response.write(callback + '({ "books" : [')
	c = 0
	for book in books:
	    title = book.Title.lower()
	    if title[0] == letter:
	        if c == 0:
		    c = 1
		else:
		    self.response.write(',')
	        self.response.write('{"title": "' + book.Title + '",')
                self.response.write('"author": "' + book.Author + '",')
                self.response.write('"year": "' + str(book.Year) + '",')
                self.response.write('"ISBN": "' + book.key().name() + '",')
                self.response.write('"publisher": "' + book.Publisher + '",')
                self.response.write('"genres": "' + book.Genre + '",')
                self.response.write('"country": "' + book.Country + '",')
                self.response.write('"language": "' + book.Language + '"}\n')
        self.response.write(']})')

# This handler is for retrieving the contents of a book. It uses a pdfreader to extract
# the content and send it off as a JSON object
class GetBook(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/javascript'
        ISBN = self.request.get('ISBN')
        callback = self.request.get('callback')
        book = Books.get_by_key_name(ISBN)
        path = book.FilePath
        rsrcmgr = PDFResourceManager()
        retstr = StringIO()
        codec = 'utf-8'
        laparams = LAParams()
        device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
        fp = file(path, 'rb')
        process_pdf(rsrcmgr, device, fp)
        fp.close()
        device.close()
        content = retstr.getvalue()
        retstr.close()
	content = content.split('\n')
        self.response.write(callback + '({ "content" : [')
	c = 0;
	for string in content:
	    if c == 0:
	        c = 1
	    else:
	        self.response.write(",\n")
	    self.response.write(' "' + string + '"')
	self.response.write(']})')

# This is a test handler for adding an admin user - should be removed during deployment
class AddAdminUser(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        e = Admin(key_name="admin");
        e.Username = "Am"
        e.PasswordHash = hashlib.sha1("12345").hexdigest()
        e.LoggedIn = False
        e.put()
        self.response.write("Done")

# This is the login page for the server side admin interface
# This can be accessed at comp3001teand.appspot.com/adminInterface
class AdminInterface(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        self.response.write("""
        <html>
            <head>
                <title> NetLib </title>
            </head>
            <body>
                <h1> NetLib - Admin Interface </h1>
                <form action="/authenticate" method="post">
                    <div>
                        Username: <input type="text" name="username"> </textarea>
                    </div>
                    <div>
                        Password: <input type="password" name="password"> </textarea>
                    </div>
                    <div>
                        <input type="submit" value="Login">
                    </div>
                </form>
            </body>
        </html>""")

# This handler authenticates a user. If successfull, it will redirect to the main control paner
# defined below, if not, it will display "incorrect username or password" and provide a button
# to go back to the login page
class Authenticate(webapp2.RequestHandler):
    def post(self):
        self.response.headers['Content-Type'] = 'text/html'
        username = self.request.get('username')
        phash = hashlib.sha1(self.request.get('password')).hexdigest()
        adminAcc = Admin.get_by_key_name('admin')
        if (username == adminAcc.Username and phash == adminAcc.PasswordHash):
            adminAcc.LoggedIn = True
            adminAcc.put()
            self.redirect('/controlPanel?hash=' + phash)
        else:
            self.response.write("""
            <html>
                <head>
                    <title> NetLib </title>
                </head>
                <body>
                    <div> Incorrect user name or password </div>
                    <form action="/adminInterface" method="get">
                        <div><input type="submit" value="Go back"></div>
                    </form>
                </body>
            </html>""")

# This is the main control panel and provides various forms for controlling the datastore
# such as add a new book or delete an existing one.
class ControlPanel(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        phash = self.request.get('hash')
        adminAcc = Admin.get_by_key_name('admin')
        if (phash == adminAcc.PasswordHash and adminAcc.LoggedIn):
            self.response.write("""
            <html>
                <head>
                    <title> NetLib </title>
                </head>
                <body>
                    <h1> NetLib - Admin Interface </h1>
                    <form action="/adminLogout" method="get">
                        <div> <input type="submit" value="logout"> </div>
                    </form>

                    <br><hr>

                    <div><h3> Add a new book </h3></div>
                    <form action="/addNewBook" method="get">
    		        <div><input type="hidden" name="hash" value='""" + phash + """'></div>
		        <div><input type="text" name="title"> Title </div>
			<div><input type="text" name="author"> Author </div>
			<div><input type="text" name="year"> Year </div>
                        <div><input type="text" name="publisher"> Publisher </div>
                        <div><input type="text" name="genre"> Genre </div>
                        <div><input type="text" name="country"> Country </div>
                        <div><input type="text" name="language"> Language </div>
                        <div><input type="text" name="filepath"> Filepath </div>
                        <div><textarea name="summary" rows="5" cols="17"> </textarea> Summary </div>
			<div><input type="text" name="ISBN"> ISBN </div>
                        <div><input type="submit" value="Add Book"></div>
		    </form>

		    <br><hr>

		    <div><h3> Delete a book </h3></div>
		    <form action="/deleteBook" method="get">
		        <div><input type="hidden" name="hash" value='""" + phash + """'></div>
		    	<div><input type="text" name="ISBN"> ISBN of book to be deleted </div>
			<div><input type="submit" value="Delete"></div>
		    </form>

		    <br><hr>

		    <div><h3> Delete a user </h3></div>
		    <form action="/deleteUser" method="get">
		        <div><input type="hidden" name="hash" value='""" + phash + """'></div>
		        <div><input type="text" name="username"> Username of user to be deleted </div>
			<div><input type="submit" value="Delete"></div>
		    </form>

		    <br><hr>

		    <div><h3> Change admin username/password </h3></div>
		    <form action="/changeAdminDetails" method="get">
		        <div><input type="hidden" name="hash" value='""" + phash + """'></div>
		        <div><input type="text" name="username"> Username </div>
			<div><input type="password" name="password"> Password </div>
			<div><input type="submit" value="Change"></div>
		    </form>
                </body>
            </html>
            """)
        else:
            self.response.write("You don't have permission to view this ")

# This is for changing the admin user details.
class ChangeAdminDetails(webapp2.RequestHandler):
	def error(self):
		self.response.headers['Content-Type'] = 'text/html'
		self.response.write("""
		<html>
			<head>
				<title> NetLib </title>
			</head>
			<body>
				Error in submitted information
				<form action="/controlPanel" method="get">
				<div><input type="hidden" name="hash" value='""" + self.request.get('hash') + """'></div>
				<div><input type="submit" value="Back"></div>
				</form>
			</body>
		</html>""")

	def get(self):
		self.response.headers['Content-Type'] = 'text/html'
		phash = self.request.get('hash')
		adminAcc = Admin.get_by_key_name('admin')
	        if (phash == adminAcc.PasswordHash and adminAcc.LoggedIn):
			username = self.request.get('username')
			password = self.request.get('password')
			if username == "" and password == "":
				self.error()
			else:
				if username != "":
					adminAcc.Username = username
				if password != "":
					adminAcc.PasswordHash = hashlib.sha1(password).hexdigest()
				adminAcc.put()
				self.response.write("""
				<html>
					<head>
						<title> NetLib </title>
					</head>
					<body>
						Admin details updated
						<form action="/controlPanel" method="get">
						<div><input type="hidden" name="hash" value='""" + adminAcc.PasswordHash + """'></div>
						<div><input type="submit" value="Back"></div>
						</form>
					</body>
				</html>""")
		else:
            		self.response.write("You don't have permission to view this ")

# This is for deleting an existing user. If the user exists it will be removed, if not
# The user will be informed before being linked back to the control panel
class DeleteUser(webapp2.RequestHandler):
	def error(self):
		self.response.headers['Content-Type'] = 'text/html'
		self.response.write("""
		<html>
			<head>
				<title> NetLib </title>
			</head>
			<body>
				Error in submitted information
				<form action="/controlPanel" method="get">
				<div><input type="hidden" name="hash" value='""" + self.request.get('hash') + """'></div>
				<div><input type="submit" value="Back"></div>
				</form>
			</body>
		</html>""")

	def get(self):
		self.response.headers['Content-Type'] = 'text/html'
		phash = self.request.get('hash')
		adminAcc = Admin.get_by_key_name('admin')
	        if (phash == adminAcc.PasswordHash and adminAcc.LoggedIn):
			username = self.request.get('username')
			user = BookUsers.get_by_key_name(username)
			if user is None:
				self.error()
			else:
				user.delete()
				self.response.write("""
				<html>
					<head>
						<title> NetLib </title>
					</head>
					<body>
						The User has been deleted
						<form action="/controlPanel" method="get">
						<div><input type="hidden" name="hash" value='""" + phash + """'></div>
						<div><input type="submit" value="Back"></div>
						</form>
					</body>
				</html>""")
		else:
            		self.response.write("You don't have permission to view this ")

# This is for deleting an existing book, works the same sort of wat as the handler above
class DeleteBook(webapp2.RequestHandler):
	def error(self):
		self.response.headers['Content-Type'] = 'text/html'
		self.response.write("""
		<html>
			<head>
				<title> NetLib </title>
			</head>
			<body>
				Error in submitted information
				<form action="/controlPanel" method="get">
				<div><input type="hidden" name="hash" value='""" + self.request.get('hash') + """'></div>
				<div><input type="submit" value="Back"></div>
				</form>
			</body>
		</html>""")

	def get(self):
		self.response.headers['Content-Type'] = 'text/html'
		phash = self.request.get('hash')
		adminAcc = Admin.get_by_key_name('admin')
	        if (phash == adminAcc.PasswordHash and adminAcc.LoggedIn):
			ISBN = self.request.get('ISBN')
			book = Books.get_by_key_name(ISBN)
			if book is None:
				self.error()
			else:
				book.delete()
				self.response.write("""
				<html>
					<head>
						<title> NetLib </title>
					</head>
					<body>
						The Book has been deleted
						<form action="/controlPanel" method="get">
						<div><input type="hidden" name="hash" value='""" + phash + """'></div>
						<div><input type="submit" value="Back"></div>
						</form>
					</body>
				</html>""")
		else:
            		self.response.write("You don't have permission to view this ")

# This is for adding a new book to the datastore. It checks if all the fiels have been supplied before creating and 
# adding a new Book entity
class AddNewBook(webapp2.RequestHandler):
	def error(self):
		self.response.headers['Content-Type'] = 'text/html'
		self.response.write("""
		<html>
			<head>
				<title> NetLib </title>
			</head>
			<body>
				Error in submitted information
				<form action="/controlPanel" method="get">
				<div><input type="hidden" name="hash" value='""" + self.request.get('hash') + """'></div>
				<div><input type="submit" value="Back"></div>
				</form>
			</body>
		</html>""")

	def get(self):
		self.response.headers['Content-Type'] = 'text/html'
		phash = self.request.get('hash')
		adminAcc = Admin.get_by_key_name('admin')
        	if (phash == adminAcc.PasswordHash and adminAcc.LoggedIn):
			title = self.request.get('title')
			bad = False
			if title == "":
				self.response.write("title")
				bad = True
			author = self.request.get('author')
			if author == "":
				self.response.write("author")
				bad = True
			year = self.request.get('year')
			try:
				int(year)
			except Error:
				self.response.write("year")
				bad = True
			publisher = self.request.get('publisher')
			if publisher == "":
				self.response.write("pub")
				bad = True
			genre = self.request.get('genre')
			if genre == "":
				self.response.write("gen")
				bad = True
			country = self.request.get('country')
			if country == "":
				self.response.write("country")
				bad = True
			language = self.request.get('language')
			if language == "":
				self.response.write("lang")
				bad = True
			filepath = self.request.get('filepath')
			if filepath == "":
				self.response.write("fp")
				bad = True
			ISBN = self.request.get('ISBN')
			if ISBN == "":
				self.response.write("isbn")
				bad = True
			summary = self.request.get('summary')
			if summary == "":
				self.response.write("sum")
				bad = True
			if bad:
				self.error()
			else:
				e = Books(key_name=ISBN)
				e.Title = title
				e.Author = author
				e.Year = int(year)
				e.Publisher = publisher
				e.Genre = genre
				e.Country = country
				e.Language = language
				e.FilePath = filepath
				e.Summary = summary
				e.Reads = 0
				e.put()
				self.response.write("""
				<html>
					<head>
						<title> NetLib </title>
					</head>
					<body>
						The Book has been added
						<form action="/controlPanel" method="get">
						<div><input type="hidden" name="hash" value='""" + phash + """'></div>
						<div><input type="submit" value="Back"></div>
						</form>
					</body>
				</html>""")
	        else:
        	    self.response.write("You don't have permission to view this ")

# This is for logging out, it changes the loggedin state of the user and then redirects to the login page
class AdminLogout(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        adminAcc = Admin.get_by_key_name('admin')
        adminAcc.LoggedIn = False
        adminAcc.put()
        self.redirect('/adminInterface')

app = webapp2.WSGIApplication([('/', Main),
                               ('/search', Search),
                               ('/login', Login),
                               ('/addToShelf', AddToShelf),
                               ('/makeFav', MakeFavourite),
                               ('/getUserList', GetList),
                               ('/register', Register),
                               ('/addAdmin', AddAdmin),
                               ('/getAll', GetAll),
                               ('/addBooks', AddBooks),
                               ('/getSummary', GetSummary),
			       ('/getBook', GetBook),
                               ('/getByLetter', GetByLetter),
                               ('/addAdminUser', AddAdminUser),
                               ('/adminInterface', AdminInterface),
                               ('/authenticate', Authenticate),
                               ('/controlPanel', ControlPanel),
                               ('/adminLogout', AdminLogout),
                               ('/addNewBook', AddNewBook),
			       ('/deleteBook', DeleteBook),
			       ('/deleteUser', DeleteUser),
                               ('/incrementRead', IncrementRead),
                               ('/getReadOrder', GetReadOrder),
			       ('/changeAdminDetails', ChangeAdminDetails)],
                                debug = True)

