//
//  CPDFDigtalView.m
//  EaseUS PDF Editor
//
//  Created by Niehaoyu on 2023/10/10.
//

#import "CPDFDigtalView.h"
#import "CPDFAnnotation+PDFListView.h"
#import "NSGeometry+PDFListView.h"
#import "CPDFListViewConfig.h"

#define HANDLE_SIZE 4.0

#define MIN_NOTE_SIZE 8.0

@implementation CPDFDigtalView

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    
    // Drawing code here.
}

- (id)initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:frameRect];
    if (self) {
        [self setUp];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super initWithCoder:decoder];
    if (self) {
        [self setUp];
    }
    return self;
}

- (void)setUp {
    
    self.annotationType = CAnnotationTypeSignature;
    self.activeAnnotations = [NSMutableArray array];
}

- (void)setDocument:(CPDFDocument *)document {
    [super setDocument:document];
    
    NSArray *signatures = document.signatures;
    
    NSMutableArray *tempArr = [NSMutableArray array];
    for (CPDFSignature *signature in signatures) {
        if(signature.signers.count > 0) {
            [signature verifySignatureWithDocument:document];
            [tempArr addObject:signature];
        }
    }
    self.signatures = tempArr;
}

- (CPDFPage *)pageAndPoint:(NSPoint *)point forEvent:(NSEvent *)event nearest:(BOOL)nearest {
    NSPoint p = [self convertPoint:[event locationInWindow] fromView:nil];
    CPDFPage *page = [self pageForPoint:p nearest:nearest];
    if (page && point)
        *point = [self convertPoint:p toPage:page];
    return page;
}

- (void)setCursorForMouse:(NSEvent *)theEvent {
    if (theEvent == nil)
        theEvent = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
                                      location:[[self window] mouseLocationOutsideOfEventStream]
                                 modifierFlags:[NSEvent standardPDFListViewModifierFlags]
                                     timestamp:0
                                  windowNumber:[[self window] windowNumber]
                                       context:nil
                                   eventNumber:0
                                    clickCount:1
                                      pressure:0.0];
    [self setCursorForAreaOfInterest:[self areaOfInterestForMouse:theEvent]];
}

- (CPDFAnnotation *)activeAnnotation {
    return self.activeAnnotations.lastObject;
}

- (void)mouseDown:(NSEvent *)theEvent {
    [self setCursorForMouse:theEvent];
    
    NSPoint point = NSZeroPoint;

    CPDFAreaOfInterest area = [self areaOfInterestForMouse:theEvent];
    NSPoint newpoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    area = [self areaOfInterestForPoint:newpoint];

    CPDFAnnotation *newActiveAnnotation = nil;
    if ([[self document] isLocked]) {
        [super mouseDown:theEvent];
    } else if ([self doClickAnnotationWithEvent:theEvent forAnnotation:&newActiveAnnotation]) {
        [self doDragAnnotationWithEvent:theEvent forAnnotation:newActiveAnnotation];
    } else {
        [self doDragAddAnnotationWithEvent:theEvent];
    }
    
}

- (BOOL)doClickAnnotationWithEvent:(NSEvent *)theEvent forAnnotation:(CPDFAnnotation **)annotation{
    CPDFAnnotation *newActiveAnnotation = nil;
    NSPoint point = NSZeroPoint;
    CPDFPage *page = [self pageAndPoint:&point forEvent:theEvent nearest:YES];
    
    
    NSMutableArray *currentActiveAnnotations = [NSMutableArray array];
    for (CPDFAnnotation *an in self.activeAnnotations) {
        if([an.page isEqual:page]) {
            if(!([an isKindOfClass:[CPDFMarkupAnnotation class]] || [an isKindOfClass:[CPDFTextAnnotation class]])) {
                [currentActiveAnnotations addObject:an];
            }
        }
    }
    
    newActiveAnnotation = [self doSelectAnnotationWithEvent:theEvent];
    *annotation = newActiveAnnotation;
    return !!newActiveAnnotation;
}

- (CPDFAnnotation *)doSelectAnnotationWithEvent:(NSEvent *)theEvent {
    CPDFAnnotation *newActiveAnnotation = nil;
    NSPoint point = NSZeroPoint;
    CPDFPage *page = [self pageAndPoint:&point forEvent:theEvent nearest:YES];
    id annotations = [page annotations];
    
    for (CPDFAnnotation *annotation in annotations) {
        if ([annotation hitTest:point] && [annotation annotationShouldDisplay] ) {
            newActiveAnnotation = annotation;
            break;
        }
    }
    
    return newActiveAnnotation;
}

- (void)doDragAnnotationWithEvent:(NSEvent *)theEvent forAnnotation:(CPDFAnnotation *)newActiveAnnotation {
    BOOL isContains = YES;
    if (self.activeAnnotations.count == 0 || ![self.activeAnnotations containsObject:newActiveAnnotation]) {
        isContains = NO;
    }
    
    NSRect originalBounds = [newActiveAnnotation bounds];
    BOOL isLine = [newActiveAnnotation isKindOfClass:[CPDFLineAnnotation class]];
    NSPoint pagePoint = NSZeroPoint;
    CPDFPage *page = [self pageAndPoint:&pagePoint forEvent:theEvent nearest:YES];
    NSPoint originalStartPoint = NSZeroPoint;
    NSPoint originalEndPoint = NSZeroPoint;
    
    BOOL draggedAnnotation = NO;
    NSEvent *lastMouseEvent = theEvent;
    NSPoint offset = CPDFListViewSubstractPoints(pagePoint, originalBounds.origin);
    NSUInteger eventMask = NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged;

    CGFloat mouseOffset = [self unitWidthOnPage:page];
    
    
    while (YES) {
        theEvent = [[self window] nextEventMatchingMask:eventMask];
        if ([theEvent type] == NSEventTypeLeftMouseUp) {
            if(draggedAnnotation) {
                if (!isContains)
                    [self.selectAnnotations removeAllObjects];
            } else {
                if(self.activeAnnotations.count == 1 &&
                   self.activeAnnotation == newActiveAnnotation &&
                   ([newActiveAnnotation isKindOfClass:[CPDFTextAnnotation class]] || [newActiveAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]])) {
                    [self editAnnotation:newActiveAnnotation];
                    break;
                }
                
                if(!isContains) {
                    [self updateActiveAnnotations:@[newActiveAnnotation]];
                }
                [self editAnnotation:newActiveAnnotation];
            }
            [self setNeedsDisplayAnnotationViewForPage:page];
            break;
        } else if ([theEvent type] == NSEventTypeLeftMouseDragged) {
            NSPoint point = NSZeroPoint;
            [self pageAndPoint:&point forEvent:theEvent nearest:YES];
            CGRect zRect = CGRectMake(pagePoint.x-2*mouseOffset, pagePoint.y-2*mouseOffset, 4*mouseOffset, 4*mouseOffset);
            if (CGRectContainsPoint(zRect, point)) {continue;}
            
            lastMouseEvent = theEvent;
            draggedAnnotation = YES;

            if(!isContains) {
                [self dragAnnotationReferenceLine:newActiveAnnotation];
                
                [self.selectAnnotations removeAllObjects];
                [self.selectAnnotations addObject:newActiveAnnotation];
                
                [self doMoveAnnotation:newActiveAnnotation withEvent:lastMouseEvent offset:offset];
            } else {
                
                if ([newActiveAnnotation isKindOfClass:[CPDFStampAnnotation class]] ||
                    [newActiveAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]] ||
                    [newActiveAnnotation isKindOfClass:[CPDFSignatureAnnotation class]] ||
                    [newActiveAnnotation isKindOfClass:[CPDFWidgetAnnotation class]]) {
                    [newActiveAnnotation updateAppearanceStream];
                }
            }
            [self dragAnnotationReferenceLine:newActiveAnnotation];
            
            [self setNeedsDisplayAnnotationViewForPage:page];
        }
    }
    
    [self performSelector:@selector(setCursorForMouse:) withObject:theEvent afterDelay:0];
    
}


- (void)doMoveAnnotation:(CPDFAnnotation *)activeAnnotation withEvent:(NSEvent *)theEvent offset:(NSPoint)offset {
    // Move annotation.
    [[[self documentView] contentView] autoscroll:theEvent];
    
    NSPoint point = NSZeroPoint;
    CPDFPage *newActivePage = [self pageAndPoint:&point forEvent:theEvent nearest:YES];
    
    if (newActivePage) { // newActivePage should never be nil, but just to be sure
        if (newActivePage != [activeAnnotation page]) {
            return;
        }
        
        NSRect newBounds = [activeAnnotation bounds];
        newBounds.origin = CPDFListViewIntegralPoint(CPDFListViewSubstractPoints(point, offset));
        // constrain bounds inside page bounds
        
    }
}

- (void)dragAnnotationReferenceLine:(CPDFAnnotation *)annotation {
    
}

- (void)editAnnotation:(CPDFAnnotation *)annotation {
    if ([annotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
        [self editAnnotationFreeText:(CPDFFreeTextAnnotation *)annotation];
        [[self window] makeFirstResponder:self];
        
        [self setNeedsDisplayAnnotation:annotation];
    } else {
        if([annotation isKindOfClass:[CPDFSignatureWidgetAnnotation class]]) {
            if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewEditAnnotation:forAnnotation:)]) {
                [self.pdfListViewDelegate PDFListViewEditAnnotation:self forAnnotation:annotation];
            }
        }
    }
}


- (void)doDragAddAnnotationWithEvent:(NSEvent *)theEvent {
    NSPoint pagePoint = NSZeroPoint;
    CPDFPage *page = [self pageAndPoint:&pagePoint forEvent:theEvent nearest:YES];

    NSRect originalBounds = CGRectZero;
    CGFloat mouseOffset = [self unitWidthOnPage:page];
//    [self setCursorForAreaOfInterest:CAreaOfInterestForResizeHandle(CMaxXEdgeMask | CMinYEdgeMask, page)];

    CPDFAnnotation *annotation = nil;
    
    originalBounds = CPDFListViewRectFromCenterAndSquareSize(CPDFListViewIntegralPoint(pagePoint), 0.0);
    CRectEdges resizeHandle = CMaxXEdgeMask | CMinYEdgeMask;
    
    BOOL draggedAnnotation = NO;
    NSEvent *lastMouseEvent = theEvent;
    NSUInteger eventMask = NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged;
    while (YES) {
        theEvent = [[self window] nextEventMatchingMask:eventMask];
        if ([theEvent type] == NSEventTypeLeftMouseUp) {
            if (!draggedAnnotation) {
                if (annotation) {
                    break;
                }
                if(CAnnotationTypeLine == self.annotationType ||
                   CAnnotationTypeArrow == self.annotationType) {
                    
                } else {
                    
                    CGFloat defaultWidth = 72;
                    CGFloat defaultHeight = 32;
                    NSSize defaultSize = ([page rotation] % 180 == 0) ? NSMakeSize(defaultWidth, defaultHeight) : NSMakeSize(defaultHeight, defaultWidth);
                    CGRect bounds = CGRectZero;
                   
                    bounds = CPDFListViewRectFromCenterAndSize(CPDFListViewIntegralPoint(pagePoint), defaultSize);
                    
                    bounds = CPDFListViewConstrainRect(bounds, page.bounds,[CPDFListViewConfig defaultManager].annotationBorderOffset.floatValue);
                    annotation = [self addAnnotationWithType:self.annotationType selection:nil page:page bounds:bounds];
                    originalBounds = [annotation bounds];
                    
                    if(annotation) {
                        [self updateActiveAnnotations:@[annotation]];
                        [self setNeedsDisplayAnnotation:annotation];
                    } else if(self.activeAnnotations.count >0) {
                        [self updateActiveAnnotations:@[]];
                        [self setNeedsDisplayAnnotationViewForPage:page];
                    }
                }
            } else {
                
            }
            
            break;
        } else if ([theEvent type] == NSEventTypeLeftMouseDragged) {

            CGPoint zPoint = pagePoint;
            [self pageAndPoint:&zPoint forEvent:theEvent nearest:YES];
            CGRect zRect = CGRectMake(pagePoint.x-2*mouseOffset, pagePoint.y-2*mouseOffset, 4*mouseOffset, 4*mouseOffset);
            if (CGRectContainsPoint(zRect, zPoint)) {continue;}
            
            if (annotation == nil)
                annotation = [self addAnnotationWithType:self.annotationType selection:nil page:page bounds:CPDFListViewRectFromCenterAndSquareSize(originalBounds.origin, 0.0)];
            
            if(annotation) {
                [self updateActiveAnnotations:@[annotation]];
            } else if(self.activeAnnotations.count >0) {
                [self updateActiveAnnotations:@[]];
                [self setNeedsDisplayAnnotationViewForPage:page];
            }
            lastMouseEvent = theEvent;
            draggedAnnotation = YES;
            
            [self setNeedsDisplayAnnotationViewForPage:page];
        }
        [self doResizeAnnotationWithEvent:lastMouseEvent fromPoint:pagePoint originalBounds:originalBounds resizeHandle:&resizeHandle];
    }
    if (annotation) {
        [self setNeedsDisplayAnnotation:annotation];
        
        if ([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewAddAnnotation:forAddAnnotation:inPage:)]) {
            [self.pdfListViewDelegate PDFListViewAddAnnotation:self forAddAnnotation:annotation inPage:page];
        }
    }
    
    [self performSelector:@selector(setCursorForMouse:) withObject:theEvent afterDelay:0];
}

- (void)setNeedsDisplayAnnotation:(CPDFAnnotation *)annotation {
    if (annotation) {
        [self setNeedsDisplayAnnotationViewForPage:annotation.page];
    } else {
        [self setNeedsDisplayAnnotationViewForVisiblePages];
    }
}

- (CGFloat)unitWidthOnPage:(CPDFPage *)page {
    return NSWidth([self convertRect:NSMakeRect(0.0, 0.0, 1.0, 1.0) toPage:page]);
}


- (CPDFAnnotation *)addAnnotationWithType:(CAnnotationType)annotationType selection:(CPDFSelection *)selection page:(CPDFPage *)page bounds:(NSRect)bounds {
    CPDFAnnotation *annotation = nil;
    
    NSString *text = [selection PDFListViewCleanedString];
    
    BOOL isInitial = NO;
    if(selection) {
        CGRect noteRect = selection.bounds;
        isInitial = NSEqualSizes(noteRect.size, NSZeroSize);
    } else {
        isInitial = NSEqualSizes(bounds.size, NSZeroSize);
    }
        
    if (isInitial)
        bounds = CPDFListViewRectFromCenterAndSquareSize(bounds.origin, 8.0);
    switch (annotationType) {
        case CAnnotationTypeSignature:
            annotation = [[CPDFSignatureWidgetAnnotation alloc] initPDFListViewNoteWithDocument:self.document];
            annotation.bounds = bounds;
            break;
        default:
            break;
    }
    if (annotation) {
        if (annotationType != CAnnotationTypeLine && annotationType != CAnnotationTypeArrow && annotationType != CAnnotationTypeInk && [text length] > 0)
            [annotation setString:text];
        [self addAnnotation:annotation toPage:page];
    }
    return annotation;
}

- (void)updateActiveAnnotations:(NSArray<CPDFAnnotation *> *)activeAnnotations {
    [self refreshActiveAnnotations:activeAnnotations isRight:NO];
}

- (void)addAnnotation:(CPDFAnnotation *)annotation toPage:(CPDFPage *)page {
//    [[[self undoManager] prepareWithInvocationTarget:self] removeAnnotation:annotation];
    
    [annotation setModificationDate:[NSDate date]];
    //widget设置作者与fieldName冲突
    if (![annotation isKindOfClass:[CPDFWidgetAnnotation class]]) {
        [annotation setUserName:CPDFKitShareConfig.annotationAuthor?:NSFullUserName()];
    }
    [page addAnnotation:annotation];
    [self setNeedsDisplayAnnotation:annotation];
    [[self undoManager] setActionName:NSLocalizedString(@"Add Note", @"Undo action name")];
}

- (void)refreshActiveAnnotations:(NSArray<CPDFAnnotation *> *)activeAnnotations isRight:(BOOL)isRight {
    if(activeAnnotations) {
        NSArray *selectTure = [activeAnnotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF in %@", self.activeAnnotations]];
        BOOL isSame = NO;
        if(self.activeAnnotations.count == activeAnnotations.count && self.activeAnnotations.count == selectTure.count) isSame = YES;
        
        if(!isSame) {
            self.activeAnnotations = [NSMutableArray arrayWithArray:activeAnnotations];
        }
    } else if (!activeAnnotations && self.activeAnnotations.count > 0) {
        [self.activeAnnotations removeAllObjects];
    }
}

- (void)doResizeAnnotationWithEvent:(NSEvent *)theEvent fromPoint:(NSPoint)originalPagePoint originalBounds:(NSRect)originalBounds resizeHandle:(CRectEdges *)resizeHandlePtr {
    CPDFAnnotation *activeAnnotation = self.activeAnnotation;
    NSPoint pagePoint = NSZeroPoint;
    CPDFPage *page = activeAnnotation?activeAnnotation.page:[self pageAndPoint:&pagePoint forEvent:theEvent nearest:YES];
    NSRect newBounds = originalBounds;
    NSRect pageBounds = [page boundsForBox:[self displayBox]];
    NSPoint currentPagePoint = [self convertPoint:[theEvent locationInPDFListView:self] toPage:page];
    NSPoint relPoint = CPDFListViewSubstractPoints(currentPagePoint, originalPagePoint);
    CRectEdges resizeHandle = *resizeHandlePtr;
    
    if (NSEqualSizes(originalBounds.size, NSZeroSize)) {
        CRectEdges currentResizeHandle = (relPoint.x < 0.0 ? CMinXEdgeMask : CMaxXEdgeMask) | (relPoint.y <= 0.0 ? CMinYEdgeMask : CMaxYEdgeMask);
        if (currentResizeHandle != resizeHandle) {
            *resizeHandlePtr = resizeHandle = currentResizeHandle;
//            [self setCursorForAreaOfInterest:CAreaOfInterestForResizeHandle(resizeHandle, page)];
        }
    }
    
    BOOL isRadioOrCheckButton = NO;
    if ([activeAnnotation isKindOfClass:[CPDFButtonWidgetAnnotation class]]) {
        CPDFButtonWidgetAnnotation *annotation = (CPDFButtonWidgetAnnotation *)activeAnnotation;
        if (CPDFWidgetRadioButtonControl == annotation.controlType ||
            CPDFWidgetCheckBoxControl == annotation.controlType) {
            isRadioOrCheckButton = YES;
        }
    }
    
    CGFloat minWidth = MIN_NOTE_SIZE;
    CGFloat minHeight = MIN_NOTE_SIZE;
    CGFloat offsetPageSet = 2;
    if ((resizeHandle & CMaxXEdgeMask)) {
        newBounds.size.width += relPoint.x;
        if (NSMaxX(newBounds)+offsetPageSet > NSMaxX(pageBounds))
            newBounds.size.width = NSMaxX(pageBounds) - NSMinX(newBounds)-offsetPageSet;
        if (NSWidth(newBounds) < minWidth) {
            newBounds.size.width = minWidth;
        }
    } else if ((resizeHandle & CMinXEdgeMask)) {
        newBounds.origin.x += relPoint.x;
        newBounds.size.width -= relPoint.x;
        if (NSMinX(newBounds)-offsetPageSet < NSMinX(pageBounds)) {
            newBounds.size.width = NSMaxX(newBounds) - NSMinX(pageBounds)-offsetPageSet;
            newBounds.origin.x = NSMinX(pageBounds)+offsetPageSet;
        }
        if (NSWidth(newBounds) < minWidth) {
            newBounds.origin.x = NSMaxX(newBounds) - minWidth;
            newBounds.size.width = minWidth;
        }
    }
    if ((resizeHandle & CMaxYEdgeMask)) {
        newBounds.size.height += relPoint.y;
        if (NSMaxY(newBounds)+ offsetPageSet > NSMaxY(pageBounds)) {
            newBounds.size.height = NSMaxY(pageBounds) - NSMinY(newBounds)- offsetPageSet;
        }
        if (NSHeight(newBounds) < minHeight) {
            newBounds.size.height = minHeight;
        }
        
    } else if ((resizeHandle & CMinYEdgeMask)) {
        newBounds.origin.y += relPoint.y;
        newBounds.size.height -= relPoint.y;
        if (NSMinY(newBounds)-offsetPageSet < NSMinY(pageBounds)) {
            newBounds.size.height = NSMaxY(newBounds) - NSMinY(pageBounds)-offsetPageSet;
            newBounds.origin.y = NSMinY(pageBounds)+offsetPageSet;
        }
        if (NSHeight(newBounds) < minHeight) {
            newBounds.origin.y = NSMaxY(newBounds) - minHeight;
            newBounds.size.height = minHeight;
        }
    }
    
    [activeAnnotation setBounds:NSIntegralRect(newBounds)];
    
    if ([activeAnnotation isKindOfClass:[CPDFFreeTextAnnotation class]]) {
        [self updateAnnotationFreeTextBounds:(CPDFFreeTextAnnotation *)activeAnnotation];
    }
}

#pragma mark - NSMenu

- (NSMenu *)menuForEvent:(NSEvent *)event {
    if (self.annotationType == CAnnotationTypeInk || self.annotationType == CAnnotationTypeEraser) {
        return nil;
    }
    NSMenu *menu = [super menuForEvent:event];
    if(!menu)
        menu = [[NSMenu alloc] init];
    
    NSPoint pagePoint = NSZeroPoint;
    CPDFPage *page = [self pageAndPoint:&pagePoint forEvent:event nearest:YES];
    NSMenuItem * copyItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", @"PDFListView") action:@selector(copy:) keyEquivalent:@"c"];
    
    NSMenuItem * pasteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Paste", @"PDFListView") action:@selector(menuItemClick_Paste:) keyEquivalent:@"v"];
    pasteItem.representedObject = event;
    NSMenuItem * cutItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Cut", @"PDFListView") action:@selector(cut:) keyEquivalent:@"x"];
    
    NSMenuItem * deleteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Delete", @"PDFListView") action:@selector(delete:) keyEquivalent:@""];
    
    NSMenu *subMenu = nil;
    NSMenuItem * arrangementItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Arrangement", @"PDFListView") action:nil keyEquivalent:@""];
    subMenu = [[NSMenu alloc] init];
    
    NSMenuItem * bringForwardItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Bring Forward", @"PDFListView") action:@selector(menuItemClick_BringForward:) keyEquivalent:@""];
    NSMenuItem * sendBackForwardItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Send Backward", @"PDFListView") action:@selector(menuItemClick_SendBackward:) keyEquivalent:@""];
    NSMenuItem * bringFrontItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Bring to Front", @"PDFListView") action:@selector(menuItemClick_BringFront:) keyEquivalent:@""];
    NSMenuItem * sendBackItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Send to Back", @"PDFListView") action:@selector(menuItemClick_SendBack:) keyEquivalent:@""];
    [subMenu addItem:bringForwardItem];
    [subMenu addItem:sendBackForwardItem];
    [subMenu addItem:bringFrontItem];
    [subMenu addItem:sendBackItem];
    arrangementItem.submenu = subMenu;
    
    NSMenuItem * editNoteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Edit Note", @"PDFListView") action:@selector(menuItemClick_EditNote:) keyEquivalent:@""];

    if(0) {
      
        
    } else {
        CPDFAnnotation *annotation = nil;
        
        for (CPDFAnnotation *tAnnotation in page.annotations) {
            if ([tAnnotation hitTest:pagePoint]) {
                annotation = tAnnotation;
                break;
            }
        }
        
        if (annotation && [annotation isKindOfClass:[CPDFWidgetAnnotation class]] ){
           
        }
        
        if(annotation) {
            if(![self.activeAnnotations containsObject:annotation]) {
                [self updateIsRightActiveAnnotations:@[annotation]];
                [self setNeedsDisplayAnnotation:annotation];
            }
        }
        
        if(annotation && [annotation isKindOfClass:[CPDFWidgetAnnotation class]]) {
            annotation = nil;
        } else if(annotation && [annotation isKindOfClass:[CPDFRedactAnnotation class]]) {
            annotation = nil;
        } else if (annotation && [annotation isKindOfClass:[CPDFInkAnnotation class]] && [self annotationType] == CAnnotationTypeInk) {
            annotation = nil;
        }
        

        CPDFSelection *selection = [self creatImageCurrentSelectionForPoint:[event locationInPDFListView:self]];
        if(selection && CPDFSelectionTypeImage == [selection selectionType] && !self.activeAnnotation){
            self.currentSelection = selection;
        }
        
        NSMenu *subMenu = [[NSMenu alloc] init];
        if(self.activeAnnotations.count == 1) {
//            NSMenuItem * lineStyleItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Line Style", @"PDFListView") action:@selector(menuItemClick_LineStyle:) keyEquivalent:@""];
//            
//            subMenu = [[NSMenu alloc] init];
//            NSMenuItem * lineSolidItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Solid", @"PDFListView") action:@selector(menuItemClick_LineStyle:) keyEquivalent:@""];
//            lineSolidItem.tag = CPDFBorderStyleSolid;
//            NSMenuItem * lineDashedItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Dashed", @"PDFListView") action:@selector(menuItemClick_LineStyle:) keyEquivalent:@""];
//            lineDashedItem.tag = CPDFBorderStyleDashed;
//
//            [subMenu addItem:lineSolidItem];
//            [subMenu addItem:lineDashedItem];
//            lineStyleItem.submenu = subMenu;
//
//            NSMenuItem * changeColorItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Color...", @"PDFListView") action:@selector(menuItemClick_ChangeColor:) keyEquivalent:@""];

//            [menu insertItem:arrangementItem atIndex:0];
//            [menu insertItem:[NSMenuItem separatorItem] atIndex:0];

//            if([self.activeAnnotation isKindOfClass:[CPDFMarkupAnnotation class]] ||
//               [self.activeAnnotation isKindOfClass:[CPDFStampAnnotation class]] ||
//               [self.activeAnnotation isKindOfClass:[CPDFSignatureAnnotation class]]) {
//                [menu insertItem:editNoteItem atIndex:0];
//            } else if ([self.activeAnnotation isKindOfClass:[CPDFInkAnnotation class]]) {
//                [menu insertItem:editNoteItem atIndex:0];
//                [menu insertItem:lineStyleItem atIndex:0];
//                [menu insertItem:changeColorItem atIndex:0];
//            } else if ([self.activeAnnotation isKindOfClass:[CPDFTextAnnotation class]]) {
//                [menu insertItem:editNoteItem atIndex:0];
//                [menu insertItem:changeColorItem atIndex:0];
//            } else if ([self.activeAnnotation isKindOfClass:[CPDFSquareAnnotation class]] ||
//                       [self.activeAnnotation isKindOfClass:[CPDFCircleAnnotation class]] ||
//                       [self.activeAnnotation isKindOfClass:[CPDFLineAnnotation class]]) {
//                [menu insertItem:editNoteItem atIndex:0];
//                if([self.activeAnnotation isKindOfClass:[CPDFLineAnnotation class]]) {
//                    NSMenuItem * directionItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Direction", @"PDFListView") action:nil keyEquivalent:@""];
//                    subMenu = [[NSMenu alloc]init];
//                    
//                    NSMenuItem * lineHorizontalItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Horizontal", @"PDFListView") action:@selector(menuItemClick_LineHorizontal:) keyEquivalent:@""];
//                    NSMenuItem * lineVerticalItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Vertical", @"PDFListView") action:@selector(menuItemClick_LineVertical:) keyEquivalent:@""];
//                    [subMenu addItem:lineHorizontalItem];
//                    [subMenu addItem:lineVerticalItem];
//                    directionItem.submenu = subMenu;
//                    
//                    [menu insertItem:directionItem atIndex:0];
//                }
//                [menu insertItem:lineStyleItem atIndex:0];
//                [menu insertItem:changeColorItem atIndex:0];
//            }
            if ([self.activeAnnotation isKindOfClass:[CPDFSignatureWidgetAnnotation class]]) {
                CPDFSignatureWidgetAnnotation *aa = (CPDFSignatureWidgetAnnotation *)self.activeAnnotation;
                CPDFSignature *aaa = aa.signature;
                [menu insertItem:[NSMenuItem separatorItem] atIndex:0];
                [menu insertItem:deleteItem atIndex:0];
            }
//            if(![self.activeAnnotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
//                if ([[NSPasteboard generalPasteboard] canReadObjectForClasses:[NSArray arrayWithObjects:[CPDFAnnotation class], [NSString class],[NSImage class], nil] options:[NSDictionary dictionary]]) {
//                    [menu insertItem:pasteItem atIndex:0];
//                }
//                [menu insertItem:cutItem atIndex:0];
//            }
//            [menu insertItem:copyItem atIndex:0];
            __block typeof(self) blockSelf = self;

            
        } else if (self.activeAnnotations.count > 1) {
            BOOL isMarkupAn = NO;
            for (CPDFAnnotation *annotation in self.activeAnnotations) {
                if([annotation isKindOfClass:[CPDFMarkupAnnotation class]]) {
                    isMarkupAn = YES;
                    break;
                }
            }
            
//            [menu insertItem:arrangementItem atIndex:0];
            [menu insertItem:[NSMenuItem separatorItem] atIndex:0];
            [menu insertItem:deleteItem atIndex:0];
            if(!isMarkupAn) {
                [menu insertItem:cutItem atIndex:0];
                [menu insertItem:copyItem atIndex:0];
            }
        } else if (self.currentSelection) {
            if(CPDFSelectionTypeImage == [self.currentSelection selectionType]) {
                NSMenuItem * exportImageItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Export…", nil) action:@selector(menuItemClick_ExportImage:) keyEquivalent:@""];

                [menu insertItem:exportImageItem atIndex:0];
                [menu insertItem:[NSMenuItem separatorItem] atIndex:0];
            }
            if ([[NSPasteboard generalPasteboard] canReadObjectForClasses:[NSArray arrayWithObjects:[CPDFAnnotation class], [NSString class],[NSImage class], nil] options:[NSDictionary dictionary]]) {
                [menu insertItem:pasteItem atIndex:0];
            }
            [menu insertItem:copyItem atIndex:0];
        } else if (!self.activeAnnotation) {
//            NSMenuItem * pageDisplayItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Page Display", @"PDFListView") action:nil keyEquivalent:@""];
//            subMenu = [[NSMenu alloc] init];
//
//            NSMenuItem * twoPagesContinuousItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Two Pages Continuous", @"PDFListView") action:@selector(menuItemClick_TwoPagesContinuous:) keyEquivalent:@""];
//            NSMenuItem * twoPagesItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Two Pages", @"PDFListView") action:@selector(menuItemClick_TwoPages:) keyEquivalent:@""];
//            NSMenuItem * singlePageContinuousItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Single Page Continuous", @"PDFListView") action:@selector(menuItemClick_SinglePagesContinuous:) keyEquivalent:@""];
//            NSMenuItem * singlePageItem =  [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Single Page", @"PDFListView") action:@selector(menuItemClick_SinglePage:) keyEquivalent:@""];
//            NSMenuItem * bookModeItem =  [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Book Mode", @"PDFListView") action:@selector(menuItemClick_BookMode:) keyEquivalent:@""];
//            switch (self.displayViewMode) {
//                case CPDFDisplayViewSinglePageContinuous:
//                    singlePageContinuousItem.state = NSControlStateValueOn;
//                    break;
//                case CPDFDisplayViewTwoUp:
//                    if (self.displaysAsBook)
//                        bookModeItem.state = NSControlStateValueOn;
//                    else
//                        twoPagesItem.state = NSControlStateValueOn;
//                    break;
//                case CPDFDisplayViewTwoUpContinuous:
//                    if (self.displaysAsBook)
//                        bookModeItem.state = NSControlStateValueOn;
//                    else
//                        twoPagesContinuousItem.state = NSControlStateValueOn;
//                    break;
//                default:
//                case CPDFDisplayViewSinglePage:
//                    singlePageItem.state = NSControlStateValueOn;
//                    break;
//            }
//
//            [subMenu addItem:singlePageItem];
//            [subMenu addItem:singlePageContinuousItem];
//            [subMenu addItem:twoPagesItem];
//            [subMenu addItem:twoPagesContinuousItem];
//            [subMenu addItem:bookModeItem];
//            pageDisplayItem.submenu = subMenu;
//            
//            [menu insertItem:pageDisplayItem atIndex:0];
//
//            NSMenuItem *zoomItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Zoom", @"PDFListView") action:nil keyEquivalent:@""];
//            subMenu = [[NSMenu alloc]init];
//
//            NSMenuItem * fitWidthItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Fit Width", @"PDFListView") action:@selector(menuItemClick_FitWidth:) keyEquivalent:@""];
//            NSMenuItem * automaticallyItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Automatically Resize", @"PDFListView") action:@selector(menuItemClick_AutomaticallyResize:) keyEquivalent:@""];
//            NSMenuItem * actualSizeItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Actual Size", @"PDFListView") action:@selector(menuItemClick_ActualSize:) keyEquivalent:@""];
//            NSMenuItem * zoomInItem =  [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Zoom In", @"PDFListView") action:@selector(menuItemClick_ZoomIn:) keyEquivalent:@""];
//            NSMenuItem * zoomOutItem =  [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Zoom Out", @"PDFListView") action:@selector(menuItemClick_ZoomOut:) keyEquivalent:@""];
//            
//            NSMenuItem * hidenShowNoteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Hide Notes", @"PDFListView") action:@selector(menuItemClick_HidenorShowNote:) keyEquivalent:@""];
//            
//            if (self.autoScales) {
//                automaticallyItem.state = NSControlStateValueOn;
//            } else if (self.scaleFactor == 1.0) {
//                actualSizeItem.state = NSControlStateValueOn;
//            }
//            
//           
//            
//            [subMenu addItem:fitWidthItem];
//            [subMenu addItem:automaticallyItem];
//            [subMenu addItem:actualSizeItem];
//            [subMenu addItem:zoomInItem];
//            [subMenu addItem:zoomOutItem];
//            zoomItem.submenu = subMenu;
//            [menu insertItem:zoomItem atIndex:0];
//            
//            [menu insertItem:[NSMenuItem separatorItem] atIndex:0];
//            [menu insertItem:hidenShowNoteItem atIndex:0];
//            [menu insertItem:[NSMenuItem separatorItem] atIndex:0];
//            [menu insertItem:pasteItem atIndex:0];

        }
    }
    
//    if ([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewMenuForEvent:forEvent:clickMenu:)]) {
//        [self.pdfListViewDelegate PDFListViewMenuForEvent:self forEvent:event clickMenu:&menu];
//    }
    
    return menu;
}

- (void)updateIsRightActiveAnnotations:(NSArray<CPDFAnnotation *> *)activeAnnotations {
    [self refreshActiveAnnotations:activeAnnotations isRight:YES];
}

- (IBAction)delete:(id)sender {
    if (self.activeAnnotations.count > 0 ) {
        NSMutableArray *tarr = [NSMutableArray arrayWithArray:self.activeAnnotations];
        for (CPDFAnnotation * an in tarr) {
//            if(self.hoverAnnotation == an) {
//                self.hoverAnnotation = nil;
//            }
            [self removeAnnotation:an];
            [[self undoManager] setActionName:NSLocalizedString(@"Remove Note", @"Undo action name")];
            if([an isKindOfClass:[CPDFFreeTextAnnotation class]]) {
                CPDFFreeTextAnnotation *freeTextAn = (CPDFFreeTextAnnotation *)an;
                if ([self isEditWithCurrentFreeText:freeTextAn]) {
                    [self commitEditAnnotationFreeText:freeTextAn];
                }
            }
        }
        [self removeActiveAnnotations:tarr];
    } else {
        NSBeep();
    }
}

- (void)removeAnnotation:(CPDFAnnotation *)annotation {
    CPDFAnnotation *wasAnnotation = annotation;
    CPDFPage *page = wasAnnotation.page;
    
    [[[self undoManager] prepareWithInvocationTarget:self] addAnnotation:wasAnnotation toPage:page];
    
    [page removeAnnotation:wasAnnotation];
    [self annotationsChangedOnPage:page];
    [self setNeedsDisplayAnnotation:wasAnnotation];

//    dispatch_async(dispatch_get_main_queue(), ^{
//        [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewDidRemoveAnnotationNotification object:self
//                                                          userInfo:[NSDictionary dictionaryWithObjectsAndKeys:wasAnnotation, CPDFListViewAnnotationKey, page, CPDFListViewPageKey, nil]];
//    });
//    
//    if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewRemoveAnnotations:forRemoveAnnotations:inPage:)])
//        [self.pdfListViewDelegate PDFListViewRemoveAnnotations:self forRemoveAnnotations:@[annotation] inPage:page];
}

- (void)removeActiveAnnotations:(NSArray<CPDFAnnotation *> *)removeAnnotations {
    BOOL isContains = NO;
    NSMutableArray *tarr = [NSMutableArray arrayWithArray:self.activeAnnotations];
    [tarr removeObjectsInArray:removeAnnotations];
    self.activeAnnotations = tarr;
    isContains = YES;
    
    if(isContains) {
        if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewDeleteAnnotation:forAnnotation:)])
            [self.pdfListViewDelegate PDFListViewDeleteAnnotation:self forAnnotation:removeAnnotations.firstObject];

        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewActiveAnnotationsChangeNotification object:self];
        });
    }

//    if(isContains) {
//        if([self.pdfListViewDelegate respondsToSelector:@selector(PDFListViewChangeatioActiveAnnotations:forActiveAnnotations:isRightMenu:)])
//            [self.pdfListViewDelegate PDFListViewChangeatioActiveAnnotations:self forActiveAnnotations:self.activeAnnotations isRightMenu:NO];
//        
//        dispatch_async(dispatch_get_main_queue(), ^{
//            [[NSNotificationCenter defaultCenter] postNotificationName:CPDFListViewActiveAnnotationsChangeNotification object:self];
//        });
//    }
}

@end