letterControl = {};


LetterManager.prototype._init = function() {
    this.supressDraftMsg = false;
    if(!this.hasOwnProperty("vars")) this.vars = {};
    this.vars.marginFields = ["page_margin_top", "page_margin_left", "page_margin_right", "page_margin_bottom"];
    this.vars.optionFields = $.extend(["make_it_fit", "page_size","return_address_include_name"], this.vars.marginFields);
    this.vars.FCKBasePath = "fckeditor/";
    this.vars.lastContactSearch = {pageNum:0};

    if(!this.hasOwnProperty("searchResults")) {
        this.searchResults = {};
    }
    if(!this.searchResults.hasOwnProperty("outbox")) {
        this.searchResults.outbox = [];
    }
    if(!this.searchResults.hasOwnProperty("draft")) {
        this.searchResults.draft = [];
    }
    if(!this.searchResults.hasOwnProperty("sent")) {
        this.searchResults.sent = [];
    }
}


LetterManager.prototype.addRecipient = function(inAddressID) {
    $("#aTile_lmanABList__" + inAddressID).fadeOut();
    this.rmi_addRecipient(this.editingLetterID, inAddressID);

}


LetterManager.prototype.addRecipient_cb = function(e) {
    if(!ui.ro(e)) return;
    this.rmi_getRecipients(this.editingLetterID);
}


LetterManager.prototype.alertReadOnly = function(e) {
    alert("This window is for information purposes only.")
}


LetterManager.prototype.autoSaveDraft = function(inID) {
    if(letterControl.hasOwnProperty(inID)) {
        if(FCKeditorAPI.GetInstance("fck_" + inID).IsDirty()) {
            this.rmi_autoSaveDraft({
                "id":inID,
                "content_autosave":FCKeditorAPI.GetInstance("fck_" + inID).GetHTML()
                });
        }
        letterControl[inID].autoSaveTimeout = setTimeout("lman.autoSaveDraft(" + inID + ")", 30000);
    }
}

LetterManager.prototype.autoSaveDraft_cb = function(e) {
    if(!ui.ro(e)) return;
    FCKeditorAPI.GetInstance("fck_" + e.data).ResetIsDirty();
}

LetterManager.prototype.buildLetterFromUI = function(inID) {
    var letter = {
        "id":inID,
        "title":$("#letter__title__" + inID).val(),
        "content":""
    };
    letter = $.extend(letter, $.ofd(this.vars.marginFields, "letter_" + inID + "__"));
    letter = $.extend(letter, $.ofd(["page_size", "make_it_fit"], "letter_" + inID + "__"));
    letter.return_address_include_name = $("#letter_" + inID + "__return_address_include_name").attr("checked").toString();
    letter.content = FCKeditorAPI.GetInstance("fck_" + inID).GetHTML();
    letter.leadin = letter.content.replace("<br />", " ");
    letter.leadin = letter.leadin.replace(/(<([^>]+)>)/ig,"").substring(0,199);
    return letter;
}


LetterManager.prototype.callbackHandler = function(e) {
    alert(e);
}


LetterManager.prototype.changeTabTitle = function(inLetterID, inString) {

    $("#mainMenu_letter_" + inLetterID + "__tooltip").snippet("tooltip", {
        content:inString,
        cssClass:"ttBlueTile",
        toolTipID:"letter_title_" + inLetterID
    });
    if(inString.length > 12)
        inString = inString.substring(0,12) + "... ";
    else
        inString = inString + "&nbsp;&nbsp;";
    $("#mainMenu_letter__" + inLetterID + "__title").html(inString);
}

LetterManager.prototype.closeAllEditLetterPanels = function() {
    for(i in letterControl) if(letterControl.hasOwnProperty(i)) {
        this.closeEditLetterPanel(i)
    }
}


LetterManager.prototype.closeEditLetterPanel = function(inID, inArgs) {
    var opts = $.extend({noCloseConfirm:false, showPanel:"drafts"}, inArgs);
    if(letterControl.hasOwnProperty(inID)) {
        if(this.dirtyLetter(inID)) {
            if(!opts.noCloseConfirm) //yes, backward logic. Must have been early
                if(!confirm("You have not saved changes to this letter.\nClose anyway?"))
                    return(false);
        }
        clearTimeout(letterControl[inID].autoSaveTimeout);
        this.rmi_autoSaveDraftClear(inID);
        $("#contentPanel_letter_" + inID).remove();
        $("#mainMenu_letter_" + inID).remove();
        $("#contentPanel_letter_" + inID + "__tooltips").remove();
        letterControl[inID] = null;
        delete(letterControl[inID]);

        this.searchDrafts({}, false);
        ui.displayMain(opts.showPanel);
    }
    return(true);
}

/**
 * requests that a copy be made of the db entry for letter 'inID'
 */
LetterManager.prototype.copyLetter = function (inID) {
    ui.statusMessage("copying letter");
    this.rmi_copyLetter(inID);
}


LetterManager.prototype.copyLetter_cb = function (e) {
    if(!ui.ro(e, true)) return false;
    this.newEditLetterPanel(e.data)
}


LetterManager.prototype.delayedContactSearch = function (inLetterID) {
    if(typeof(timeouts.contactSearch) != "undefined") {
        clearTimeout(timeouts.contactSearch);
    }
    timeouts.contactSearch = setTimeout("delete(timeouts.contactSearch); lman.searchContacts({'letterID':" + inLetterID + ", pageNum:0})", 250);
}


LetterManager.prototype.dirtyLetter = function(inID) {
    /*loop through letters checking for dirty attribute.
	 * if dirty, return true.
	 */
    if(typeof(inID) != "undefined") {
        if(letterControl.hasOwnProperty(inID)) {
            var oEditor = FCKeditorAPI.GetInstance('fck_' + inID);
            if(oEditor.IsDirty()) {
                return(true);
            }
        } else {
            $.log("dirtyLetter: we don't have letter " + inID + "error! (may be caused by deleting a letter that is not currently open)");
        }
    }
    else {
        for(var i in letterControl) {
            if(letterControl.hasOwnProperty(i)) {
                var oEditor = FCKeditorAPI.GetInstance('fck_' + i);
                if(oEditor.IsDirty()) {
                    return(true);
                }
            }
        }
    }
    return(false);
}


LetterManager.prototype.discardDraft = function(inID) {
    if(!confirm("are you sure you want to delete this letter?")) {
        return;
    };
    this.rmi_discardDraft(inID);
}


LetterManager.prototype.discardDraft_cb = function(e) {
    if(!ui.ro(e)) return false;
    lman.closeEditLetterPanel(e.data, {
        noCloseConfirm:true
    });
    lman.searchDrafts({}, false);
}


LetterManager.prototype.discardSent = function(inID) {
    if(!confirm("are you sure you want to delete this letter?")) {
        return;
    };
    this.rmi_discardSent(inID);
}
	

LetterManager.prototype.discardSent_cb = function(e) {
    if(!ui.ro(e)) return false;
    lman.searchSent();
}


LetterManager.prototype.editLetter = function(inID) {
    if(this.letterIsOpen(inID)) {
        this.uiDisplay("letter", inID);
        return;
    }
    ui.statusMessage("retrieving your letter");
    this.rmi_getLetterByID(inID, function(e) {
        lman.editLetter_cb(e);
    });
}


LetterManager.prototype.editLetter_cb = function(e) {
    if(!ui.ro(e)) return false;
    this.newEditLetterPanel(e.data);
}


/**
*	fills the recipients section of the editRecipients modal
*/
LetterManager.prototype.fillAddressList = function(inLetterID, inFunctionCall, inPanelID, inAddressList) {
    var letter = this.letterIsOpen(inLetterID, "lman.fillAddressList");
    if(letter) {
        if(typeof(inAddressList) == "undefined") {
            var list = $.clone(letter.letter.recipientList);
        } else {
            var list = $.clone(inAddressList);
        }
        var tpE = {
            "list":list,
            "itemType":"address_contact",
            "functionCall":inFunctionCall
        }
        $("#" + inPanelID).snippet("modal__lman__contact_tile", tpE);
        delete(tpE);
        delete(list);
    }
    letter = null;
    delete(letter);

}


LetterManager.prototype.getRecipients_cb = function(e) {
    if(!ui.ro(e)) return false;
    if(!letterControl.hasOwnProperty(e.data.letter__id)) {
        ui.statusMessage("letter manager does not have this letter! #" + e.data.letter__id +" (getRecipients_cb)", "error");
        return(false);
    }
    letterControl[e.data.letter__id].letter.recipientList = e.data.recipientList;
    this.searchContacts({
        "letterID":e.data.letter__id
        });
    $("#recipientList").snippet("modal__lman__contact_tile", {
        list:letterControl[this.editingLetterID].letter.recipientList,
        aTileMode:"lmanRecipient"
    });
    this.editLetter_setRecipientUIContent(e.data.letter__id, e.data.recipientList);
}

LetterManager.prototype.letterIsOpen = function(inLetterID, inFailMessage) {
    if(!letterControl.hasOwnProperty(inLetterID)) {
        //$.log("letter " + inLetterID + " in letterControl NOT PRESENT!\n" + " calling function says:" + inFailMessage, "lman.letterIsOpen");
        return(false);
    }
    return(letterControl[inLetterID]);
}


LetterManager.prototype.modalContactNew = function(inOpts) {
    tpElements = $.extend({
        "contact_nameLabel":"new contact: ",
        "id":-1,
        modalTitle:"Send Letter to...",
        editorMode:"lman",
        contactCount:tk.setting("contactCount")
        }, inOpts);
    tpElements.contactChooserButtons = ui.btnGroup("lmanNewContact",
        [
        {
            text:"a new contact",
            onclick:"$('#modal__lman__new_address__contact_row').fadeOut();"
        + "$('#modal__lman__new_address__contact__id').val('-1');"
        + "$('#modal__lman__new_address__contact__name').val('');"
        + "$('#editContactAddressPanel').fadeIn()"
        },
        {
            text:"an existing contact",
            onclick:"$('#modal__lman__new_address__contact_row').fadeIn();"
        + "$('#editContactAddressPanel').fadeIn()"
        }
        ],
        {
            btnClass:"btnTblGreySML",
            btnClassActive:"btnTblRedSML",
            defaultBtn:-1
        }
        );
    ui.modal("modal__lman__new_address", tpElements, "newAddress");
        
    setTimeout("lman.modalContactNew_init()", 1000);
}

/*
 * Created to help deal with timing issues
 */
LetterManager.prototype.modalContactNew_init = function() {
    $("#modal__lman__new_address__contact__name").autocomplete("js/autocomplete.php?mode=searchContacts");
    $("#modal__lman__new_address__contact__name").result(function(event, data, formatted) {
        $("#modal__lman__new_address__contact__id").val(data[1]);
        $("#address1__name").val(formatted);
    });
    lman.newEditAddressTile()
}

LetterManager.prototype.newEditAddressTile = function() {
    inAddress = ab.getEmpty("address");
    inAddress.num = 1;
    $("#editContactAddressPanel").prepend( ui.aTile(inAddress, "lmanEdit" ) );
    $("#address" + inAddress.num + "__type__id").val(inAddress.type__id);
}


LetterManager.prototype.modalSaveAddNewAddress = function(inAddress) {
    if(!tk.loggedIn()) {
        //		tk.loginDriveBy("modalSaveAddNewContact");
        return false;
    }

    var contact = $.objFromDom(new Array("id","name"), "modal__lman__new_address__contact__");
    if(parseInt(contact.id) == -1) contact.name = $("#address1__name").val();
    contact.addressList = [$.objFromDom(["id","name", "postalAddress", "type__id"], "address1__")];
	
    ab.rmi_saveContact(contact,function(e) {
        lman.modalSaveAddNewContact_cb(e)
        });
}


LetterManager.prototype.modalSaveAddNewContact_cb = function(e) {
    if(!ui.ro(e)) return false;
    $.modal.close();
    tk.setting("contactCount", e.data.contactCount);
    //setTimeout("lman.modalRecipientsEdit()", 1000);
    if(e.data.contact.addressList.length == 0) {
        ui.statusMessage("unable to add address. Please check your address book");
        return false;
    }
    this.rmi_addRecipient(this.editingLetterID, e.data.contact.addressList[0].id);
}


LetterManager.prototype.modalRecipientsEdit = function(inID) {
    if(tk.setting("contactCount") == 0) {
        this.modalContactNew();
        return;
    }
    if(typeof inID == "undefined") inID = this.editingLetterID;

    var tpLetter = $.extend({
        modalTitle:"Edit Recipients - <i>Who is this letter going to?</i>",
        list:letterControl[inID].letter.recipientList,
        aTileMode:"lmanRecipient",
        modalOverflowY:true
    }, letterControl[inID]);
    ui.modal("modal__lman__edit_recipients", tpLetter, "editRecipients");
    $(".modalCloseX").html(ui.btnGrySml({
        title:"close when done adding/removing recipients",
        text:"done"
    }));
    $(".modalCloseX").css("padding-top", "6px");
    //setTimeout("lman.searchContacts({pageNum:0})", 500);
    setTimeout("lman.searchContacts({letterID:" + inID + ", pageNum:0})", 500);
}

LetterManager.prototype.modalImageManager = function(inObj) {
    ui.modal("modal__lman__image_manager", {}, "imageManager");
}

LetterManager.prototype.modalImageManager_cb = function(inName) {
    $.modal.close();
    letterControl[this.editingLetterID].FCKIManager.Add(inName);
}

/**
 * infinite recursion what?
 */
LetterManager.prototype.modalViewRecipients = function(inLetterID, inTitle) {	
    ui.modal("modal__wait", {}, "viewRecipients");
    this.rmi_getRecipients(inLetterID, function(e){
        lman.modalViewRecipients_cb(e, inTitle)
        });
}

LetterManager.prototype.modalViewRecipients_cb = function(e, inTitle) {
    if(!ui.ro(e)) {
        $.modal.close();
        return false;
    }

    ui.modalSetContent({modalTitle:"Recipients for: " + inTitle, content:$.snippet("lman__modal__view_recipients"),  modalOverflowY:true});
    $.each(e.data.recipientList, function() {
        if(e.data.status == "outbox" || e.data.status == "sent") {
            this.name = this.rel__sent_name;
            this.postalAddress = this.rel__sent_postalAddress;
        }
        $("#recipientList").append(ui.aTile(this));
    });

    if(e.data.recipientList.length == 0) {
        $("#recipientList").html("There are no recipients for this letter");
    }
}


LetterManager.prototype.editLetter_setRecipientUIContent = function(inLetterID, inAddressList, inTarget) {
    var aTileContent = {
        content:"",
        cssClass:"ttBlueTile",
        toolTipID:inLetterID
    };
    $.each(inAddressList, function() {
        this.cssClass = "toolTip";
        aTileContent.content += $.snippet("address__postalAddress__view", this);
    });
    if(inAddressList.length > 1) {
        $("#letter_to_count_" + inLetterID).html("<b>" + inAddressList.length + "</b> people" );
    } else if (inAddressList.length == 1) {
        $("#letter_to_count_" + inLetterID).html(inAddressList[0].name);
    } else { //if there is no-one
        $("#letter_to_count_" + inLetterID).html("<span style='color:red; font-weight:bold'>add someone!</span>");
        aTileContent.content = "<b>click here to add a recipient</b>";
    }

    $("#editLetter_recipientTooltip_" + inLetterID).snippet("tooltip", aTileContent);
}

LetterManager.prototype.editLetter_recipientSummary_elements = function(inLetterID, inAddressList) {
    var tpE = {};
    var aTileContent = {
        content:"",
        cssClass:"ttBlueTile",
        toolTipID:inLetterID
    };
    $.each(inAddressList, function() {
        this.cssClass = "toolTip";
        aTileContent.content += $.snippet("address__postalAddress__view", this);
    });
    if(inAddressList.length > 1) {
        tpE.recipientSummary = "<b>" + inAddressList.length + "</b> people";
    } else if (inAddressList.length == 1) {
        tpE.recipientSummary = inAddressList[0].name;
    } else { //if there is no-one
        tpE.recipientSummary = "<span style='color:red''>add someone!</span>";
        aTileContent.content = "<b>click here to add a recipient</b>";
    }

    tpE.recipientTooltip = $.snippet("tooltip", aTileContent);
    return(tpE);
}


LetterManager.prototype.newEditLetterPanel = function(inLetter, inConfig) {
    var config = $.extend({
        editRecipients:false
    }, inConfig);
    //var contentPanel = "";
    if(letterControl.hasOwnProperty(inLetter.id)) {
        ui.statusMessage("This letter is already open", "error");
        return(false);
    }
    var content = inLetter.content;
    if(inLetter.hasOwnProperty("content_autosave") && inLetter.content_autosave.length > 0) {
        if(confirm("Previously, this letter was closed before saving.\n Would you like to recover unsaved changes?")) {
            ui.statusMessage("you must click save to keep recovered changes!")
            content = inLetter.content_autosave;
        }
    }
    this.rmi_autoSaveDraftClear(inLetter.id);
    letterControl[inLetter.id] = {};
    letterControl[inLetter.id].letter = inLetter;
    if(config.editRecipients) {
        this.modalRecipientsEdit(inLetter.id);
    }
    $("head").snippetAppend("lman__edit_letter_style", inLetter);
    $("#letterTabPanel").snippetAppend("mainmenu__letter_tab", inLetter);
        
    //adding these vars because the letter is being used to populate the editor template (maybe need to find another way and keep it clean?)

    inLetter.returnAddress = tk.setting("ex_returnAddress");
    var state = ab.get("stateByID", inLetter.returnAddress.state__id);
    inLetter.returnAddress.state = (state)? state.abbreviation : "";
    inLetter["page_sizeList"] = tk.setting("ex_page_sizes");
    $("#mainContentPanel").snippetAppend("lman__edit_letter", inLetter);
    $("#fck_" + inLetter.id).val(content);

	
    this.changeTabTitle(inLetter.id, inLetter.title);
    $("#mainMenu_letter_" + inLetter.id).tooltip({tip:"#mainMenu_letter_" + inLetter.id + "__tooltip", position:["top","center"], effect: 'toggle', delay:0}); //(inLetter.id, inLetter.title);
    $("#letter__title__" + inLetter.id).val(inLetter.title);
    ui.displayMain("letter_" + inLetter.id);
    this.setEditingLetter(inLetter.id);

    var oFCKeditor = new FCKeditor( "fck_" + inLetter.id ) ;

    oFCKeditor.letterID = inLetter.id;
    oFCKeditor.BasePath	= this.vars.FCKBasePath ;
    //oFCKeditor.Height	= $("#mainContentPanel").innerHeight() -30 ;
    oFCKeditor.Height	=  ui.setting("fckHeight");
    oFCKeditor.Width	= "100%" ;
    oFCKeditor.ReplaceTextarea() ;

    //tooltipcode
    $("#letter_to_" + inLetter.id).tooltip({
        tip:"#editLetter_recipientTooltip_" + inLetter.id,
        position:["bottom","center"], offset:[5,-25]
        });

    $("#editLetter_panelTab_" + inLetter.id + "__options").tooltip({tip:"#editLetter_panelTab_" + inLetter.id + "__options__tooltip", position:["bottom","center"], offset:[0,-15]});
    this.editLetter_setRecipientUIContent(inLetter.id, inLetter.recipientList);
    //set event listener to force margin fields to numbers
    for(var i in this.vars.marginFields) if(this.vars.marginFields.hasOwnProperty(i)) {
        $("#letter_" + inLetter.id + "__" + this.vars.marginFields[i]).listen({
            chars:{
                "\t":""
            },
            regEx:{expr:/^\d*(\.\d*)?$/,
            onFailedPreventDefault:true
        }});
    }
    for(var i in this.vars.optionFields) if(this.vars.optionFields.hasOwnProperty(i)) {
        $("#letter_" + inLetter.id + "__" + this.vars.optionFields[i]).val(inLetter[this.vars.optionFields[i]]);
    }
    $("#letter_" + inLetter.id + "__return_address_include_name").attr("checked", (inLetter.return_address_include_name == "true"));
    $("#letter_" + inLetter.id + "__page_size").val(inLetter.page_size);

    
}



LetterManager.prototype.newLetter = function(inData) {
    if(!tk.loggedIn()) {
        tk.loginDriveBy("newLetter");
    }
    else {
        if(typeof(inData) != "undefined")
            this.rmi_newLetter(inData);
        else {
            this.rmi_newLetter();
        }
    }
}


LetterManager.prototype.newLetter_cb = function(e) {
    if(!ui.ro(e, true)) return false;
    var config = {};
    if(e.data.recipientList.length == 0) {
        config.editRecipients = (tk.setting("lman_letter_prompt_for_recipient_on_new") == "true");
    }
    this.newEditLetterPanel(e.data, config);
    
}


LetterManager.prototype.pdfPreview = function(inID) {
    ui.modal("modal__wait", {
        messageBelow:"Please wait while we create your preview.",
        modalTitle:"Preview '" + letterControl[inID].letter.title + "'"
        }, "previewSend");
    var letter = this.buildLetterFromUI(inID);
    lman.rmi_pdfPreview(letter);
}


LetterManager.prototype.pdfPreview_cb = function(e) {
    if(!ui.ro(e)) {
        $.modal.close();
        return false;
    }
    $("#modalContent").snippet("iframe_pdf", {
        "id":e.data,
        "preview":'true'
    });
}


/**
 *	Cleanup function - called when deleting a contact 
 */
LetterManager.prototype.removeContactFromOpenLetters = function(inContactID) {
    inContactID = parseInt(inContactID);
    for(var i in letterControl) if(letterControl.hasOwnProperty(i)) {
        for(var j in letterControl[i].letter.recipientList) if(letterControl[i].letter.recipientList.hasOwnProperty(j)) {
            if(parseInt(letterControl[i].letter.recipientList[j].c_id) == inContactID) {
                letterControl[i].letter.recipientList.splice(j, 1);
                lman.editLetter_setRecipientUIContent(letterControl[i].letter.id, letterControl[i].letter.recipientList)
                break;
            }
        }
    }
}

/**
 *	Cleanup function - called when deleting an address
 */
LetterManager.prototype.removeAddressFromOpenLetters = function(inAddressIDList) {
    inAddressIDList = (typeof inAddressIDList == "object")? inAddressIDList : [inAddressIDList];
    for(var i in letterControl) if(letterControl.hasOwnProperty(i)) {
        for(var j in letterControl[i].letter.recipientList) if(letterControl[i].letter.recipientList.hasOwnProperty(j)) {
            for(var k in inAddressIDList) if(inAddressIDList.hasOwnProperty(k)) {
                if(letterControl[i].letter.recipientList[j].id == inAddressIDList[k]) {
                    letterControl[i].letter.recipientList.splice(j, 1);
                    lman.editLetter_setRecipientUIContent(letterControl[i].letter.id, letterControl[i].letter.recipientList)
                    break;
                }
            }
        }
    }
}


LetterManager.prototype.removeRecipient = function(inAddressID) {
    $("#aTile_lmanRecipient__" + inAddressID).fadeOut();
    this.rmi_removeRecipient(this.editingLetterID, inAddressID);
}


LetterManager.prototype.removeRecipient_cb = function(e) {
    if(!ui.ro(e)) return false;
    this.rmi_getRecipients(this.editingLetterID);
}

LetterManager.prototype.revertToDraft = function(inID) {
    this.rmi_outboxToDraft(inID, function(e) {
        lman.revertToDraft_cb(e);
    });
}
	
LetterManager.prototype.revertToDraft_cb = function(e) {
    if(!ui.ro(e)) return false;
    this.searchSent();
}

LetterManager.prototype.saveDraft = function(inID) {
    var letter = this.buildLetterFromUI(inID);
    
    if(letter.title.toLowerCase() == "untitled" && letter.leadin.length > 5) {
        //$.log(letter.leadin + "\n ||\n" + letter.leadin.length + " " + letter.leadin.indexOf(" ", 18));
        var index = (letter.leadin.indexOf(" ", 18) > 0)? letter.leadin.indexOf(" ", 18) : 50;
        letter.title = letter.leadin.substring(0,index).substring(0,50);
        $("#letter__title__" + inID).val(letter.title);
        this.changeTabTitle(inID, letter.title);
    }
    this.rmi_saveDraft(letter);
    ui.statusMessage("saving your letter '" + $("#letter__title__" + inID).val() + "'");
    delete(index);
    delete(letter);
}


LetterManager.prototype.saveDraft_cb = function(e) {
    if(ui.ro(e, true)) {
        if(tk.driveBy()) {
            if(confirm("You are not logged in. If you want to be able to access your letter after you have closed your browser you MUST login or register. Would you like to do that now?")) {
                ui.modalLogin();
            };
        }
        FCKeditorAPI.GetInstance("fck_" + e.data).ResetIsDirty();
    }
}


LetterManager.prototype.saveAndSend = function(inID) {
    var id = inID; //did this to save variable for reference in the callback function otherwise would have had to rewrite php core class code
    var letter = this.buildLetterFromUI(inID);
    if(tk.loggedIn() && tk.driveBy()) {
        ui.modalLogin("Great! You're almost ready to send your letter.  We need to register you first, so we can put a return address on the envelope.");
        this.rmi_saveDraft(letter, function(e) {
            ui.ro(e)
        }); //we are saving here so that if the user confirms in another window the letter will be what they've input so-far.
        return(true);
    } else {
        if(letterControl[inID].letter.recipientList.length == 0) {
            this.modalRecipientsEdit(inID);
            alert("Who is this letter going to?");
            return(false);
        }
        ui.modal("modal__wait", {
            modalTitle:"Send this letter",
            messageBelow:"Please wait while we prepare your letter."
        }, "previewSend");
        this.rmi_saveFinal(letter, function(e) {
            lman.saveAndSend_cb(e, id);
        });
    }
    delete(letter);
}


LetterManager.prototype.saveAndSend_cb = function(e, id) {
    if(!ui.ro(e)) {
        $.modal.close();
        return;
    }
    FCKeditorAPI.GetInstance("fck_" + e.data.id).ResetIsDirty();
    $.log(e, true);
    var tpE = $.extend({
        "pdf_url":"pdf_view.php?letter__id=" + id + "&file=file.pdf",
        "id":id,
        "transaction_amount": e.data.transaction_amount,
        "user__balance":e.data.user__balance,
        "user__total_balance":(e.data.user__balance - e.data.outbox_balance),
        "outbox_balance":e.data.outbox_balance
    }, this.editLetter_recipientSummary_elements(id, letterControl[id].letter.recipientList));
    //below would be the cost calculation
    tpE.cost = "$" + (letterControl[id].letter.recipientList.length * 1.20).toFixed(2);
    tpE.recipientTooltip = $.snippet("tooltip", {
        content:"<div style='text-align:center'>click to view</div>",
        cssClass:"ttBlueTile",
        toolTipID:id
    });
    //var tpE = {"pdf_url":"pdf_view.php?letter__id=" + id + "&file=file.pdf", "id":id};
    $("#modalContent").snippet("modal__lman__preview_and_send", tpE);
    $("#modalIframeWrapper").css("height", $("#modalIframeWrapper").innerHeight());
    $("#modalIframe").fadeIn();
    $("#modal_recipientSummary").tooltip({
        tip:"#modal_recipientTooltip",
        position:["bottom", "center"]
        });
}


LetterManager.prototype.searchContacts = function (inSearchConfig, inCallback) {
    var searchConfig = {
        "displayOn":"address",
        "excludeAddressID":[],
        "letterID":this.editingLetterID,
        "pageNum":this.vars.lastContactSearch.pageNum,
        "pageLen":tk.setting("lman_searchcontacts_pageLen"),
        "searchName":$('#sendTo_contactSearchBox').val()
        };
	
    if(typeof(inSearchConfig) != "undefined") {
        $.extend(searchConfig, inSearchConfig);
    }
	
    for(var i in letterControl[searchConfig.letterID].letter.recipientList) {
        if(letterControl[searchConfig.letterID].letter.recipientList.hasOwnProperty(i))
            searchConfig.excludeAddressID.push(parseInt(letterControl[searchConfig.letterID].letter.recipientList[i].id));
    }
    if(typeof(inCallback) == "function") this.rmi_searchContacts($('#sendTo_contactSearchBox').val(), searchConfig, inCallback);
    else this.rmi_searchContacts(searchConfig);
}


LetterManager.prototype.searchContacts_cb = function (e) {
    e.data.func = "lman.searchContacts";
    //e.data.result
    e.data.pager = ui.pagerGrySml(e.data, true);
    e.data.pagelen = ui.btnGroup("lmanSearchContacts", [10,20,40], {
        func:"lman.setContactsPageLen",
        btnClass:"btnTblGreySML",
        btnClassActive:"btnTblRedSML",
        defaultBtn:tk.setting("lman_searchcontacts_pageLen")
    });
    e.data.functionCall = "lman.addRecipient";
    e.data.itemType     = "address_contact"; /*why do we need this?*/
    e.data.aTileMode    = "lmanABList";
    this.vars.lastContactSearch = e.data;
    $("#sendToContactList").snippet("modal__lman__contact_tile", e.data);
}


LetterManager.prototype.searchDrafts = function(inSearchConfig, inStatusMessage) {
    if(!tk.loggedIn()) {
        $("#contentPanel_drafts").snippet("no_items", {
            "status":"drafts"
        });
        return false;
    }
    var searchConfig = {
        "status":"draft",
        "search":"",
        "pageNum":0,
        "pageLen":((tk.setting("lman_searchdrafts_pageLen"))?tk.setting("lman_searchdrafts_pageLen"):10)
        };
    if(typeof inSearchConfig != "boolean") {
        $.extend(searchConfig, inSearchConfig);
    }
	
    if(typeof(inStatusMessage) == "undefined" || inStatusMessage == true) {
        ui.statusMessage("looking for drafts");
    }
	
    this.rmi_searchLetters(searchConfig, function(e) {
        lman.searchDrafts_cb(e);
    });
    delete(letterFilter);
}

LetterManager.prototype.searchDrafts_cb = function(e) {
    if(this.supressDraftMsg) {
        if(!e.ok) {
            this.supressDraftMsg = false;
            $("#contentPanel_drafts").snippet("no_items", {
                "status":"drafts"
            });
            return false;
        }
    } else if (!ui.ro(e)) {
        $("#contentPanel_drafts").snippet("no_items", {
            "status":"drafts"
        });
        return false;
    }
	
    this.searchResults.draft = e.data;
    e.data.func = "lman.searchDrafts";
    e.data.pager = ui.pagerGrySml(e.data, true);
    e.data.pagelen = ui.btnGroup("draftListBottom", ['8', '16', '32'], {
        func:"lman.setDraftsPageLen",
        defaultBtn:tk.setting("lman_searchdrafts_pageLen")
        });
    var list = e.data.list;
    var jsDate = new Date();
    for(i in list) {
        if(list.hasOwnProperty(i)) {
            var letter = list[i];
            letter.name = letter.title;// + " " + jsDate.format();
            letter.itemType = "letter__draft";
        }
    }
    var html = $.snippet("lman__draft_list", e.data);
    $("#contentPanel_drafts").html(html);
}


LetterManager.prototype.searchSent = function() {
    if(!tk.loggedIn()) {
        $("#contentPanel_sent").snippet("no_items", {
            "status":"sent"
        });
        return false;
    }
	
    var searchConfig = {
        "status":["sent","outbox","outbox_locked"],
        "search":"",
        "pageNum":0,
        "pageLen":tk.setting("lman_searchsent_pageLen")
        };
    if(typeof(inSearchConfig) != "undefined") {
        $.extend(searchConfig, inSearchConfig);
    }
	
    if(typeof(inStatusMessage) == "undefined" || inStatusMessage == true) {
        ui.statusMessage("looking for sent letters");
    }
	
    this.rmi_searchLetters(searchConfig, function(e) {
        lman.searchSent_cb(e);
    });
    delete(letterFilter);
}


LetterManager.prototype.searchSent_cb = function(e) {
    if(!ui.ro(e)) {
        $("#contentPanel_sent").snippet("no_items", {
            "status":"sent"
        });
        return false;
    }
    this.searchResults.sent = e.data;
	
    e.data.pagerData = ui.paginationData(e.data.pageNum, e.data.pageLen, e.data.count);
    e.data.pagerData.func = "lman.searchSent";
    e.data.pager = $.snippet("pager_simple", e.data.pagerData);
	
    var list = e.data.list;
    $("#contentPanel_sent").html("");
    var html = "<table style=\"width:100%;\" cellspacing=\"0\" cellpadding=\"0\">";
    if(list.outbox.length > 0) {
        html += $.snippet("outbox_list", {
            "list":list.outbox
            });
    }
    if(list.sent.length > 0) {
        html += $.snippet("sent_list", {
            "list":list.sent
            });
    }
    html += "</table>";
    $("#contentPanel_sent").html(html);
}


LetterManager.prototype.sendLetter = function(inID) {
    this.rmi_sendLetter({
        "id":inID
    });
}


LetterManager.prototype.sendLetter_cb = function(e) {
    $("#modalContent").css("display", "none");
    //$.log(letterControl[e.data], true);
    if(e.ok){
        lman.searchSent();
        var messageBelow = (e.data.addCredit)? "You need to purchase credit to send this letter." : "Displaying outbox";
        $("#modalContent").snippet("modal__message",  {
            "modalTitle":"Letter Sent",
            "messageAbove":"The letter \"" + letterControl[e.data.letter.id].letter.title + "\" has been placed in your outbox.",
            "messageBelow":messageBelow
        });
        $("#modalContent").fadeIn("normal");
        this.closeEditLetterPanel(e.data.letter.id, {showPanel:"sent"});
        if(e.data.addCredit) {
            tk.modalAccount("billing");
        } else {
            setTimeout("$.modal.close();", 3000);
        }
        //if(!ui.ro(e, true)) return false;
    } else {
        $("#modalContent").snippet("modal__message",  {
            modalTitle:"Oops!",
            messageAbove:"We were not able to send the letter.",
            messageBelow:""
        });
        $("#modalContent").fadeIn("normal");
        alert(e.message);
    }
}
/**
 * THIS FUNCTIONALITY SUPERCEEDED BY pymt.newPaymentFromUI()
LetterManager.prototype.sendLetterPayment = function(inID, inProcessor) {

    pymt.newPayment(inProcessor, $("#sendLetter__transaction_amount").val(), "add credit & send-letter", {
        needstoken:function() {
            var winObj = window.open("/_ext/payments/" + inProcessor + "/authorize.php?transaction__id=" + this.id, "location=0,status=0,width=647,height=500,scrollbars=1");
            if(winObj == null || typeof(winObj) == "undefined") {
                alert("You must allow popups to continue.");
            } else {
                $("#modalContent").snippet("modal__wait", {
                    messageBelow:"Please verify yourself in the popup window."
                });
            }

        },
        completed:function(){
            lman.sendLetter(inID);
        },
        failed:function() {
            alert("Your transaction did not complete successfully\n");
            $("#modalContent").snippet("modal__message",  {
                modalTitle:"Oops!",
                messageAbove:"We were not able to send the letter.<br>The error returned by " + inProcessor + " was " + this.processor_transaction_status,
                messageBelow:"Please close this message modal and try again."
            });
            //ui.modalSetContent("Your transaction did not complete successfully<br><br>);
        }
    });
}*/


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

LetterManager.prototype.setDraftsPageLen = function(inPageLen) {
    tk.setting("lman_searchdrafts_pageLen", inPageLen);
    this.searchDrafts();
}

LetterManager.prototype.setEditingLetter = function(inLetterID) {
    if(!this.letterIsOpen(inLetterID, "ui.setEditingLetter (likely caused by stop propagation not working on letter close in tab template)")) return false;
    this.editingLetterID = inLetterID;
    return true;
}

LetterManager.prototype.setEditorAreaMargins = function(inLetterID) {
    if(typeof inLetterID == "undefined") inLetterID = this.editingLetterID;

    var letterWidth = parseFloat(tk.setting("ex_page_sizes")[$("#letter_" + inLetterID + "__page_size").val()].widthIn);
    var displayWidth = parseFloat(tk.setting("ex_editorAreaDimensions").widthIn);
    var marginIn = (displayWidth - letterWidth)/2; //native margin, probably negative

    var leftIn = parseFloat($("#letter_" + inLetterID + "__page_margin_left").val()) + marginIn; //css("padding-", )
    var rightIn = parseFloat($("#letter_" + inLetterID + "__page_margin_right").val()) + marginIn; //css("padding-", )
    
    //if either margin is negative, we still want to preserve linebreaks. Average them (sacrificing visuals of margins being uneven if that is the case
    if(leftIn < 0 || rightIn < 0) {
        ui.statusMessage("With margins of this size, use the preview button to see an accurate display of your letter.", "warning");
        leftIn = (leftIn + rightIn) / 2;
        if(leftIn >= 0) rightIn = leftIn;
        else leftIn = rightIn = 0;
    }

    //multiply by 100 for 100 pixels per inch, set minimum margin if margin still 0 or negative.
    var leftMargin = ((leftIn * 100) > 2) ? Math.floor(leftIn * 100) : 2;
    var rightMargin = ((rightIn * 100) > 2) ? Math.floor(rightIn * 100) : 2;
    $("body", FCKeditorAPI.GetInstance("fck_" + inLetterID).EditorDocument).css("padding-left", leftMargin + "px").css("padding-right", rightMargin + "px");
    
}

/**
 * This function is called by the FCKIManager of each letter when it is created.
 * I did this because I couldn't figure out how to access it top down, so we add
 * a pointer up here for access.
 */
LetterManager.prototype.setFCKImageManager = function(inFCKIManager, inDocument) {
    inFCKIManager.imageRoot = w_root + 'user_image.php?name=';

    letterControl[this.editingLetterID].FCKIManager = inFCKIManager;
}

LetterManager.prototype.uiDisplay = function(inName, inID) {
    if(!this.letterIsOpen(inID, "lman.uiDisplay")) return false;
    switch(inName) {
        case "compose" :
            $("#editLetter_panelContent_" + inID).attr("className", "editLetter_content_showCompose");
            $("#editLetter_panelTab_" + inID).attr("className", "editLetter_panelTabWrapper_compose");
            break;
        case "options" :
            $("#editLetter_panelContent_" + inID).attr("className", "editLetter_content_showOptions");
            $("#editLetter_panelTab_" + inID).attr("className", "editLetter_panelTabWrapper_options");
            break;
        case "letter" :
        default :
            this.setEditingLetter(inID);
            ui.displayMain("letter_" + inID);
    }
    
    return true;
}


LetterManager.prototype.viewLetterModal = function(inLetterID) {
    ui.modal("modal__wait", {}, "previewSend");
    setTimeout("$('#modalContent').snippet('iframe_pdf', {'id':" + inLetterID + "});", 1000);
}


