AddressBook.prototype._init = function () {
    this.timeouts = {
        "contactSearch":null
    };
    this._initContactModalData();
    this.oNewAddress = {
        "id":-1,
        "name":"",
        "street":"",
        "city":"",
        "zip":"",
        "type__id":1
    };
    this.srchConfig = {
        displayOn:"contact",
        orderby:"name_first"
    }

    //this.importContactIDs = [];
    this.vars = {importContactIDs:[], mergeContactIDList:[], lastSearch:{pageNum:0}};
    this.oNewContact = {
        "id":-1,
        "name":"contact name"
    } //don't use this anywhere
    this.stateByID = {};
    this.rmi_getStates();
    this.rmi_getAddressTypes();
    this.rmi_getBlankAddress();
}


AddressBook.prototype._initContactModalData = function() {
    this.contactModalData = {
        "addresses":{},
        "addressesRemove":[],
        "addInc":0
    };
}


AddressBook.prototype.contactListItemDetail = function (inID) {
    if($("#contact__" + inID + "__details:visible'").length > 0) {
        $("#contact__" + inID + "__details").fadeOut();
        return;
    }
    ui.statusMessage("retrieving contact");
    this.rmi_getContactByID(inID, function(e){
        ab.contactListItemDetail_cb(e)
    });
}

AddressBook.prototype.contactListItemDetail_cb = function (e) {
    if(!ui.ro(e)) return;
    $("#contact__" + e.data.id + "__details").html(ui.aTileList(e.data.addressList, "ab", e.name));
    $("#contact__" + e.data.id + "__details").fadeIn();
}

AddressBook.prototype.contactSearchDelayed = function () {
    clearTimeout(this.timeouts.contactSearch);
    this.timeouts.contactSearch = setTimeout("ab.searchContacts({pageNum:0});", 500);
}


AddressBook.prototype.deleteContact = function(inID) {
    if(confirm('Are you sure you want to delete this contact?\n It will be removed from any unsent letters.'))
        this.rmi_deleteContact(inID);
}

AddressBook.prototype.deleteContact_cb = function(e) {
    if(!ui.ro(e, true)) {
        alert(e.message);
        return false;
    }
    tk.setting("contactCount", tk.setting("contactCount") - 1);
    lman.removeContactFromOpenLetters(e.data);
    ab.searchContacts();
    $.modal.close();
}

/*
 * Gets this singletons specified variable
 */
AddressBook.prototype.get = function(inAttrName, inAttrAttrName){
    switch(inAttrName) {
        case "addressTypeList" :
            if(typeof(this.addressTypeList) != undefined)
                return this.addressTypeList;
            break;
        case "stateByID" :
            if(typeof(this.stateByID) != undefined && this.stateByID.hasOwnProperty(inAttrAttrName))
                return this.stateByID[inAttrAttrName];
            break;
    }
    return false;
}

AddressBook.prototype.getAddressTypes_cb = function(e) {
    if(!ui.ro(e)) return false;
    this.addressTypeList = e.data;
    this.addressTypeByID = {}; //e.data;
    for(i in e.data) {
        if(e.data.hasOwnProperty(i)) {
            this.addressTypeByID[e.data[i].id] = e.data[i];
        }
    }
   // this.oNewAddress["typeList"] = e.data;
}

AddressBook.prototype.getContact = function(inID) {
    ui.statusMessage("retrieving contact");
    this.rmi_getContactByID(inID);
}


AddressBook.prototype.getContactByAddress = function(inID) {
    ui.statusMessage("retrieving contact");
    this.rmi_getContactByAddressID(inID, function(e) {
        ab.getContactByID_cb(e);
    });
}


AddressBook.prototype.getContactByID_cb = function(e) {
    if(!ui.ro(e)) return false;
    ui.statusMessage(false);
    this.newContactEditor(e.data);
}

AddressBook.prototype.getEmpty = function(inObjType) {
    if(typeof inObjType != "string") return false;
    switch(inObjType) {
        case "address" :
        default :
            return($.clone(this.oNewAddress));
    }
}


AddressBook.prototype.getStates_cb = function(e) {
    if(!ui.ro(e)) return false;
    this.stateList = e.data;
    this.stateByID = {}; //e.data;
    for(i in e.data) {
        if(e.data.hasOwnProperty(i)) {
            this.stateByID[e.data[i].id] = e.data[i];
        }
    }
}


AddressBook.prototype.gsyncPermissionGranted = function(inGranted) {
    if(inGranted) {
        $("#modalContent").snippet("modal__wait", {
            messageAbove:"Access Granted",
            messageBelow:"Syncing from your google contacts."
        });
        var win = ui.window("googleVerify");
        if(win) win.close();
        this.gsyncContacts();
    }

}
AddressBook.prototype.importRunReady = function(inID, inMessage, inType) {
    var type = (typeof inType != "undefined")? inType : "retry";
    switch(type) {
        case "forceretry" :
            ui.modalSetContent({
                modalTitle:"Error Importing Contacts",
                content: inMessage + " " 
                + ui.btnGrySml({text:"retry", onclick:"ab.modalImport()"})
            });
            break;
        case "retry" :
            if(!confirm(inMessage)) {
                ab.modalImport();
                break;
            }
        default :
            this.getImportRunContacts(inID);
    }
}

AddressBook.prototype.getImportRunContacts = function(inID) {
    this.rmi_getImportRunContacts(inID);
}

/*used when importing from file*/
AddressBook.prototype.getImportRunContacts_cb = function(e) {
    if(!e.ok) {
        alert(e.message);
    }
    if(e.ok) {
        ui.statusMessage("Review and confirm your contacts", 'green');
        ui.modalSetContent({modalTitle:"Review & Import Contacts", content:$.snippet("modal__ab__import_wrapper", {list:e.data})});
    }
}

AddressBook.prototype.gsyncContacts = function() {
    $.log("syncGoogleContacts");
    ui.modal("modal__wait", {messageBelow:"Syncing from your google contacts."}, "contact");
    this.rmi_gsyncRetrieveContacts();
}

/*used when importing from google sync... hence the fancy checking*/
AddressBook.prototype.gsyncRetrieveContacts_cb = function(e) {
    ui.ro(e);
    if(!e.ok) {
        if(e.data == "needAuthToken") {
            if(!ui.window("googleVerify")) {
                $("#modalContent").snippet("modal__wait", {
                    messageAbove:"You must allow popups to continue.",
                    messageBelow:"<span style='cursor:pointer; text-decoration:underline; color:yellow;' onclick=\"ui.window('googleVerify')\">Click here</span> when you have allowed popups."
                });
            } else {
                $("#modalContent").snippet("modal__wait", {
                    messageBelow:"Please verify yourself in the popup window."
                });
            }
        }
        return;
    }
    if(e.ok) {
        ui.statusMessage("Review and confirm your contacts", 'green');
        ui.modalSetContent({modalTitle:"Review & Import Contacts", content:$.snippet("modal__ab__import_wrapper", {list:e.data})});
    }
}



AddressBook.prototype.importSelectedContacts = function() {
    this.vars.importContactIDs = [];
    $('#abModalIAReview input:checkbox:checked').each(function() {
        ab.vars.importContactIDs.push(this.value);
    });
    this.rmi_importContacts(this.vars.importContactIDs);
    ui.statusMessage("Importing");
}

AddressBook.prototype.importContacts_cb = function(e) {
    if(e.data == "importsuccessful") {
            ab.searchContacts();
            $.modal.close();
            setTimeout("ui.statusMessage(' " + e.message + "', 'green')", 1000);
        }
}

AddressBook.prototype.mergeContacts = function(inMode) {
    this.vars.mergeContactIDList = [];
    if(inMode == "abselected"){
        $("#contactSearchResults input:checkbox:checked").each(function() {
            ab.vars.mergeContactIDList.push(this.value);
        });
    }
    this.rmi_mergeContacts(ab.vars.mergeContactIDList, {mode:"automated_merge"});
}

AddressBook.prototype.mergeContacts_cb = function(e) {
   if(!ui.ro(e)) return;
   ab.searchContacts();
   $.modal.close();
}

AddressBook.prototype.modalMergeSelected = function () {
    if($("#contactSearchResults input:checkbox:checked").length < 2) {
        ui.statusMessage("You must choose at least 2 contacts", "error");
        return;
    }
    ui.modal("modal__wait", {modalTitle:"Merge Contacts", messageBelow:"Gathering contact information."}, "contact");
    this.vars.mergeContactIDList = [];
    $("#contactSearchResults input:checkbox:checked").each(function() {
        ab.vars.mergeContactIDList.push(this.value);
    });
    //$.log(this.vars.mergeContactIDList, true);
    this.rmi_mergeContacts(this.vars.mergeContactIDList, function(e) {ab.modalMergeSelected_cb(e);});
}

AddressBook.prototype.modalMergeSelected_cb = function (e) {
    if(!ui.ro(e)) return;
    //$.log(e, true);
    e.data.mode = "merge_contacts";
    ui.modalSetContent({modalTitle:"Merge Contacts - Does this look right?", content:$.snippet("ab__modal__contact_review", e.data)});
    $.each(e.data.addressList, function() {
       $("#abReviewContactAddressPanel").append(ui.aTile(this));
    });
}


AddressBook.prototype.modalImport = function () {
    if(!tk.loggedIn()) {
        tk.loginDriveBy(function(){ab.modalImport();});
        return;
    }
    ui.modal("ab__modal__import_file", {modalTitle:"Import file to Address Book"}, "contact");
    /*testing and storage of options was done to eliminate timing problems between
    server retrieval and re-creating the modal */
    var htmlConfig = {        
        placement:"append",
        timeout:500,
        initial:500
    }
    if(typeof(this.vars.importFileSource) == "undefined") {
        tk.rmi_getOptions("ab_import_file_source", function(e) {
            ab.vars.importFileSource  = e.data;
            ui.htmlTimeout("#ab_import_file_source", $.snippet("option_item_list", {list:e.data}), "append");
            //$("#ab_import_file_source").snippetAppend("option_item_list", {list:e.data});
        });
    } else {
       ui.htmlTimeout("#ab_import_file_source", $.snippet("option_item_list", {list:ab.vars.importFileSource}), "append");
       //$("#ab_import_file_source").snippetAppend("option_item_list", {list:this.vars.importFileSource});
    }
}


AddressBook.prototype.newContactEditor = function (inContact, inConfig) {
    this._initContactModalData();
    if(typeof(inContact) == "undefined")
        inContact = {
            id:"-1",
            modalTitle:"New Contact"
        };
    else
        inContact.modalTitle = "Edit Contact";
    inContact.editorMode = "ab";
    ui.modal("ab__contact_edit", inContact, "contact");
    if(!inContact.hasOwnProperty("id") || inContact.id == "-1") {
        if(!inContact.hasOwnProperty("name"))
            inContact.name = $('#contactSearchBox').val();
        this.newEditAddressTile()
    } else {
        for(i in inContact.addressList) if(inContact.addressList.hasOwnProperty(i)) {
            this.newEditAddressTile(inContact.addressList[i]);
        }
    }
}

AddressBook.prototype.newEditAddressTile = function(inAddress) {
    this.contactModalData.addInc++;
    if(typeof inAddress == "undefined") {
        inAddress = this.getEmpty("address");
        inAddress.id = this.contactModalData.addInc * -1;
        inAddress.name = $("#contact__name").val();
    }

    inAddress.num = this.contactModalData.addInc;
    this.contactModalData.addresses[this.contactModalData.addInc] = inAddress;
    var str = ui.aTile(inAddress, "abEdit" );
    $("#editContactAddressPanel").prepend(  str );
    $("#address" + inAddress.num + "__type__id").val(inAddress.type__id);
}


AddressBook.prototype.removeAddress = function(inNum) {
    var rem = false;
    for(var i in this.contactModalData.addresses) if(this.contactModalData.addresses.hasOwnProperty(i)) {
        if(this.contactModalData.addresses[i].id == inNum) {
            rem = i;
            break;
        }
    }
    if(!rem) {
        ui.statusMessage("unable to flag address for removal", "error");
        return;
    }
    var address = this.contactModalData.addresses[rem];
    this.contactModalData.addressesRemove.push(address.id);
    delete(this.contactModalData.addresses[rem]);
    $("#modalContent #aTile_" + address.id).remove();
}

//removeAddressNOW and removeAddressNOW_cb are not currently used in the application, but they work!
//and have provided a really good example of delete address code for other places in the address book
//leaving them here
AddressBook.prototype.removeAddressNOW = function(inCID, inID, inCleanup) {
    if(confirm("If you delete this address it will be removed from any un-sent letters. Do you wish to proceed?"));
    this.rmi_removeAddressNOW(inCID, inID, true);
}

AddressBook.prototype.removeAddressNOW_cb = function(e) {
    if(!ui.ro(e)) return false;
    this.searchContacts();
}


AddressBook.prototype.saveContact = function(inCallback) {
    if(!tk.loggedIn()) {
        $.log("THINKS WE'RE NOT LOGGED IN");
        tk.loginDriveBy("saveContact");
        return false;
    }
	
    var contact = $.objFromDom(new Array("id","name"), "contact__");
    contact.addressList = [];
    contact.addressListRemove = this.contactModalData.addressesRemove;
    
    var address = {};
    var modalData = this.contactModalData;
    
    for(var i in modalData.addresses) if(modalData.addresses.hasOwnProperty(i)) {
        //address = $.objFromDom(["id","street", "state__id", "city", "zip", "type__id", "postalAddress"], "address" + i + "__");
        address = $.objFromDom(["id", "type__id", "name", "postalAddress"], "address" + i + "__");
        contact.addressList.push(address);
    }
    if(typeof(inCallback) == "function") {
        this.rmi_saveContact(contact, inCallback);
        return;
    }
    this.rmi_saveContact(contact);
}


AddressBook.prototype.saveContact_cb = function(e) {
    if(!e.ok) {
        alert("unable to save this contact. try again.");
        return false;
    }
    tk.setting("contactCount", e.data.contactCount);
    $("#contactSearchBox").focus().select();
    ab.searchContacts();
    $.modal.close();
    lman.removeAddressFromOpenLetters(e.data.contact.addressListRemove);
    setTimeout("ui.statusMessage('contact saved', 'green')", 500);
	
}


AddressBook.prototype.searchContacts = function (inSearchConfig) {
    clearTimeout(this.timeouts.contactSearch);
    if(!tk.loggedIn()) return;
    //$("#contactSearchResults").css("opacity", "0");
    $("#contactSearchResults").css("display", "none");
    if(!tk.loggedIn()) {
        $("#contactSearchResults").snippet("ab__contacts_none");
        return false;
    }
    ui.statusMessage("looking for contacts");
    var searchConfig = {
        "searchName":$('#contactSearchBox').val(),
        "pageNum":this.vars.lastSearch.pageNum,
        "pageLen":tk.setting("ab_searchcontacts_pageLen"),
        "displayOn":tk.setting("ab_searchcontacts_displayMode"),
        "orderby":tk.setting("ab_searchcontacts_orderby")
    };
    if(typeof(inSearchConfig) != "undefined") {
        $.extend(searchConfig, inSearchConfig);
    }
    this.rmi_searchContacts(searchConfig);
}


AddressBook.prototype.setContactsPageLen = function(inPageLen) {
    tk.setting("ab_searchcontacts_pageLen", inPageLen);
    this.searchContacts();
}

AddressBook.prototype.searchContacts_cb = function (e) {
    if(!ui.ro(e)) return false;
    
    ui.statusMessage(false);

    if(e.data.list.length == 0) {
        if (e.data.searchName.length == 0) {
            $("#contactSearchResults").snippet("ab__contacts_none");
        } else {
            $("#contactSearchResults").html("There are no contacts with <i>'" + e.data.searchName + "' in the name.");
        }
        return false;
    }
	
    e.data.func = "ab.searchContacts";
    e.data.pager = ui.pagerGrySml(e.data, true);
    e.data.functionCall = "ab.getContact";
    
    e.data.itemType = "contact"; //legacy line (dunno if we need it so is still here)
    e.data.pagelen = ui.btnGroup("contactList", ['10', '20', '40'], {
        func:"ab.setContactsPageLen",
        defaultBtn:tk.setting("ab_searchcontacts_pageLen")
    });
    //orderby ui configuration
    e.data.orderby = this.searchConfig("orderby");
    /* e.data.orderbyName = ui.btnGroup("orderbyName", [{
        text:'first name',
        funcVal:"name_first"
    }, {
        text:'last name',
        funcVal:"name_last"
    }], {
        func:"ab.setOrderBy",
        defaultBtn: (this.searchConfig("orderby") == "name_first")? 0:1
    }); */

    switch (tk.setting("ab_searchcontacts_displayMode")) {
        case "address" :

            var address = null;
            e.data.functionCall = "ab.getContactByAddress";
            for(i in e.data.list) {
                if(e.data.list.hasOwnProperty(i)) {
                    address = e.data.list[i];
                    address.state = this.stateByID[address.state__id].abbreviation;
                }
            }
		
		
            $("#contactSearchResults").snippet("ab__contact_tile", e.data);
            break;
        case "contactAndAddress" :
            var address = null;
            ui.btnGroupSetActiveBtn('abDisplayMode', '1', 'btnTblGreySML','btnTblRedSML');
            e.data.functionCall = "ab.getContactByAddress";
            for(i in e.data.list) if(e.data.list.hasOwnProperty(i)) {
                for(j in e.data.list[i].addressList) if(e.data.list[i].addressList.hasOwnProperty(j)) {
                    address = e.data.list[i].addressList[j];
                    address.state = "";
                    if( typeof this.stateByID[address.state__id] != "undefined" )
                        address.state = this.stateByID[address.state__id].abbreviation;
                }
            }


            $("#contactSearchResults").snippet("ab__contact_expanded__list", e.data);
            break;
	
        default : //case "contact" :
            ui.btnGroupSetActiveBtn('abDisplayMode', '0', 'btnTblGreySML','btnTblRedSML');
            $("#contactSearchResults").snippet("ab__contact_list", e.data);
    }
    this.vars.lastSearch = e.data;
    $("#contactSearchResults").fadeIn(200);
}

AddressBook.prototype.searchConfig = function(inSettingName, inSettingVal) {
    if(typeof inSettingVal == "undefined")
        return this.srchConfig[inSettingName] ;
    this.srchConfig[inSettingName] = inSettingVal;
}

AddressBook.prototype.setDisplayMode = function (inDisplayMode) {
    tk.setting("ab_searchcontacts_displayMode", inDisplayMode);
    this.searchContacts();
}

/*AddressBook.prototype.setOrderBy = function (inOrderBy) {
    tk.setting("ab_searchcontacts_pageLen", inOrderBy);
    this.searchContacts();
} */


