/*
* Initialize global AJAX handler
*/
$(
    function() { 
        $('body').ajaxStart( function() { clearFeedback(); } );
        $('body').ajaxError( function() { alert('Unknown error occured. Please try again.'); } );
    }
)

function saveLead(leadId, status, rating, notes)
{
    $.post(_ajaxBase + "ajax/LeadSave.aspx", {method:"leadsave", leadid:leadId, status:status, rating:rating, notes:notes}, saveLeadCallback);
}

function saveLeadCallback(data)
{
    $("#lead_save_feedback").html(data);
}

/*
* Reformat the title input box on the suggest/edit title page
*/
function resetTitle(
    oldTemplateId, 
    newTemplateId, 
    titleContainer, 
    titleHintsContainer
)
{
    if(!titleContainer || !titleHintsContainer) return;
    
    var prefix;
    var suffix;
    var selected;
    var title = titleContainer.val();

    selected = dictionaryPrefixSuffix[oldTemplateId];
    prefix = selected? selected.prefix : defaultPrefixSuffix;
    suffix = selected ? selected.suffix :defaultPrefixSuffix;

    if(prefix != defaultPrefixSuffix || suffix != defaultPrefixSuffix)
    {
        prefix = "(^" + prefix.replace(/\s*\|\s*/ig, ")|(") + ")";
        var regex = new RegExp(prefix + "|(" + suffix + "$)", "ig");
        title = title.replace(regex, "").replace(/(^\s+)|(\s+$)/ig, "")
    }
    
    selected = dictionaryPrefixSuffix[newTemplateId];
    prefix = selected ? selected.prefix : defaultPrefixSuffix;
    suffix = selected ? selected.suffix : defaultPrefixSuffix;
    
    if(prefix != defaultPrefixSuffix || suffix != defaultPrefixSuffix)
    {
        var prefixes = prefix.split(/\s*\|\s*/i);
        if(prefixes.length > 1) prefix = prefixes[0];
        title = (prefix ? prefix + " " : "") + title + (suffix ? " " + suffix : "");
        titleContainer.val(title);
        //Some prefixes have to deal with singular/plural forms of the subject
        //which are separted by "|"
        $(".prefix_suffix", titleHintsContainer).text((prefix + suffix).replace(/\s*\|\s*/ig, " or "));
        titleHintsContainer.show();
    }
    else
    {
        titleContainer.val(title);
        titleHintsContainer.hide();
    }
}

/*
* Reformat the title input box on the suggest/edit title page
* ?? resetTitle does the same ??
*/
function clearTitle(siteId, titleContainer, titleHintsContainer)
{
    if(!titleContainer || !titleHintsContainer) return;
    
    if(siteId == 1) /* eHow */
    {
        titleContainer.val("How to ");
        titleHintsContainer.show();
    }
    else
    {
        titleContainer.val("");
        titleHintsContainer.hide();
    }
}

function onBrowseTitleTemplateChanged
(
    userId,
    templateId,
    categoryContainer    
)
{
    getSubCategoriesByTemplateId(userId, templateId, true, true, categoryContainer);
}

function onSuggestTitleTemplateChanged
(
    userId, 
    templateId, /* the selected template id */ 
    categoryContainer, /* has to be a select */ 
    titleContainer, /* has to be a text box */
    titleHintsContainer, /* has to have "title_hints" class */
    showAvailableTitleCount, /* whether to show total available titles in each category */
    previousTemplateIdContainer
)
{
    var oldTemplateId = $(previousTemplateIdContainer).val();
    resetTitle(oldTemplateId, templateId, titleContainer, titleHintsContainer);
    getSubCategoriesByTemplateId(userId, templateId, false, showAvailableTitleCount, categoryContainer);
    $(previousTemplateIdContainer).val(templateId);
}

function getSubCategoriesByTemplateId(userId, templateId /* the template id */, showAll, showAvailableTitleCount, container)
{
    if(templateId < 0) return;
    $.post(_ajaxBase + "ajax/GetSubCategories.aspx", 
            {uid:userId, template_id:templateId, showAll:showAll, showAvailableTitleCount: (showAvailableTitleCount ? true : false) },
            function(data) { getSubCategoriesCallback(data, $(container)); }
            );
}

/*
* Get sub categories for a given category
*/
function getSubCategoriesByParentId
(
    userId, 
    parentId /* the category id for the super category */, 
    showAll /* whether all is a valid option */, 
    container,
    getAll, /* whether userId is ignored and all categories are returned for the given parentId */
    categoryPrefix /* prefix for the select elements */
)
{
    if(parentId < 0) return;
    var postParameters = {};
    postParameters.showAll = showAll;
    postParameters.uid = userId;
    postParameters.getAll = getAll;
    //var regex = /category([0-9]+)/ig;
    var regex = new RegExp(categoryPrefix + "([0-9]+)", "ig");
    var match = container.attr("id").match(regex);
    var currentCategoryIndex = parseInt(RegExp.$1);
    var currentCategoryContainer = container;
    for(var i = currentCategoryIndex; i >= 1; i--)
    {
        postParameters.pid = $('#' + categoryPrefix + i).val();
        postParameters.plevel = i;
        if(postParameters.pid != 0) break;
    }
    postParameters.clevel = currentCategoryIndex + 1;
    
    for(var i = currentCategoryIndex + 1;i++;)
    {
        currentCategoryContainer = $('#' + categoryPrefix + i);
        if(currentCategoryContainer.length == 0) break;
        resetCategory(currentCategoryContainer[0]);
    }
    // If  pageSubCategories is defined from outside the script, we need to pass the ajax url the proxy
    if(typeof(pageSubCategories) != "undefined")
    {
    	postParameters.ajaxURL = _ajaxBase + "ajax/GetSubCategories.aspx";
    }
    else
    {
    	pageSubCategories = _ajaxBase + "ajax/GetSubCategories.aspx";
    }
    
    $.post(
        pageSubCategories, 
        postParameters, 
        function(data) { getSubCategoriesCallback(data, $('#' + categoryPrefix + (currentCategoryIndex + 1))); }
    );
}

function getSubCategoriesCallback(data, container)
{
    var response = $("response", data);
    if(response.attr("status") != "ok") return;
    
    if(response.attr("hasData") == "false") 
    {
        resetExtraSubCategories(container, false);
    }
    else
    {
        resetExtraSubCategories(container, true);
        container.html($("response action[name='refresh']", data).text());
        container[0].selectedIndex = 0;
    }
}

/*
* reset all sub-categories that are extra (not exists given the parent categories)
*/
function resetExtraSubCategories
(
    startingCategoryCtrl, /* jQuery object, the first "extra" sub category */
    enabled
)
{
    var idStr = startingCategoryCtrl.attr("id");
    idStr.match(/^(.+)([0-9])/);
    var categoryPrefix = RegExp.$1;
    var startPos = parseInt(RegExp.$2);
    var currentCategoryCtrl;
    for(var i = startPos; ;i++)
    {
        currentCategoryCtrl = $('#' + categoryPrefix + i);
        if(currentCategoryCtrl.length == 0) break;
        if(!enabled)
        {
            currentCategoryCtrl[0].options[currentCategoryCtrl[0].selectedIndex].text = "No more categories";
            currentCategoryCtrl[0].options[currentCategoryCtrl[0].selectedIndex].value = "0";
            currentCategoryCtrl.attr("disabled", "disabled");
        }
        else
        {
            currentCategoryCtrl[0].options[currentCategoryCtrl[0].selectedIndex].text = "-- Select --";
            currentCategoryCtrl[0].options[currentCategoryCtrl[0].selectedIndex].value = "-1";
            currentCategoryCtrl.removeAttr("disabled");
        }        
    }
}

function resetCategory(selectObject /* DOM object */)
{
    var options = selectObject.options;
    for(var i = options.length - 1; i > 0; i--)
    {
        
        if(options[i].value == 0 || options[i].value == -1) continue; //0 - ALL, -1 - "select one". should not hard-code this.
        selectObject.remove(i);
    }
}

/*
*
*/
function resetCategoryPicker(categoryPrefix, container)
{
    var firstSelectObj = $('#' + categoryPrefix + "1", container);
    if(firstSelectObj.length <= 0) return;
    
    var currentCategory;
    firstSelectObj[0].selectedIndex = 0;
    for(var i = 2; ;i++)
    {
        currentCategory = $('#' + categoryPrefix + i, container);
        if(currentCategory.length <= 0) break;
        resetCategory(currentCategory[0]);
    }
}

function findTitles(
    templateId, /* template id */
    keywords, 
    page, 
    container /* jQuery object to put the search results */
)
{
    if(keywords.replace(/\s/ig, '').length == 0)
    {
        alert("Please enter a non-empty keyword.");
        return;
    }
    var postData = {};
    postData.template_id = templateId;
    postData.keywords = keywords;
    postData.p = page;
    postData.mode = "by-keywords";
    //make AJAX call to return results
    $.post(_ajaxBase + "ajax/FindTitles.aspx",
            postData,
            function(data) { findTitlesCallback(data, container, postData.mode, keywords); }
            );
}

function browseTitles
(
    templateId, /* template id */
    categories, /* comma separated list of categories */
    page, /* current page number being requested */
    container /* jQuery object to where to place the returned html */
)
{
    if(categories.length == 0 || categories == "-1")
    {
        alert("Please select a category.");
        return;
    }
    
    //make AJAX call to return results
    var postData = {};
    
    postData.template_id = templateId;
    postData.categories = categories;
    postData.p = page;    
    postData.mode = "by-categories";
    $.post(
        _ajaxBase + "ajax/FindTitles.aspx", 
        postData,
        function(data) { findTitlesCallback(data, container, postData.mode, window.selectedCategories); } 
    );
}

function getCategories(
    categoryPrefix, /* prefix of the category controls */
    searchContainer /* container in which to search categories */
)
{
    //convert selected categories into ">>" separted list
    var selectedCategories = "";
    var categoryIds = [];
    var categoryCtrl;
    for(var i = 1; ; i++)
    {
        categoryCtrl = $('#' + categoryPrefix + i, $(searchContainer));
        if(categoryCtrl.length == 0) break;
        selectedCategories += categoryCtrl[0].options[categoryCtrl[0].selectedIndex].text + " >> ";
        categoryIds.push(categoryCtrl.val());
    }
    selectedCategories = selectedCategories.replace(/\s*>>\s*$/ig, '');
    window.selectedCategories = selectedCategories;
    return categoryIds.join(',');
}

function findTitlesCallback(data, container, mode, searchCriteria)
{
    container.html(data);
    if(mode == 'by-categories')
    {
        $('.selectedCategories').show();
        $('.selectedKeywords').hide();
        $('.selectedCategoriesList').html(searchCriteria);
    }
    else if(mode == 'by-keywords')
    {
        //show/hide UI prompts
        $('#results').show();
        $('.selectedKeywords').show();
        $('.selectedCategories').hide();
        $('.selectedKeywordsList').html(searchCriteria);    
    }
}

function isTitleEmpty(title /* string */)
{
    return title.replace(/\s/ig, '') == '';
}

function editArticleTitle
(
    articleId, /* int */
    name, /* string */
    container,
    feedbackContainer
)
{
    if(isTitleEmpty(name))     
    {
        alert("Please enter a title.");
        return;
    }
    
    var postData = { name:name };
    postData.aid = articleId;
    
    $.post(
        _ajaxBase + "ajax/SuggestTitle.aspx", 
        postData,
        function(data) { suggestTitleCallback(data, container, feedbackContainer); }
    );
}

/*
* Use this function to get the url of the hosting page
* SHOULD use an inline pop-up instead of transferring to a page for editting
*/
function editTitle(url, returnUrlName)
{
    window.location.href = url + (url.indexOf("?") > -1 ? "&" : "?") + returnUrlName + "=" + encodeURIComponent(window.location.href);
}

/*
* Update an existing title's name & categories
*/
function updateTitle
(
    titleId, /* int */
    name, /* string */
    price, /* decimal */
    categoryPrefix, /* naming convention for categories, category1, category2, etc. */
    requiredPrivilege, /* int, privilege required to claim the title */
    container,
    feedbackContainer
)
{
    if(isTitleEmpty(name))     
    {
        alert("Please enter a title.");
        return;
    }
    
    var categories = getCategories(categoryPrefix, container.parent());
    var postData = { name:name, categories:categories, price:price, required_privilege:requiredPrivilege };
    postData.tid = titleId;
    
    $.post(
        _ajaxBase + "ajax/SuggestTitle.aspx", 
        postData,
        function(data) { suggestTitleCallback(data, container, feedbackContainer, titleId, name); }
    );    
}

/*
* suggest a new title
*/
function suggestTitle
(
    name /* string */, 
    type /* int */, 
    templateId, /* template id */
    categoryPrefix, /* naming convention for categories, category1, category2, etc. */
    container, 
    feedbackContainer
)
{
    if(isTitleEmpty(name))     
    {
        alert("Please enter a title.");
        return;
    }
           
    var categories = getCategories(categoryPrefix, container.parent());       
    var postData = { name:name, type:type, template_id:templateId, categories:categories };
    
    $.post(
        _ajaxBase + "ajax/SuggestTitle.aspx", 
        postData,
        function(data) { suggestTitleCallback(data, container, feedbackContainer); }
    );
}

function suggestTitleCallback(data, container, feedbackContainer, titleId /* optional */, name /* optional */)
{
    showFeedback(feedbackContainer, data);
    container.empty();
    if(!$(".feedback").hasClass("error") && !window.g_keepForm)
    {
        var totalSuggestedTitlesCtrl = $('#totalSuggestedTitle');
        if(totalSuggestedTitlesCtrl.length > 0)
        {
            var totalSuggestedTitles = parseInt($('#totalSuggestedTitle').text());
            $('#totalSuggestedTitle').text(totalSuggestedTitles + 1);
        }
        if(window.clearSuggestTitleForm)
        {
            clearSuggestTitleForm();
        }    
    }
    $("input[type='submit']", container.next('div')).hide();

    if (parent.refreshList) parent.refreshList(titleId, name);
    if (window.refreshList) refreshList();
}

/*
* re-suggest a title
*/
function ReSuggestTitle
(
    titleId,
    params
) {
    var postData = { tid:titleId };

    $.post(
        _ajaxBase + "ajax/SuggestTitle.aspx",
        postData,
        function(data) { suggestTitleCallback(data, $('#place_holder'), $(params.feedbackContainer)); }
    );
}

function onRejectionReasonChanged(otherReasonCtrl, isOther)
{
    if(isOther)
    {
        $(otherReasonCtrl).show();
    }
    else
    {
        $(otherReasonCtrl).hide();
    }
}

/*
* Send selected titles for approval or rejection.
* It collects all the data to be posted for processing.
*/
function reviewSubmittedTitles(pageParams)
{   
    var inputs = $('input[name=\'titleId\']', $(pageParams.refreshContainer));
    var currentElement;
    var postData = pageParams;
    var titleId;
    var title;
    var newTitle;
    var action;
    var reason;
    var templateId;
    var price;
    var hasErrors = false;
    
    postData.tids = '';   
    $(inputs).each(
        function(i, j) {
            currentElement = $(this);
            postData.tids += currentElement.val() + ",";
            titleId = currentElement.val();
            action = $('#titleAction' + titleId).val();
            if(action == '') return;
            postData['titleAction' + titleId] = action;
            title = $('#title' + titleId).val();
            newTitle = $('#newTitle' + titleId).val();
            if(newTitle != '') postData['newTitle' + titleId] = newTitle;
            templateId = $('#template' + titleId).val();
            if(templateId != -1) postData['template' + titleId] = templateId;
            reason = $('#reason' + titleId).val();
            reasonOther = $("#reasonOther" + titleId).val();
            if(action == 'reject' && reason == "-1") 
            {
                alert("Please select a reason for rejecting \"" + title + "\"");
                hasErrors = true;
            }
            postData['reason' + titleId] = reason;
            if(reasonOther != '') postData['reasonOther' + titleId] = reasonOther;
            postData['price' + titleId] = $('.price' + titleId).val();
        }
    );
    if(hasErrors) return;
    
    postData.tids = postData.tids.replace(/,$/ig, '');
    postData.p = pageParams.currentPage;
              
    $.post(
        _ajaxBase + "ajax/ReviewSubmittedTitle.aspx", 
        postData,
        function(data) { pageParams.reviewSubmittedTitleCallback(data); } 
        
    );
}

function reviewSubmittedTitleCallback(data)
{
    var status = $("response", data).attr("status");
    
    var refresh = $("response > action[name='refresh']", data);
    if(refresh.length > 0)
    {
        if(refresh.attr("type") == 'html') $(this.refreshContainer).html(refresh.text());
        else eval(refresh.text());
    }

    var feedback = $("response > action[name='feedback']", data);
    if(feedback.length > 0) 
    {
        if(feedback.attr("type") == "html") showFeedback($(this.feedbackContainer), feedback.text());
        else eval(feedback.text());
    }
}

function checkTitleDuplicates
(
    templateId,
    title, 
    id, 
    container /* optional */,
    async /* optional */
)
{
    clearFeedback();
    if(isTitleEmpty(title))
    {
        alert("Please enter a title.");
        return;
    }
    if(templateId == -1)
    {
        alert("Please select a site.");
        return;    
    }
    var postData = {};
    if(title) postData.title = title;
    if(id) postData.tid = id;
    if(templateId) postData.template_id = templateId;
    var output = {}
    $.ajax( 
        { 
            url: _ajaxBase + "ajax/CheckDuplicates.aspx",
            async: async ? true : false,
            data: postData,
            success: function(data) { checkTitleDuplicatesCallback(data, container, output); }
        } 
    );
    if(!async) return output.hasDuplicates;
}

function checkTitleDuplicatesCallback(data, container, output)
{
    var status = $("response", data).attr("status");
    if(status != "ok") return;

    var hasDuplicates = $("response hasDuplicates", data).text() == "true";    
    if(container) 
    {
        container.html($("response similarTitles", data).text());
        if(!hasDuplicates) $("#submitTitle", container.parent()).show();
        else $("#submitTitle", container.parent()).hide();
    }
    output.hasDuplicates = hasDuplicates;
}

function claimTitle(titleId, title, pageParams)
{
    if(!confirm("Are you sure you want to claim \"" + title + "\"?")) return;
    
    var postData = pageParams;
    postData.tid = titleId;
    postData.p = pageParams.currentPage;
   
    $.post(_ajaxBase + "ajax/ClaimTitle.aspx", 
            postData,
            function(data) { pageParams.claimCallback(data); } 
    );    
}

function claimTitleCallback(data)
{
    var status = $("response", data).attr("status");
    if(status == 'ok')
    {
        var refresh = $("response > action[name='refresh']", data);
        if(refresh.attr("type") == 'html') $(this.refreshContainer).html(refresh.text());
        else eval(refresh.text());
        //update the assignments acount if there
        $("#number_of_assignments").text(parseInt($("#number_of_assignments").text()) + 1);            
    }
    var feedback = $("response > action[name='feedback']", data);
    if(feedback) 
    {
        if(feedback.attr("type") == "html") $(this.feedbackContainer).replaceWith(feedback.text());
        else eval(feedback.text());
    }
    window.location.hash = "#feedback_anchor";
}

function checkInTitle(titleId, title, pageParams)
{
    if(!confirm("Are you sure you want to delete \"" + title + "\" from your assignments?")) return;
    
    var postData = pageParams;   
    postData.tid = titleId;
    postData.p = postData.currentPage;
    
    $.post(_ajaxBase + "ajax/CheckInTitle.aspx", 
            postData,
            function(data) { pageParams.checkInCallback(data); } 
    ); 
}

function checkInTitleCallback(data)
{
    var status = $("response", data).attr("status");
    if(status == 'ok')
    {
        var refresh = $("response > action[name='refresh']", data);
        if(refresh.attr("type") == 'html') $(this.refreshContainer).html(refresh.text());
        else eval(refresh.text());
    }
    var feedback = $("response > action[name='feedback']", data);
    if(feedback) 
    {
        if(feedback.attr("type") == "html") $(this.feedbackContainer).replaceWith(feedback.text());
        else eval(feedback.text());
    }
}

function deleteTitle(titleId, title, pageParams /* by page to decide callbak, etc */)
{
    if(!confirm("Are you sure to delete \"" + title + "\" ?")) return;
    var postData = pageParams;    
    postData.tid = titleId;
    postData.p = postData.currentPage;
    $.post(
        _ajaxBase + "ajax/DeleteTitle.aspx",
        postData,
        function(data) { pageParams.deleteCallback(data); }
    )
}

function deleteSuggestedTitle(titleId, title, pageParams /* by page to decide callbak, etc */) {
    if (!confirm("Are you sure to delete \"" + title + "\" ?")) return;
    var postData = pageParams;
    postData.tid = titleId;
    postData.p = postData.currentPage;
    $.post(
        _ajaxBase + "ajax/DeleteSuggestedTitle.aspx",
        postData,
        function(data) { pageParams.deleteCallback(data); }
    )
}

function deleteTitleCallback(data)
{
    var status = $("response", data).attr("status");
    if(status == 'ok')
    {
        var refresh = $("response > action[name='refresh']", data);
        if(refresh.attr("type") == 'html') $(this.refreshContainer).html(refresh.text());
        else eval(refresh.text());
    }
    var feedback = $("response > action[name='feedback']", data);
    if(feedback) 
    {
        if(feedback.attr("type") == "html") showFeedback($(this.feedbackContainer), feedback.text());
        else eval(feedback.text());
    }
}

function getPage(page)
{
    var pageParams = this;
    var postData = this;
    postData.p = page;
    
    $.post(
            this.pageAjaxHandler,
            postData,
            function(data) { pageParams.pageCallback(data); }
    )
}

function pageCallback(data)
{
    $(this.refreshContainer).html(data);
    this.currentPage = this.p;
}

function sortResult(target)
{
    this.sortBy = $(target).attr("id");
    if($(target).hasClass("asc"))
    {
        this.sortOrder = "desc";
        $(target).removeClass("asc");
        $(target).addClass("desc");
    }
    else
    {
        this.sortOrder = "asc";
        $(target).addClass("asc");
        $(target).removeClass("desc");
    }
    var pageParams = this;
    var postData = this;
    postData.p = this.currentPage;
    
    $.post(
            this.sortAjaxHandler,
            postData,
            function(data) { pageParams.sortCallback(data); }
    )
}

function sortResultCallback(data)
{
    $(this.refreshContainer).html(data);
}

function leadSortResult(target)
{
    this.sort = $(target).attr("id");
    
    if($(target).hasClass("asc"))
    {
        this.direction = "0";
        $(target).removeClass("asc");
        $(target).addClass("desc");
    }
    else
    {
        this.direction = "1";
        $(target).addClass("asc");
        $(target).removeClass("desc");
    }
    var pageParams = this;
    var postData = this;
    
    $.post(
            this.sortAjaxHandler,
            postData,
            function(data) { pageParams.sortCallback(data); }
    )
}

function leadSortResultCallback(data)
{
    $(this.refreshContainer).html(data);
}

function leadPageResult(page)
{
    this.page_no = page;    
    var pageParams = this;
    var postData = this;
    
    $.post(
            this.pageAjaxHandler,
            postData,
            function(data) { pageParams.pageCallback(data); }
    )
}

function leadPageResultCallback(data)
{
    $(this.refreshContainer).html(data);
}

//prevent a title from showing up in a user's reviewable titles queue
function blockTitles(pageParams, container)
{
    pageParams.titles = [];
    $("input.title_ids", $(container)).each(
        function(i) { pageParams.titles.push(this.value); }
    );
    if(pageParams.titles.length <= 0) return;
    
    pageParams.titles = pageParams.titles.join(",");
    
    $.post(
            _ajaxBase + "ajax/BlockTitles.aspx",
            pageParams,
            function(data) { pageParams.blockCallback(data); }
    );            
}

function blockTitlesCallback(data)
{
    $(this.refreshContainer).html(data);
}

//call the publishing tool to get an article id for a title
//and  then bring the user to the "writing an article" page
//aid = assignment id
function writeArticle(assignmentId, container)
{
    var postData = {};
    postData.aid = assignmentId;
    $.post(
        _ajaxBase + "ajax/WriteArticle.aspx",
        postData,
        function(data) { writeArticleCallback(data, container); }
    ); 
}

function writeArticleCallback(data, container)
{
    var status = $("response", data).attr("status");
    if(status == "ok")
    {
        var articleId = parseInt($("response articleId", data).text());
        if(articleId != -1)
        {
            window.location.href = _publishingGateway + "/write/" + articleId;
        }
        var categoryPicker = $("response category", data).text();
        var targetContainer = $(container).parents('tr').next('tr');
        if(targetContainer) 
        {
            targetContainer.html(categoryPicker);
            targetContainer.addClass("expand");
        }        
    }
    else
    {
        showJSFeedback($("response action", data).text());
    }
}

function continueWriteArticle(assignmentId, categoryPrefix)
{
    var categoryIds = [];
    var categoryCtrl;
    
    for(var i = 1; ; i++)
    {
        categoryCtrl = $('#' + categoryPrefix + i);
        if(categoryCtrl.length == 0) break;
        categoryIds.push(categoryCtrl.val());                    
    }
    
    var postData = { categories:categoryIds.join(',') };
    postData.aid = assignmentId;
    
    $.post(
        _ajaxBase + "ajax/WriteArticle.aspx",
        postData,
        function(data) { continueWriteArticleCallback(data); }
    );
}

function continueWriteArticleCallback(data)
{
    var status = $("response", data).attr("status");
    if(status == "ok")
    {
        var articleId = parseInt($("response articleId", data).text());
        window.location.href = _publishingGateway + "/write/" + articleId;
    }
    else
    {
        showJSFeedback($("response > action", data).text());
    }
}

function cancelWriteArticle(container)
{
    $(container).parents("tr").removeClass("expand");
}

function alterCategories(userAssignmentId, categoryPrefix, container)
{
    var postData = {};
    postData.aid = userAssignmentId;
        
    var categoryIds = [];
    var categoryCtrl;
    for(var i = 1; ; i++)
    {
        categoryCtrl = $('#' + categoryPrefix + i);
        if(categoryCtrl.length == 0) break;
        categoryIds.push(categoryCtrl.val());
    }
    
    postData.categories = categoryIds.join(",");
    
    $.post(
        _ajaxBase + "ajax/UpdateSubCategories.aspx",
        postData,
        function(data) { alterCategoriesCallback(data, container); }
    )
}

function alterCategoriesCallback(data, container)
{
    container.html(data);
}

function deleteUserAssignment(userAssignmentId, pageParams)
{
    var postData = pageParams;
    postData.aid = userAssignmentId;
    $.post(
        _ajaxBase + "ajax/DeleteUserAssignment.aspx",
        postData,
        function(data) { pageParams.deleteUserAssignmentCallback(data); }
    )
}

function deleteUserAssignmentCallback(data)
{
    var status = $("response", data).attr("status");
    if(status == 'ok')
    {
        var refresh = $("response > action[name='refresh']", data);
        if(refresh.attr("type") == 'html') $(this.refreshContainer).html(refresh.text());
        else eval(refresh.text());
    }
    var feedback = $("response > action[name='feedback']", data);
    if(feedback) 
    {
        if(feedback.attr("type") == "html") showFeedback($(this.feedbackContainer), feedback.text());
        else eval(feedback.text());
    }
}

//Put selected articles into the review queue
//of the current user
function reviewArticles(articleIdContainers, reviewingParams, reviewableParams)
{
    var postData = {};
    postData.aids = [];
    articleIdContainers.each(function(i) { postData.aids.push(articleIdContainers[i].value); } );
    postData.aids = postData.aids.join(',');
    
    $.post(
        _ajaxBase + "ajax/ReviewArticle.aspx",
        postData,
        function(data) { reviewArticlesCallback(data, reviewingParams, reviewableParams); }
    )
}

function reviewArticlesCallback(data, reviewingParams, reviewableParams)
{
    var node;
    var reviewingArticlesNode = $("response action[name='reviewing_articles']", data);
    var reviewableArticlesNode = $("response action[name='reviewable_articles']", data);
    var feedbackNode = $("response action[name='feedback']", data);
    if(reviewingArticlesNode.length > 0) 
    {
        $(reviewingParams.refreshContainer).html(reviewingArticles.text());
    }
    if(reviewableArticlesNode.length > 0) 
    {
        $(reviewableParams.refreshContainer).html(reviewableArticles.text());
    }
    if(feedbackNode.length > 0) 
    {
        if(feedbackNode.attr("type") == "html") 
        {
            $(reviewableParams.feedbackContainer).replaceWith(feedbackNode.text());
        }
        else 
        {
            eval(feedbackNode.text());
            eval(feedback[0]);
        }
    }
}

//Put the selected article into the review
function reviewArticle(articleId)
{
    var postData = {};
    postData.aids = [];
    postData.aids = articleId;
    
    $.post(
        _ajaxBase + "ajax/ReviewArticle.aspx",
        postData,
        function(data) { reviewArticleCallback(data); }
    )
}

function reviewArticleCallback(data)
{
    var feedbackNode = $("response action[name='feedback']", data);
    if(feedbackNode.length > 0) 
    {
        if(feedbackNode.attr("type") == "html") 
        {
            showFeedback($('.feedback'), feedbackNode.text());
        }
        else 
        {
            eval(feedbackNode.text());
            eval(feedback[0]);
        }
    }
}

function getTemplatesForSite(siteId, container)
{
    $.post(
        _ajaxBase + "ajax/GetTemplatesForSite.aspx",
        { site : siteId },
        function(data) { getTemplatesForSiteCallback(data, container); }
    );
}

function getTemplatesForSiteCallback(data, container)
{
    container.html(data);
    container[0].selectedIndex = 0;
}

/*
* The names are obsolete. 
* Retrive/show/hide information needed to approve a suggested title,
* including templates and prices.
*/
function getTemplatesForTitle(titleId, container)
{
    $.post(
        _ajaxBase + "ajax/GetTemplatesForTitle.aspx",
        { tid: titleId },
        function(data) { getTemplatesForTitleCallback(data, container); }
    );
}

function getTemplatesForTitleCallback(data, container)
{
    $(container).html(data);
}

function cancelTemplate(cancelCtrl)
{
    var container;
    //The row that contains "chooseTemplate"
    container = $(cancelCtrl).parents(".chooseTemplate");
    container.removeClass("expand");
    //The row that contains the "approve/reject" buttons    
    container = container.prev("tr").prev("tr");
    $(".action", container).removeAttr("value");
    $(".approve", container).attr("src", "../images/approve_gray.gif");
    $(".reject", container).css("display","inline");
}

function onTemplateChanged(selectObj)
{
    var selectedTemplateId = $(selectObj).val();
    $(':input:text').val($('.defaultPrice' + selectedTemplateId).val());
}

function initReviewTitleJS()
{
    $(".approve").click(
        function() { 
            var ct = $(".approve").index(this);
            getTemplatesForTitle($(this).nextAll('.titleId').val(), $($(this).parents('tr').nextAll('.chooseTemplate').get(0))); 
            $(".chooseTemplate").eq(ct).addClass("expand");
	        $(".action").eq(ct).val("approve");
            $(".approve").eq(ct).attr("src","../images/approve.gif");
            $(".reject").eq(ct).css("display","none");
        }
    );
    $(".reject").click(function() {
	    $(".hiddenInfo").eq($(".reject").index(this)).addClass("expand");
	    $(".action").eq($(".reject").index(this)).val("reject");
	    $(this).css("margin-left","18px");
		$(this).attr("src","../images/deny.gif");
	    $(".approve").eq($(".reject").index(this)).css("display","none");
    });
    $(".cancel").click(function() {
		var r = $(".cancel").index(this); 
		var dd = $(".reason").get(r); 
		dd.selectedIndex = 0;
	    $(".action").eq($(".cancel").index(this)).removeAttr("value");
	    $(".hiddenInfo").eq($(".cancel").index(this)).removeClass("expand");
	    $(".reject").eq($(".cancel").index(this)).css("margin-left","0");
		$(".reject").eq($(".cancel").index(this)).attr("src","../images/deny_gray.gif");
	    $(".approve").eq($(".cancel").index(this)).css("display","inline");
    });
    $(".titleEdit").click(function() {
        if($(".edit").length != 0) return;
	    $(this).addClass("edit");
    });
    $(".titleEdit").blur(function(event) {   
	    $(this).next().val($(this).val());
	    
	    var titleId = $(this).parent().prev("td").children(".titleId").val();
	    var siteId = $(this).parent().prev("td").children(".siteId").val();
	    var hasDuplicates = checkTitleDuplicates(siteId, $(this).val(), titleId, null, false);
	    if(!hasDuplicates) 
	    {
	        $(this).removeClass("edit");
	    }
	    else
	    {
	        alert("Duplicates found.");
	        //To fight FF bug
	        var id = $(this).attr("id");
	        setTimeout(function() { $("#" + id)[0].focus(); }, 1);
	    }
    });
	$(".titleEdit").keyup(function() {
		if (this.value.length > 100) {
			this.value = this.value.substr(0,100);
		}
	});
}

function initShowCategories()
{
    $(".write").click(function() {
	    $(".hiddenInfo").eq($(".write").index(this)).addClass("expand");
    });
    $(".cancel").click(function() {
		var c = $(".cancel").index(this); 
		var sc = $(".SubCat").get(c); 
		var ssc = $(".SubSubCat").get(c); 
		sc.selectedIndex = 0;
		ssc.selectedIndex = 0;
	    $(".hiddenInfo").eq($(".cancel").index(this)).removeClass("expand");
    });
}

function delUserCategory
(
    userId, 
    categoryId,
    count
)
{
    var postParameters = {};
    postParameters.uid= userId;
    postParameters.cid = categoryId;
    container = $("#userCategories");
    container.empty();
    
    $.post(_ajaxBase + "ajax/DeleteUserCategory.aspx", 
            postParameters, 
            function(data) { delUserCategoryCallback(data, container); }
            );
}

function delUserCategoryCallback(data, container)
{
    container.html(data);
}

function insUserCategory
(
    userId, 
    categoryId
)
{
    var postParameters = {};
    postParameters.uid= userId;
    postParameters.cid = categoryId;
    container = $("#userCategories");
    container.empty();
    
    $.post(_ajaxBase + "ajax/InsertUserCategory.aspx", 
            postParameters, 
            function(data) { insUserCategoryCallback(data, container); }
            );
}

function insUserCategoryCallback(data, container)
{
    container.html(data);
}

function searchLeadResult()
{
    var pageParams = this;
    var postData = this;
    $.getJSON(this.searchAjaxHandler, postData, pageParams.searchCallback);
}

function searchLeadResultCallback(data)
{
    var leadId = parseInt(data.LeadId, 10);
    
    if (leadId > 0)
    {
        window.location = data.WebBase + "admin/manage-users.aspx?lid=" + leadId;
    }
    else
    {
        var htmlText = unescape(data.Html);
        htmlText = htmlText.replace(/\+/g, " ");
        var searchContainer = document.getElementById("SearchLeadContainer");
        searchContainer.innerHTML = htmlText;
    }
}   

function manageContent()
{
    var pageParams = this;
    var postData = this;
    
    $.post(
            this.manageContentAjaxHandler,
            postData,
            function(data) { pageParams.manageContentCallback(data); }
    )
}

function manageContentCallback(data)
{
    $(this.refreshContainer).html(data);
}

function showFeedback
(
    feedbackContainer, /* jQuery object */
    data /* html to display */
)
{
    if(feedbackContainer.length == 0) return;
    
    var firstItem = $(feedbackContainer[0]);
    firstItem.nextAll().remove();
    firstItem.empty();
    firstItem.replaceWith(data);
}

function showJSFeedback
(
    data /* JavaScript containing the error messages */
)
{
    eval(data);
    if(!feedback) return;
    
    for(var i = 0; i < feedback.length; i++) alert(feedback[i]);
}

function clearFeedback()
{
    $('.feedback').empty();
    $('.feedback').hide();
}

function processQualityReview(id, pageParams)
{
    var postData = pageParams;
    postData.qid = id;
    $.post(
        _ajaxBase + "ajax/UpdateQualityReview.aspx",
        postData,
        function(data) { pageParams.processQualityReviewCallback(data); }
    );        
}

function saveQualityReviewChanges(qualityReviewId, userId, rating, maximumTitles, maximumTitlesOther, notes)
{
    var postData = {};
    postData.qid = qualityReviewId;
    postData.uid = userId;
    postData.rating = rating;
    postData.maximumTitles = maximumTitles;
    postData.maximumTitlesOther = maximumTitlesOther;
    postData.notes = notes || '';
    
    $.post(
        _ajaxBase + "ajax/SaveQualityReviewChanges.aspx",
        postData,
        function(data) { saveQualityReviewChangesCallback(data); }
    );
}

function saveQualityReviewChangesCallback(data)
{
    if(parent.refreshList) parent.refreshList();
    tb_remove();
}

function processQualityReviewCallback(data)
{
    var status = $("response", data).attr("status");
    
    var refresh = $("response > action[name='refresh']", data);
    if(refresh.length > 0)
    {
        if(refresh.attr("type") == 'html') $(this.refreshContainer).html(refresh.text());
        else eval(refresh.text());
    }

    var feedback = $("response > action[name='feedback']", data);
    if(feedback.length > 0) 
    {
        if(feedback.attr("type") == "html") showFeedback($(this.feedbackContainer), feedback.text());
        else eval(feedback.text());
    }
}

function GetQualityReviewSamples(articleId, sampleSize, container)
{
    var postData = {};
    postData.aid = articleId;
    postData.sampleSize = sampleSize;
    
    $.post(
        _ajaxBase + "ajax/GetQualityReviewSamples.aspx",
        postData,
        function(data) { GetQualityReviewSamplesCallback(data, container); }
    );
}

function GetQualityReviewSamplesCallback(data, container)
{
    $('div', $(container)).html(data);
    $(container).show();
    $('a.sample').click(
        function() {
            $('iframe').attr('src', $(this).next(':input').val());
        }
    );
}

/*
* Workflow histories
*/
function getTitleHistories(titleId, container)
{
    var postData = {};
    postData.tid = titleId;
    $.post(
        _ajaxBase + "ajax/GetTitleHistories.aspx",
        postData,
        function(data) { getTitleHistoriesCallback(data, container); }
    );
}

/*
* Revisions
*/
function getTitleRevisions(titleId, container)
{
    var postData = {};
    postData.tid = titleId;
    $.post(
        _ajaxBase + "ajax/GetTitleRevisions.aspx",
        postData,
        function(data) { getTitleHistoriesCallback(data, container); }
    );
}

/*
* Shared between workflow histories and revision histories
*/
function getTitleHistoriesCallback(data, container)
{
    container.html(data);
}

function closeTitleHistory(container)
{
    container.html(' ');
}

function getViewPortDimension()
{
    var viewPortWidth;
    var viewPortHeight;
     
    // the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
    if (typeof window.innerWidth != 'undefined')
    {
        viewPortWidth = window.innerWidth,
        viewPortHeight = window.innerHeight
    }
    // IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
    else if (typeof document.documentElement != 'undefined'
                && typeof document.documentElement.clientWidth != 'undefined' 
                && document.documentElement.clientWidth != 0)
    {
        viewPortWidth = document.documentElement.clientWidth,
        viewPortHeight = document.documentElement.clientHeight
    }
    // older versions of IE
    else
    {
        viewPortWidth = document.getElementsByTagName('body')[0].clientWidth,
        viewPortHeight = document.getElementsByTagName('body')[0].clientHeight
    }
    return { width:viewPortWidth, height:viewPortHeight };
}

function acceptPlagiarismAppeal(articleId)
{
    var postData = {};
    postData.aid = articleId;
    $.post(
        _ajaxBase + "ajax/AcceptPlagiarismAppeal.aspx",
        postData,
        function(data) { alert(data); }
    );
}