@model Disco.Web.Models.Job.ShowModel
@{
    Authorization.RequireAny(Claims.Job.ShowLogs, Claims.Job.ShowAttachments);

    var canShowLogs = Authorization.Has(Claims.Job.ShowLogs);
    var canShowAttachments = Authorization.Has(Claims.Job.ShowAttachments);

    var canAddLogs = Authorization.Has(Claims.Job.Actions.AddLogs);
    var canRemoveAnyLogs = Authorization.Has(Claims.Job.Actions.RemoveAnyLogs);
    var canRemoveOwnLogs = Authorization.Has(Claims.Job.Actions.RemoveOwnLogs);

    var canAddAttachments = Authorization.Has(Claims.Job.Actions.AddAttachments);
    var canRemoveAnyAttachments = Authorization.Has(Claims.Job.Actions.RemoveAnyAttachments);
    var canRemoveOwnAttachments = Authorization.Has(Claims.Job.Actions.RemoveOwnAttachments);

    if (canShowAttachments)
    {
        Html.BundleDeferred("~/Style/Shadowbox");
        Html.BundleDeferred("~/ClientScripts/Modules/Shadowbox");
    }
    if (canAddAttachments)
    {
        Html.BundleDeferred("~/ClientScripts/Modules/Disco-AttachmentUploader");
    }
    Html.BundleDeferred("~/ClientScripts/Modules/jQuery-SignalR");
}
<table id="jobShowResources">
    <tr class="@(canShowLogs ? "canShowLogs" : "cannotShowLogs") @(canShowAttachments ? "canShowAttachments" : "cannotShowAttachments")">
        @if (canShowLogs)
        {
            <td id="CommentsContainer">
                <div id="Comments" class="@(canAddLogs ? "canAddLogs" : "cannotAddLogs")">
                    <div class="commentOutput">
                        @foreach (var jl in Model.Job.JobLogs.OrderBy(m => m.Timestamp))
                        {
                            <div data-logid="@jl.Id">
                                <span class="author">@jl.TechUser.ToStringFriendly()</span>@if (canRemoveAnyLogs || (canRemoveOwnLogs && jl.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
                                                                                           {<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(jl.Timestamp.ToUnixEpoc())" title="@jl.Timestamp.ToFullDateTime()">@jl.Timestamp.ToFullDateTime()</span>
                                <div class="comment">@jl.Comments.ToHtmlComment()</div>
                            </div>
                        }
                    </div>
                    @if (canAddLogs)
                    {
                        <div class="commentInput clearfix">
                            <textarea class="commentInput" placeholder="write comment..." accesskey="l"></textarea>
                            <span class="action post commentInputPost fa fa-comment disabled" title="Post Comment"></span>
                        </div>
                    }
                </div>
            </td>
        }
        @if (canShowAttachments)
        {
            <td id="AttachmentsContainer">
                <div id="Attachments" class="@(canAddAttachments ? "canAddAttachments" : "cannotAddAttachments")" data-uploadurl="@(Url.Action(MVC.API.Job.AttachmentUpload(Model.Job.Id, null)))">
                    @Html.AntiForgeryToken()
                    <div class="Disco-AttachmentUpload-DropTarget">
                        <h2>Drop Attachments Here</h2>
                    </div>
                    <div class="attachmentOutput">
                        @foreach (var ja in Model.Job.JobAttachments.OrderByDescending(a => a.Id))
                        {
                            <a href="@Url.Action(MVC.API.Job.AttachmentDownload(ja.Id))" data-attachmentid="@ja.Id" data-mimetype="@ja.MimeType">
                                <span class="icon" title="@ja.Filename">
                                    <img alt="Attachment Thumbnail" src="@(Url.Action(MVC.API.Job.AttachmentThumbnail(ja.Id)))" />
                                </span>
                                <span class="comments" title="@ja.Comments">
                                    @{if (!string.IsNullOrEmpty(ja.DocumentTemplateId))
                                        { @ja.DocumentTemplate.Description}
                                    else
                                    { @(ja.Comments ?? ja.Filename) }}
                                </span><span class="author">@ja.TechUser.ToStringFriendly()</span>@if (canRemoveAnyAttachments || (canRemoveOwnAttachments && ja.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)))
                                {<text><span class="remove fa fa-times-circle"></span></text>}<span class="timestamp" data-livestamp="@(ja.Timestamp.ToUnixEpoc())" title="@ja.Timestamp.ToFullDateTime()">@ja.Timestamp.ToFullDateTime()</span>
                            </a>
                        }
                    </div>
                    @if (canAddAttachments)
                    {
                        <div class="Disco-AttachmentUpload-Progress"></div>
                        <div class="attachmentInput clearfix">
                            <span class="action enabled upload fa fa-upload disabled" title="Attach File"></span><span class="action enabled photo fa fa-camera disabled" title="Capture Image"></span>
                        </div>
                    }
                </div>
            </td>
        }
    </tr>
</table>
@if (canShowLogs && (canRemoveAnyLogs || canRemoveOwnLogs))
{
    <div id="dialogRemoveLog" class="dialog" title="Remove this Comment?">
        <p>
            <i class="fa fa-exclamation-triangle fa-lg"></i>&nbsp;Are you sure?
        </p>
    </div>
}
@if (canShowAttachments && (canRemoveAnyAttachments || canRemoveOwnAttachments))
{
    <div id="dialogRemoveAttachment" class="dialog" title="Remove this Attachment?">
        <p>
            <i class="fa fa-exclamation-triangle fa-lg"></i>&nbsp;Are you sure?
        </p>
    </div>
}
@if (canShowLogs)
{
    <script>
        if (!document.DiscoFunctions) {
            document.DiscoFunctions = {};
        }

        $(function () {
            var jobId = parseInt('@(Model.Job.Id)');

            //#region Comments
            var $Comments = $('#Comments');
            var $CommentOutput = $Comments.find('.commentOutput');
            var $CommentOutputContainer = $Comments.find('.commentOutputContainer');

            window.setTimeout(function () {
                $CommentOutput[0].scrollTop = $CommentOutput[0].scrollHeight; // Scroll to Bottom
            }, 0);
            $('#jobDetailTabs').on('tabsactivate', function (event, ui) {
                if (ui.newPanel && ui.newPanel.is('#jobDetailTab-Resources')) {
                    $CommentOutput[0].scrollTop = $CommentOutput[0].scrollHeight; // Scroll to Bottom
                }
            });

            @if (canAddLogs)
            {<text>
            //#region Add Logs

            var $CommentInput = $Comments.find('textarea.commentInput');

            $Comments.find('.commentInputPost').click(postComment);
            $CommentInput.keypress(function (e) {
                if (e.which == 13 && !e.shiftKey) {
                    postComment();
                    return false;
                }
            });

            function postComment() {
                if ($Comments.find('.commentInputPost').hasClass('disabled')) {
                    alert('Disconnected from the Disco ICT Server, please refresh this page and try again');
                    return;
                }

                var comment = $CommentInput.val();

                if (comment == '') {
                    alert('Enter a comment to post');
                    $CommentInput.focus();
                    return;
                }

                var data = { comment: comment }
                $.ajax({
                    url: '@Url.Action(MVC.API.Job.CommentPost(Model.Job.Id, null))',
                    dataType: 'json',
                    data: data,
                    success: function (d) {
                        if (d.Result == 'OK') {
                            // Should be added via Repository Notifications
                            // addComment(d.Comment, false);
                            $CommentInput.val('').attr('disabled', false).focus();
                        } else {
                            alert('Unable to post comment: ' + d.Result);
                            $CommentInput.attr('disabled', false);
                        }
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        alert('Unable to post comment: ' + textStatus);
                        $CommentInput.attr('disabled', false);
                    }
                });
            }

            //#endregion
            </text>}
            @if (canRemoveAnyLogs || canRemoveOwnLogs)
            {<text>
            //#region Remove Logs

            var $dialogRemoveLog;

            $CommentOutput.find('span.remove').click(removePost);

            function removePost() {
                $this = $(this);
                var data = { id: $this.closest('div').attr('data-logid') };

                if (!$dialogRemoveLog) {
                    $dialogRemoveLog = $('#dialogRemoveLog').dialog({
                        resizable: false,
                        height: 140,
                        modal: true,
                        autoOpen: false
                    });
                }

                $dialogRemoveLog.dialog("enable").dialog('option', 'buttons', {
                    "Remove": function () {
                        $dialogRemoveLog.dialog("disable");
                        $dialogRemoveLog.dialog("option", "buttons", null);
                        $.ajax({
                            url: '@Url.Action(MVC.API.Job.CommentRemove())',
                            dataType: 'json',
                            data: data,
                            success: function (d) {
                                if (d == 'OK') {
                                    // Should be removed via Repository Notifications
                                    //$this.closest('div').slideUp(300).delay(300).queue(function () {
                                    //    $(this).remove();
                                    //});
                                } else {
                                    alert('Unable to remove comment: ' + d);
                                }
                                $dialogRemoveLog.dialog("close");
                            },
                            error: function (jqXHR, textStatus, errorThrown) {
                                alert('Unable to remove comment: ' + textStatus);
                                $dialogRemoveLog.dialog("close");
                            }
                        });
                    },
                    "Cancel": function () {
                        $dialogRemoveLog.dialog("close");
                    }
                }).dialog('open');

                return false;
            }

            //#endregion
            </text>}

            function loadLiveComment(key) {
                $.ajax({
                    url: '@Url.Action(MVC.API.Job.Comment())',
                    dataType: 'json',
                    data: { id: key },
                    success: function (d) {
                        if (d && d.JobId == jobId) {
                                @if (canRemoveAnyLogs)
                                {<text>addComment(d, false, true);</text>}
                                else if (canRemoveOwnLogs)
                                {<text>addComment(d, false, (d.AuthorId === '@(CurrentUser.UserId)'));</text>}
                                else
                                {<text>addComment(d, false, false);</text>}

                        }
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        alert('Unable to load live comment ' + id + ': ' + textStatus);
                    }
                });
            }
            function liveRemoveComment(key) {
                $CommentOutput.children('div[data-logid="' + key + '"]').slideUp(300).delay(300).queue(function () {
                    var $this = $(this);
                    $this.find('.timestamp').livestamp('destroy');
                    $this.remove();
                });
            }
            function addComment(c, quick, canRemove) {
                var t = '<div><span class="author" />';
                if (canRemove)
                    t += '<span class="remove fa fa-times-circle" />';
                t += '<span class="timestamp" /><div class="comment" /></div>';

                var e = $(t);
                e.attr('data-logid', c.Id);
                e.find('.author').text(c.Author);
                e.find('.timestamp').text(c.TimestampFull).attr('title', c.TimestampFull).livestamp(c.TimestampUnixEpoc);
                if (canRemove)
                    e.find('.remove').click(removePost);
                var eComment = e.find('.comment').html(c.HtmlComments);

                $CommentOutput.append(e);

                if (!quick) {
                    e.animate({ backgroundColor: '#ffff99' }, 500, function () {
                        e.animate({ backgroundColor: '#fafafa' }, 500, function () {
                            e.css('background-color', '');
                        });
                    });
                    $CommentOutput.animate({ scrollTop: $CommentOutput[0].scrollHeight }, 250)
                }
            }

            // Add Globally Available Functions
            document.DiscoFunctions.liveLoadComment = loadLiveComment;
            document.DiscoFunctions.liveRemoveComment = liveRemoveComment;
            //#endregion
        });
    </script>
}
@if (canShowAttachments)
{
    <script>
        Shadowbox.init({
            skipSetup: true,
            modal: true
        });

        if (!document.DiscoFunctions) {
            document.DiscoFunctions = {};
        }

        $(function () {
            var jobId = parseInt('@(Model.Job.Id)');

            //#region Attachments
            var $Attachments = $('#Attachments');
            var $attachmentOutput = $Attachments.find('.attachmentOutput');

            @if (canAddAttachments)
            {<text>
            //#region Add Attachments
            var attachmentUploader = new document.Disco.AttachmentUploader($Attachments);

            var $attachmentInput = $Attachments.find('.attachmentInput');
            if (window.location.protocol != 'https:') {
                $attachmentInput.find('.photo')
                    .removeClass('enabled')
                    .addClass('disabled')
                    .attr('title', 'Capture Image: this functionality is only available over a HTTPS connection');
            }
            $attachmentInput.find('.photo').click(function () {
                if (!$(this).hasClass('enabled'))
                    alert('This functionality is only available over a HTTPS connection');
                else if ($(this).hasClass('disabled'))
                    alert('Disconnected from the Disco ICT Server, please refresh this page and try again');
                else
                    attachmentUploader.uploadImage();
            });
            $attachmentInput.find('.upload').click(function () {
                if ($(this).hasClass('disabled'))
                    alert('Disconnected from the Disco ICT Server, please refresh this page and try again');
                else
                    attachmentUploader.uploadFiles();
            });

            var resourcesTab;
            $(document).on('dragover', function () {
                if (!resourcesTab) {
                    var tabs = $Attachments.closest('.ui-tabs');
                    resourcesTab = {
                        tabs: tabs,
                        resourcesIndex: tabs.children('ul.ui-tabs-nav').find('a[href="#jobDetailTab-Resources"]').closest('li').index()
                    };
                }
                var selectedIndex = resourcesTab.tabs.tabs('option', 'active');
                if (resourcesTab.resourcesIndex !== selectedIndex)
                    resourcesTab.tabs.tabs('option', 'active', resourcesTab.resourcesIndex);
            });
            //#endregion
            </text>}

            @if (canRemoveAnyAttachments || canRemoveOwnAttachments)
            {<text>
            //#region Remove Attachments

            var $dialogRemoveAttachment;

            $attachmentOutput.find('span.remove').click(removeLocalAttachment);

            function removeLocalAttachment() {
                $this = $(this).closest('a');

                var data = { id: $this.attr('data-attachmentid') };

                if (!$dialogRemoveAttachment) {
                    $dialogRemoveAttachment = $('#dialogRemoveAttachment').dialog({
                        resizable: false,
                        height: 140,
                        modal: true,
                        autoOpen: false
                    });
                }

                $dialogRemoveAttachment.dialog("enable").dialog('option', 'buttons', {
                    "Remove": function () {
                        $dialogRemoveAttachment.dialog("disable");
                        $dialogRemoveAttachment.dialog("option", "buttons", null);
                        $.ajax({
                            url: '@Url.Action(MVC.API.Job.AttachmentRemove())',
                            dataType: 'json',
                            data: data,
                            success: function (d) {
                                if (d == 'OK') {
                                    // Should be removed via Repository Notifications
                                } else {
                                    alert('Unable to remove attachment: ' + d);
                                }
                                $dialogRemoveAttachment.dialog("close");
                            },
                            error: function (jqXHR, textStatus, errorThrown) {
                                alert('Unable to remove attachment: ' + textStatus);
                                $dialogRemoveAttachment.dialog("close");
                            }
                        });
                    },
                    "Cancel": function () {
                        $dialogRemoveAttachment.dialog("close");
                    }
                }).dialog('open');

                return false;
            }

            //#endregion

            </text>}

            function addAttachment(key, quick) {
                var data = { id: key };
                $.ajax({
                    url: '@Url.Action(MVC.API.Job.Attachment())',
                    dataType: 'json',
                    data: data,
                    success: function (d) {
                        if (d.Result == 'OK') {
                            var a = d.Attachment;
                                @if (canRemoveAnyAttachments)
                                {
                                <text>buildAttachment(a, true, quick);</text>
                                }
                                else if (canRemoveOwnAttachments)
                                {
                                <text>buildAttachment(a, (a.AuthorId === '@(CurrentUser.UserId)'), quick);</text>
                                }
                                else
                                {
                                <text>buildAttachment(a, false, quick);</text>
                                }
                        } else {
                            alert('Unable to add attachment: ' + d.Result);
                        }
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        alert('Unable to add attachment: ' + textStatus);
                    }
                });
            }
            function buildAttachment(a, canRemove, quick) {
                if (parseInt(a.ParentId) == jobId) {
                    var t = '<a><span class="icon"><img alt="Attachment Thumbnail" /></span><span class="comments"></span><span class="author"></span>';
                    if (canRemove)
                        t += '<span class="remove fa fa-times-circle"></span>';
                    t += '<span class="timestamp"></span></a>';

                    var e = $(t);

                    e.attr('data-attachmentid', a.Id).attr('data-mimetype', a.MimeType).attr('href', '@(Url.Action(MVC.API.Job.AttachmentDownload()))/' + a.Id);
                    e.find('.comments').text(a.Description);
                    e.find('.author').text(a.Author);
                    e.find('.timestamp').text(a.TimestampFull).attr('title', a.TimestampFull).livestamp(a.TimestampUnixEpoc);
                    if (canRemove)
                        e.find('.remove').click(removeLocalAttachment);
                    if (!quick)
                        e.hide();
                    $attachmentOutput.prepend(e);
                    document.DiscoFunctions.liveAfterUpdate();
                    if (!quick)
                        e.show('slow');
                    if (a.MimeType.toLowerCase().indexOf('image/') == 0)
                        e.shadowbox({ gallery: 'attachments', player: 'img', title: a.Description });
                    else
                        e.click(onDownload);

                    // Add Thumbnail
                    var buildThumbnail = function () {
                        var retryCount = 0;
                        var img = e.find('.icon img');

                        var setThumbnailUrl = function () {
                            img.attr('src', '@(Url.Action(MVC.API.Job.AttachmentThumbnail()))/' + a.Id + '?v=' + retryCount);
                        };
                        img.on('error', function () {
                            img.addClass('loading');
                            retryCount++;
                            if (retryCount < 6)
                                window.setTimeout(setThumbnailUrl, retryCount * 250);
                        });
                        img.on('load', function () {
                            img.removeClass('loading');
                        });
                        window.setTimeout(setThumbnailUrl, 100);
                    };
                    buildThumbnail();
                }
            }

            function onDownload() {
                var $this = $(this);
                var url = $this.attr('href');

                if ($.connection && $.connection.hub && $.connection.hub.transport &&
                                    $.connection.hub.transport.name == 'foreverFrame') {
                    // SignalR active with foreverFrame transport - use popup window
                    window.open(url, '_blank', 'height=150,width=250,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no');
                } else {
                    // use iFrame
                    if (!$attachmentDownloadHost) {
                        $attachmentDownloadHost = $('<iframe>')
                            .attr({ 'src': url, 'title': 'Attachment Download Host' })
                            .addClass('hidden')
                            .appendTo('body')
                            .contents();
                    } else {
                        $attachmentDownloadHost[0].location.href = url;
                    }
                }

                return false;
            }

            function removeAttachment(key) {
                var $element = $attachmentOutput.find('a[data-attachmentid="' + key + '"]');
                if ($element.length > 0) {
                    $element.hide(300).delay(300).queue(function () {
                        if ($element.attr('data-mimetype').toLowerCase().indexOf('image/') == 0)
                            Shadowbox.removeCache(this);
                        $element.remove();
                        document.DiscoFunctions.liveAfterUpdate();
                    });
                }
            }

            $attachmentOutput.children('a').each(function () {
                $this = $(this);
                if ($this.attr('data-mimetype').toLowerCase().indexOf('image/') == 0)
                    $this.shadowbox({ gallery: 'attachments', player: 'img', title: $this.find('.comments').text() });
                else
                    $this.click(onDownload);
            });

            // Add Globally Available Functions
            document.DiscoFunctions.liveAddAttachment = addAttachment;
            document.DiscoFunctions.liveRemoveAttachment = removeAttachment;

            //#endregion
        });


    </script>
}
@if (canShowLogs || canShowAttachments)
{
    <script>
        $(function () {
            var jobId = parseInt('@(Model.Job.Id)');

            //#region LiveEvents
            var hub = $.connection.jobUpdates;

            // Map Functions
@if (canShowLogs)
{<text>
            hub.client.addLog = document.DiscoFunctions.liveLoadComment;
            hub.client.removeLog = document.DiscoFunctions.liveRemoveComment;
            </text>}
@if (canShowAttachments)
{<text>
            hub.client.addAttachment = document.DiscoFunctions.liveAddAttachment;
            hub.client.removeAttachment = document.DiscoFunctions.liveRemoveAttachment;

            document.DiscoFunctions.liveAfterUpdate = function () {
                var tabLink = $('#jobDetailTab-ResourcesLink');
                var attachmentCount = $('#Attachments').find('.attachmentOutput').children('a').length;

                var tabHeading = tabLink.text();
                tabHeading = tabHeading.substr(0, tabHeading.indexOf('[') + 1) + attachmentCount + ']';
                tabLink.text(tabHeading);
            }
</text>}

            $.connection.hub.qs = { JobId: jobId };
            $.connection.hub.error(onHubFailed);
            $.connection.hub.disconnected(onHubFailed);

            $.connection.hub.reconnecting(function () {
                $('#CommentsContainer').find('span.action').addClass('disabled');
                $('#AttachmentsContainer').find('span.action.enabled').addClass('disabled');
            });
            $.connection.hub.reconnected(function () {
                $('#CommentsContainer').find('span.action').removeClass('disabled');
                $('#AttachmentsContainer').find('span.action.enabled').removeClass('disabled');
            });

            // Start Connection
            $.connection.hub.start(function () {
                $('#CommentsContainer').find('span.action').removeClass('disabled');
                $('#AttachmentsContainer').find('span.action.enabled').removeClass('disabled');
            }).fail(onHubFailed);

            function onHubFailed(error) {
                // Disable UI
                $('#CommentsContainer').find('textarea.commentInput').attr('readonly', 'readonly');
                $('#CommentsContainer').find('span.action').addClass('disabled');
                $('#AttachmentsContainer').find('span.action.enabled').addClass('disabled');

                // Show Dialog Message
                if ($('.disconnected-dialog').length == 0) {
                    $('<div>')
                        .addClass('dialog disconnected-dialog')
                        .html('<h3><span class="fa-stack fa-lg"><i class="fa fa-wifi fa-stack-1x"></i><i class="fa fa-ban fa-stack-2x error"></i></span>Disconnected from the Disco ICT Server</h3><div>This page is not receiving live updates. Please ensure you are connected to the server, then refresh this page to enable features.</div>')
                        .dialog({
                            resizable: false,
                            title: 'Disconnected',
                            width: 400,
                            modal: true,
                            buttons: {
                                'Refresh Now': function () {
                                    $(this).dialog('option', 'buttons', null);
                                    window.location.reload(true);
                                },
                                'Close': function () {
                                    $(this).dialog('destroy');
                                }
                            }
                        });
                }
            }

            //#endregion
        });
    </script>
}