window.getCol = function(col)
{
    if(col.type == 'story')
    {
        col.title = col.title + ' (' + col.end + ')';

        return $.extend({contentClass: 'shadown-sm', content: function(info)
        {
            let workhour     = 0;
            let requirements = [];
            for(let i in info.items)
            {
                workhour += parseInt(info.items[i].estimate);
                if(info.items[i].requirement != undefined && info.items[i].requirement.story) requirements[info.items[i].requirement.story] = info.items[i].requirement;
            }

            let extendHtml =
            `
              <div class='relative'>
                <div class='flex px-2 workhour'>
                  <div class='cell py-2 px-1 flex-1 row'>
                    <div class='flex-1 center'>${workloadLabel}</div>
                    <div class='flex-1 center'>${workhour}${hourUnit}</div>
                  </div>
                  <div class='cell py-2 px-1 flex-1 row'>
                    <div class='flex-1 center'>${capacityLabel}</div>
                    <div class='flex-1 capacity center border' data-column='${col.id}'>${col.capacity}${hourUnit}</div>
                  </div>
                </div>
            `;

            let requirementHTML = '';
            for(let i in requirements) requirementHTML += "<div class='border-b p-2'><div class='flex items-center'><span class='bg-special text-white mr-1 mb-1 px-1 rounded-lg'><i class='icon icon-lightbulb'></i></span><span class='text-special'>特性<span></div><div class='ellipsis' title='" + requirements[i].title + "'>" + requirements[i].title + "</div></div>";

            extendHtml += "<div class='h-5'><div class='requirement absolute left-0 right-0 top-10 bg-white'><div class='content hidden'>" + requirementHTML + "</div><div class='center p-1'><i class='icon icon-chevron-double-down scale-75' style='cursor:pointer'></i></div></div></div></div>";

            return {html: extendHtml};
        }}, col);
    }

    return $.extend({attrs: {id : col.id}}, col);  // 风险和目标列
}

window.getLane = function(lane)
{
    if(teamID > 0) lane.minHeight = window.innerHeight - 235;
}

window.getColActions = function(col)
{
    if(col.type == 'story')
    {
        if(!privs.canCreateStory && !privs.canLinkStory) return false;

        return [{
            type: 'dropdown',
            icon: 'expand-alt text-primary',
            caret: false,
            items: [
                privs.canCreateStory ? {text: createStory, icon: 'plus', url: $.createLink('story', 'create', 'product=' + product + '&branch=0&moduleID=0&storyID=0&objectID=0&bugID=0&planID=0&todoID=0&extra=&storyType=story&piID=' + piID + '&columnID=' + col.id), 'data-toggle': 'iframeModal', 'data-size' : 'lg'} : null,
                privs.canLinkStory   ? {text: linkStory, icon: 'link', url: $.createLink('pi', 'linkStory', 'piID=' + piID + '&columnID=' + col.id), 'data-toggle': 'modal', 'data-size' : 'lg'} : null,
            ],
        }];
    }
    else if(col.type == 'risk')
    {
        if(!privs.canCreateRisk) return false;

        return [{
            type: 'dropdown',
            icon: 'expand-alt text-primary',
            caret: false,
            items: [
                privs.canCreateRisk ? {text: riskLang.create, icon: 'plus', url: $.createLink('risk', 'create', 'projectID=0&from=pi&colID=' + col.id), 'data-toggle': 'modal'} : null,
            ],
        }];
    }
    else if((col.type == 'yes' || col.type == 'no') && col.parentName)
    {
        if(!privs.canCreateObjective) return false;

        return [{
            icon: 'expand-alt text-primary',
            url : $.createLink('objective', 'create', 'piID=' + piID + '&laneID=0&columnID=' + col.parentName + '&promise=' + col.type),
            'data-toggle': 'modal',
        }];
    }
}

window.getItemActions = function(item)
{
    if(item.type == 'story')
    {
        if(!privs.canUnlinkStory) return false;

        return [{
            type: 'dropdown',
            icon: 'ellipsis-v text-primary',
            caret: false,
            items: [{text: unlinkStory, icon: 'unlink', url: $.createLink('pi', 'unlinkStory', 'piID=' + piID + '&columnID=' + item.col + '&laneID=' + item.lane + '&storyID=' + item.cardID), 'data-confirm': confirmUnlink, innerClass: 'ajax-submit'}],
        }];
    }
    else if(item.type == 'risk')
    {
        return [{
            type  : 'dropdown',
            icon  : 'ellipsis-v text-primary',
            caret : false,
            items : buildRiskActions(item)
        }];
    }
    else if(item.type == 'objective')
    {
        if(!privs.canEditObjective && !privs.canDeleteObjective) return false;

        return [{
            type: 'dropdown',
            icon: 'ellipsis-v text-primary',
            caret: false,
            items: [
                privs.canEditObjective   ? {text: editObjective,   icon: 'edit',  url: $.createLink('objective', 'edit',   'objectiveID=' + item.name + '&laneID=' + item.lane + '&columnID=' + item.col), 'data-toggle': 'modal'} : false,
                privs.canDeleteObjective ? {text: deleteObjective, icon: 'trash', url: $.createLink('objective', 'delete', 'objectiveID=' + item.name + '&laneID=' + item.lane + '&columnID=' + item.col), 'data-confirm': confirmDelete, innerClass: 'ajax-submit'} : false
            ],
        }];
    }
}

window.getItem = function(info)
{
    info.item.titleAttrs = {'title' : info.item.title}; // title的属性
    if(info.item.type == 'story')
    {
        if(privs.canViewStory)
        {
            info.item.titleUrl   = $.createLink('story', 'view', 'storyID=' + info.item.name); // title的链接
            info.item.titleAttrs = {'data-toggle' : 'modal', 'data-size': 'lg', "className" : 'open-in-parent card-title', 'title': info.item.title}; // title的属性
        }

        info.item.icon = 'product';
        let avatar = "<span class='avatar rounded-full size-xs ml-1 " + (info.item.uavatar ? 'primary' : 'bg-lighter text-canvas') + "'>" + (info.item.uavatar ? info.item.uavatar : "<i class='icon icon-person'></i>");
        if(privs.canAssignToStory) avatar = "<a href='" + $.createLink('story', 'assignTo', 'storyID=' + info.item.name + '&kanbanGroup=default&from=&storyType=story&columnID=' + info.item.col) + "' data-toggle='iframeModal'>" + avatar + "</a>";
        info.item.footer     = {html: "<div class='flex items-center'><span class='pri-" + info.item.pri + "'>" + info.item.pri + "</span><span class='text-sm ml-2 mr-1'>" + estimateLang + "</span><span class='text-sm'>" + info.item.estimate + hourUnit +"</span><div class='flex-1 flex justify-end'><span class='status-" + info.item.status + "'>" + info.item.statusLabel + "</span>" + avatar + "</div></div>"};
    }
    else if(info.item.type == 'risk')
    {
        if(privs.canViewRisk)
        {
            info.item.titleUrl   = $.createLink('risk', 'view', 'id=' + info.item.name + '&from=pi'); // title的链接
            info.item.titleAttrs = {'data-toggle' : 'modal', 'data-size' : 'lg', 'title' : info.item.title}; // title的属性
        }

        info.item.content     = info.item.strategy ? {html: '<div class="flex items-center"><span class="text-sm mr-1 text-mute">' + riskLang.strategy + '</span><span class="text-sm">' + riskLang.strategyList[info.item.strategy] + '</span></div>'} : {html: '<div class="flex items-center"><span class="text-sm mr-1 text-mute">' + riskLang.strategy + '</span></div>'};
        info.item.footer      = riskLang.statusList[info.item.status];
        info.item.footer      = {html: `<div class='flex items-center'><span class='text-sm mr-1 text-mute'>${riskLang.rate}</span><span class='text-sm'>${info.item.rate}</span>` + "<div class='flex-1 flex justify-end'><span class='status-" + info.item.status + "'>" + riskLang.statusList[info.item.status] + "</span></div></div>"};
    }
    else if (info.item.type == 'objective')
    {
        info.item.prefix      = ' ';
        info.item.prefixClass = "label label-dot " + (info.colInfo.type == 'yes' ? 'success' : 'light') + " mr-2 mt-1";
        info.item.footer      = {html: "<div class='flex items-center'><span class='text-sm'>BV</span><span class='text-primary ml-1 mr-4'>" + info.item.BV + "</span><span class='text-sm'>AV</span><span class='text-primary ml-1'>" + info.item.AV + "</span></div>"}
    }
}

/* 拼接风险卡片的操作按钮。 */
window.buildRiskActions = function(risk)
{
    let actions = [];

    if(privs.canEditRisk) actions.push({icon : 'edit', text : riskLang.edit, url : $.createLink('risk', 'edit', "riskID=" + risk.name + '&from=pi&colID=' + risk.col), 'data-toggle' : 'modal', 'data-size' : 'lg'});
    if(privs.canCloseRisk && risk.status != 'closed')    actions.push({icon : 'off',   text : riskLang.close + riskLang.common,    url : $.createLink('risk', 'close', "riskID=" + risk.name + '&colID=' + risk.col),    'data-toggle'  : 'modal', 'data-size' : 'lg'});
    if(privs.canActivateRisk && risk.status != 'active') actions.push({icon : 'magic', text : riskLang.activate + riskLang.common, url : $.createLink('risk', 'activate', "riskID=" + risk.name + '&colID=' + risk.col), 'data-toggle'  : 'modal', 'data-size' : 'lg'});
    if(privs.canDeleteRisk) actions.push({icon : 'trash', text : riskLang.delete + riskLang.common, url : $.createLink('risk', 'delete', "riskID=" + risk.name + '&laneID=' + risk.lane + '&colID=' + risk.col), 'data-confirm' : riskLang.confirmDelete, 'innerClass' : 'ajax-submit'});

    return actions;
}

// 监听产能的双击事件，双击后将内容变化输入框。
$(document).off('click', '.capacity').on('click', '.capacity', function()
{
    if(!$(this).find('[name=capacity]').length && privs.canSetCapacity)
    {
        const capacity = $(this).text().replace(hourUnit, '');
        $(this).html('<input type="number" style="width:50px;text-align:center" min="0" name="capacity" value="' + capacity + '" />');
    }
});

// 监听产能的输入框的失去焦点事件，失去焦点后将输入框的内容变为文本。
$(document).off('blur', '[name=capacity]').on('blur', '[name=capacity]', function()
{
    // 限制输入的最大长度为8位。
    if($(this).val().length > 8) $(this).val($(this).val().substr(0, 8));
    if($(this).val() < 0 || !$(this).val()) $(this).val(0);

    const url  = $.createLink('pi', 'setCapacity', 'columnID=' + $(this).closest('.capacity').data('column'));
    const form = new FormData();
    form.append('capacity', $(this).val());
    if(privs.canSetCapacity) $.ajaxSubmit({url, data:form});

    const workhour   = $(this).closest('.flex').find('.workhour').text().replace(hourUnit, '');
    const workload   = $(this).val() > 0 ? (workhour / $(this).val() * 100).toFixed(): 0;
    const extraClass = workload > 100 ? 'text-danger' : 'text-success';

    $(this).closest('.flex').find('.workload').attr('class', 'workload ' + extraClass).text(workload + '%');
    $(this).parent().html(parseFloat($(this).val()) + hourUnit);
});

$(document).off('click', '.icon-chevron-double-down,.icon-chevron-double-up').on('click', '.icon-chevron-double-down,.icon-chevron-double-up', function()
{
    $(this).closest('.requirement').find('.content').toggleClass('hidden');
    $(this).toggleClass('icon-chevron-double-down icon-chevron-double-up');
});
