// ******* Annotation MANAGER ******** //
$axure.internal(function($ax) {
    var NOTE_SIZE = 10;

    var _annotationManager = $ax.annotation = {};

    var _updateLinkLocations = $ax.annotation.updateLinkLocations = function(elementId) {
        var textId = $ax.GetTextPanelId(elementId);
        if(!textId) return;

        var rotation = $ax.getObjectFromElementId(elementId).style.rotation;
        //we have to do this because webkit reports the post-transform position but when you set positions it's pre-transform
        if(WEBKIT && rotation) {
            //we can dynamiclly rotate a widget now, show need to remember the transform rather than just remove it
            //here jquery.css will return 'none' if element is display none
            var oldShapeTransform = document.getElementById(elementId).style['-webkit-transform'];
            var oldTextTransform = document.getElementById(textId).style['-webkit-transform'];
            $('#' + elementId).css('-webkit-transform', 'scale(1)');
            $('#' + textId).css('-webkit-transform', 'scale(1)');
        }

        $('#' + textId).find('div[id$="_ann"]').each(function(index, value) {
            var elementId = value.id.replace('_ann', '');
            var $link = $('#' + elementId);
            var annPos = $link.position();
            annPos.left += $link.width();
            //var annPos = $(value).position();
            var left = annPos.left;// - NOTE_SIZE;
            var top = annPos.top - 5;

            $(value).css('left', left).css('top', top);
        });

        //undo the transform reset
        if(WEBKIT && rotation) {
            $('#' + elementId).css('-webkit-transform', oldShapeTransform || '');
            $('#' + textId).css('-webkit-transform', oldTextTransform || '');
        }
    };

    var _toggleAnnotationDialog = function (elementId, event) {
        let win = $(window);
        let scrollY = win.scrollTop();
        let scrollX = win.scrollLeft();
        
        let x = event.pageX - scrollX;
        let y = event.pageY - scrollY;

        let frameElement = window.frameElement;
        let parent = window.parent;
        //ann dialog is relative to mainFrame, exclude the mainFrame location so the notes shows up correctly in device mode
        while(frameElement && frameElement.name !== 'mainFrame') {
            let rect = frameElement.getBoundingClientRect();
            x += rect.x;
            y += rect.y;
            
            if(!parent) break;

            frameElement = parent.frameElement;
            parent = parent.parent;
        }
        
        let messageData = { id: elementId, x: x, y: y }
        if (!$axure.utils.isInPlayer()) messageData.page = $ax.pageData.notesData;
        $ax.messageCenter.postMessage('toggleAnnDialog', messageData);
    }
    
    $ax.annotation.initialize = function () {
        _createFootnotes($ax('*'), true);
    }

    var _createFootnotes = $ax.annotation.createFootnotes = function(query, create) {
        if(!$ax.document.configuration.showAnnotations) return;
        
        var widgetNotes = $ax.pageData.notesData.widgetNotes;
        if (widgetNotes) {
            var ownerToFns = $ax.pageData.notesData.ownerToFns;
            if(!$.isEmptyObject(ownerToFns)) {
                query.each(function(dObj, elementId) {
                    var fns = ownerToFns[dObj.id];
                    if (fns !== undefined) {
                        var elementIdQuery = $('#' + elementId);
                        if (dObj.type == 'hyperlink') {
                            var parentId = $ax.GetParentIdFromLink(elementId);
                            if (create) {
                                elementIdQuery.after("<div id='" + elementId + "_ann' class='annnote'>&#8203;</div>");
                                appendFns($('#' + elementId + "_ann"), fns);
                            }
                            _updateLinkLocations(parentId);
                        } else {
                            if (create) {
                                elementIdQuery.after("<div id='" + elementId + "_ann' class='annnote'>&#8203;</div>");
                                appendFns($('#' + elementId + "_ann"), fns);
                            }
                            _adjustIconLocation(elementId, dObj);
                        }

                        if (create) {
                            $('#' + elementId + "_ann").click(function (e) {
                                _toggleAnnotationDialog(dObj.id, e);
                                return false;
                            });

                            var isVisible = true;
                            var isMaster = $ax.public.fn.IsReferenceDiagramObject(dObj.type);
                            if (isMaster) isVisible = dObj.visible;
                            else isVisible = $ax.visibility.IsIdVisible(elementId);
                            if (!isVisible) {
                                var ann = document.getElementById(elementId + "_ann");
                                if (ann) $ax.visibility.SetVisible(ann, false);
                            }
                        }
                    }
                });
            }
        }

        function appendFns($parent, fns) {
            for (var index = 0; index < fns.length; index++) {
                $parent.append("<div class='annnotelabel' >" + fns[index] + "</div>");
            }
        }
    };

    $ax.annotation.updateAllFootnotes = function () {
        _createFootnotes($ax('*'), false);
    }

    $ax.annotation.jQueryAnn = function(query) {
        var elementIds = [];
        query.each(function(diagramObject, elementId) {
            if(diagramObject.annotation) elementIds[elementIds.length] = elementId;
        });
        var elementIdSelectors = jQuery.map(elementIds, function(elementId) { return '#' + elementId + '_ann'; });
        var jQuerySelectorText = (elementIdSelectors.length > 0) ? elementIdSelectors.join(', ') : '';
        return $(jQuerySelectorText);
    };

    $(window.document).ready(function() {
        //$ax.annotation.InitializeAnnotations($ax(function(dObj) { return dObj.annotation; }));

        $ax.messageCenter.addMessageListener(function(message, data) {
            //If the annotations are being hidden via the Sitemap toggle button, hide any open dialogs
            if(message == 'annotationToggle') {
                if (data == true) {
                    $('div.annnote').show();
                } else {
                    $('div.annnote').hide();
                }
            }
        });
    });

    var _getCornersForFootnotes = function (id) {
        var element = document.getElementById(id);
        var matrix = element ? $ax.public.fn.transformFromElement(element) : [1.0, 0.0, 0.0, 1.0, 0.0, 0.0];
        var currentMatrix = { m11: matrix[0], m21: matrix[1], m12: matrix[2], m22: matrix[3], tx: matrix[4], ty: matrix[5] };
        var dimensions = {};
        var axObj = $ax('#' + id);
        var viewportLocation = axObj.offsetLocation();
        dimensions.left = viewportLocation.left;
        dimensions.top = viewportLocation.top;

        var parentRdo = axObj.getParents(false, ['rdo'])[0];
        if(parentRdo && parentRdo.length > 0) {
            var parentRdoLocation = $ax('#' + parentRdo).offsetLocation();
            dimensions.left = dimensions.left - parentRdoLocation.left;
            dimensions.top = dimensions.top - parentRdoLocation.top;
        }

        var size = axObj.size();
        dimensions.width = size.width;
        dimensions.height = size.height;

        var halfWidth = dimensions.width * 0.5;
        var halfHeight = dimensions.height * 0.5;
        var preTransformTopRight = { x: halfWidth, y: -halfHeight };
        var preTransformBottomRight = { x: halfWidth, y: halfHeight };

        return {
            relativeTopRight: $ax.public.fn.matrixMultiply(currentMatrix, preTransformTopRight),
            relativeBottomRight: $ax.public.fn.matrixMultiply(currentMatrix, preTransformBottomRight),
            centerPoint: { x: dimensions.left + halfWidth, y: dimensions.top + halfHeight }
        }
    }

    //adjust annotation location to a element's top right corner
    var _adjustIconLocation = $ax.annotation.adjustIconLocation = function(id, dObj) {
        var ann = document.getElementById(id + "_ann");
        if(ann) {
            var corners = _getCornersForFootnotes(id);
            var width = $(ann).width();
            var newTopRight = $ax.public.fn.vectorPlus(corners.relativeTopRight, corners.centerPoint);
            //note size is 14x8, this is how rp calculated it as well
            ann.style.left = (newTopRight.x - width) + "px";

            var elementType = dObj ? dObj.type : $ax.getTypeFromElementId(id);
            var yOffset = $ax.public.fn.IsTableCell(elementType) ? 0 : -8;
            ann.style.top = (newTopRight.y + yOffset) + "px";
        }

        var ref = document.getElementById(id + "_ref");
        if(ref) {
            if(!corners) corners = _getCornersForFootnotes(id);
            var newBottomRight = $ax.public.fn.vectorPlus(corners.relativeBottomRight, corners.centerPoint);

            ref.style.left = (newBottomRight.x - 8) + 'px';
            ref.style.top = (newBottomRight.y - 10) + 'px';
        }
    }
});