//**********************************************************************
// parseAndAddAuthors: 
//**********************************************************************
Books.parseAndAddAuthors = function(authorsString) {
    if(!authorsString) return [];
    var authorArray = authorsString.split(' and ');
    var returnArray = [];
    var nextAuthorArraySlot = Books.bookData.authors.length;
    for(var i=0; i< authorArray.length; ++i) {
        var nameString = authorArray[i];
        var authorIndex = Books.findDuplicateAuthor(nameString);
        if(authorIndex < 0) {
            var names = nameString.split(' ');
            if(names.length > 3) console.log("author name in > 3 parts: "+authorArray[i]);
            authorIndex = nextAuthorArraySlot;
            ++nextAuthorArraySlot;
            Books.bookData.authors[authorIndex] = { names: names };
        }
        returnArray.push(authorIndex);
    }
    return returnArray;
};

//**********************************************************************
// findDuplicateAuthor: 
//**********************************************************************
Books.findDuplicateAuthor = function(nameString) {
    var numAuthors = Books.bookData.authors.length;
    for(var i=0; i < numAuthors; ++i) {
        var s = Books.bookData.authors[i].names.join(' ');
        if(s == nameString) {
            //console.log("Duplicate author: "+nameString);
            return i;
        }
    }
    return -1;
};

//**********************************************************************
// findDuplicateBook: 
//**********************************************************************
Books.findDuplicateBook = function(titleStringIn, authorsArray) {
    var numBooks = Books.bookData.books.length;
    var titleString = titleStringIn.toLowerCase();
    for(var i=0; i < numBooks; ++i) {
        var booksData = Books.bookData.books[i];
        // do we have a cached, lower case version?
        var title = booksData.titleLowerCase;
        if(!title) {
            // If not create one and remember it for later.
            title = booksData.title.toLowerCase();
            booksData.titleLowerCase = title;
        }
        if(title == titleString) {
            // See if the authors are the same.
            var len = authorsArray.length;
            var aa = booksData.author;
            if(aa.length != len) {
                console.log("Duplicate title: "+titleString+" but different number of authors");
                return -1;
            } else {
                for(var j=0; j < len; ++j) {
                    var name1 = Books.getAuthorName(authorsArray[j]);
                    var name2 = Books.getAuthorName(aa[j]);
                    if(name1 != name2) {
                        console.log("Duplicate title: "+titleString+" but author1="+name1
                            +" and author2="+name2);
                        return -1;
                    }
                }
            }
            return i;
        }
    }
    return -1;
};

//**********************************************************************
// addBook: 
//**********************************************************************
Books.addBook = function(title, authors, notes, readDate) {
    if(Books.findDuplicateBook(title, authors) >= 0) {
        //console.log("Ignoring dupliate book: "+title);
        return;
    }
    Books.bookData.books.push({
        title: title,
        author: authors,
        notes: notes,
        readDate: readDate
    });
};

//**********************************************************************
// importData: 
//**********************************************************************
Books.importData = function(bookData) {
    var booksArray = bookData.split('\n');
    var nBooks = booksArray.length;
    Books.statusMessage("Importing "+nBooks+" books");
    
    // Put it into the table
    var $tbody = $('#import-table tbody');
    console.log("Importing "+nBooks+" lines");
    console.log("BEFORE import: "+Books.bookData.books.length+" books and "
        +Books.bookData.authors.length+" authors");
    for(var i=0; i<nBooks; ++i) {
        var bookLine = booksArray[i];
        // Skip empty lines
        if(bookLine.length == 0) {
            log("Skipping empty line, line #"+i);
            continue;
        }
        
        var items = bookLine.split('===');
        if(items.length!=4) {
            console.log("ERROR: not 4 items in <"+booksArray[i]+"> i="+i);
            continue;
        }
        var $row = $('<tr></tr>');
        for(var j=0; j<items.length; ++j) {
            $('<td></td>').text(items[j]).appendTo($row);
        }
        $tbody.append($row);
        //var authors = Books.parseAndAddAuthors(items[1]);
        //Books.addBook(items[0], authors, items[2], items[3]);
    }
    console.log("AFTER import: "+Books.bookData.books.length+" books and "
        +Books.bookData.authors.length+" authors");
    //Books.setupTable('books');
    //Books.setupTable('authors');    
    Books.statusMessage(null);
};

//**********************************************************************
// getAuthorName:
//**********************************************************************
Books.getAuthorName = function(authorIndex) {
    return Books.bookData.authors[authorIndex].names.join(' ');
};

//**********************************************************************
// statusMessage: show or hide status window
//**********************************************************************
Books.statusMessage = function(msg) {
    var $box = $('#popupMessageBox');
    if(msg) $box.html(msg).show();
    else $box.hide();
}

//**********************************************************************
// setUpColumnSorting: in a table
//**********************************************************************
Books.setUpColumnSorting = function($table) {
    // Set up the sort-alpha rows
    $('th', $table).each(function(column) {
        if( $(this).is('.sort') ) {
            var findSortKey = function($cell) {
                return $cell.find('.sort-key').text().toUpperCase()
                    + ' ' + $cell.text().toUpperCase();
            };
            $(this).addClass('clickable').hover(function() {
                $(this).addClass('hover');
            }, function() {
                $(this).removeClass('hover');
            }).click(function() {
                // Remove other direction markers and add one for this sort.
                $('th', $table).each(function(col2) {
                    var mark = '';
                    if(col2==column) {
                        if($(this).is('.sort-asc')) {
                            sortDirection = -1;
                            mark = " (Z->A)";
                            $(this).removeClass("sort-asc");
                        } else {
                            sortDirection = 1;
                            mark = " (A->Z)";
                            $(this).addClass("sort-asc");
                        }
                    }
                    $('span.sort-direction', this).text(mark);
                });
                // Get the tbody rows
                var rows = $table.find('tbody > tr').get();
                // Generate a sort key for each row, do it once now for efficiency
                $.each(rows, function(index, row) {
                    row.sortKey = findSortKey($(row).children('td').eq(column));
                });
                // Sort the rows array
                rows.sort(Books.colCompare);
                // Reinsert the rows in sorted order
                var $tbody = $table.children('tbody');
                $.each(rows, function(index, row) {
                    $tbody.append(row);
                    row.sortKey = null;
                });
                sortDirection = -sortDirection;
                Books.colorAlternateRows($table);
            });
        }
    });
};

//**********************************************************************
// colCompare: compare two table columns
//**********************************************************************
Books.colCompare = function(a, b) {
    if(a.sortKey < b.sortKey) return -sortDirection;
    if(a.sortKey > b.sortKey) return sortDirection;
    return 0;
};

//**********************************************************************
// colorAlternateRows: color alternate table rows
//**********************************************************************
Books.colorAlternateRows = function($table) {
    $('tbody tr:odd', $table).removeClass('even').addClass('odd');
    $('tbody tr:even', $table).removeClass('odd').addClass('even');
}

//**********************************************************************
// parseMeetingRecords: import data -- not currently used
//
// As is this imports meetings (from the web site).
// Later it can be changed to import other book lists.
//**********************************************************************
Books.parseMeetingRecords = function(data, records) {
    // Add the new data
    var imeeting = data.meetings.length;
    var ibooks = data.books.length;
    var iauthors = data.authors.length;

    for(i=0; i<records.length; ++i) {
        var meeting = records[i].split('---');
        if(meeting.length<4) {
            console.error("meeting["+i+"] ="+records[i]);
            continue;
        }

        // Parse the author's name. Lots of cases.

        // First separate by commas
        var authorStrings = meeting[2].split(',');

        // For now, just use the first one.
        var authorString = authorStrings[0];

        var authorNames = authorString.split(' ');
        var anLength = authorNames.length;
        var first = (anLength>0) ? authorNames[0] : '';
        var middle = '', last = '';
        if(anLength == 2) {
            last = authorNames[1];
        } else {
            middle = authorNames[1];
            last = authorNames[2];
        }

        // Author's name already there?
        var authorIndex = -1;
        for(j=0; j<iauthors; ++j) {
            var a = data.authors[j];
            if(a.firstName==first && a.lastName==last && a.middleName==middle) {
                authorIndex = j;
                break;
            }
        }
        if(authorIndex < 0) {
            authorIndex = iauthors;
            ++iauthors;
            data.authors[authorIndex] = {
                "id": iauthors,
                "firstName": first,
                "lastName": last,
                "middleName": middle
            };
        }

        data.books[ibooks] = {
            "id": ibooks,
            "title": meeting[1],
            "author": [authorIndex]
        };
        bookIndex = ibooks;
        ++ibooks;

        data.meetings[imeeting] = {
            "id": imeeting,
            "date": meeting[0],
            "book": bookIndex,
            "host": meeting[3]
        };
        ++imeeting;
    }
};

//**********************************************************************
// saveBookData: save the current state of the book database to JSON.
//**********************************************************************
Books.saveBookData = function(filename) {
    var filedata = JSON.stringify(Books.bookData, null, 4);
    $.post('save.php', {'filename':filename, 'filedata':filedata}, function(){
        log('Book data saved in file "'+filename+'"');
    });
};

//**********************************************************************
// o2s: recursive print object function for debugging.
//**********************************************************************
var o2s = function(o) {
    var s;
    if(!o) {
        if(o===null)
            s = "null";
        else
            s = "undefined";
    } else if(typeof o == "object") {
        if(o instanceof Array) {
            var s = '[ ';
            for(var i=0; i<o.length; ++i) {
                s += o2s(o[i]);
            }
            s += "]";
        } else {
            var s = '{ ';
            for(var f in o) {
                s += f + ": " + o2s(o[f]) + " ";
            }
            s += "}";
        }
    } else {
        s = o.toString();
    }
    return s;
}

//**********************************************************************
// log: console log function for debugging
//**********************************************************************
var log = function(msg) {
    if(console && console.log) console.log(msg);
    else alert(msg);
};


