/*
SRBrowserControllerAction.m

Author: Makoto Kinoshita

Copyright 2004-2006 The Shiira Project. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted 
provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions 
  and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of 
  conditions and the following disclaimer in the documentation and/or other materials provided 
  with the distribution.

THIS SOFTWARE IS PROVIDED BY THE SHIIRA PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE SHIIRA PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.
*/

#import "SRBookmark.h"

#import "SRConstants.h"

#import "SRAppController.h"
#import "SRBrowserController.h"
#import "SRBrowserDocument.h"
#import "SRDefaultKeys.h"
#import "SRFullScreenImageController.h"
#import "SRPageController.h"
#import "SRPageInfoController.h"
#import "SRSearchFieldController.h"
#import "SRSourceWindowController.h"
#import "SRTabExposeController.h"
#import "SRURLCompleteDataSource.h"

#import "SRBookmarkButton.h"
#import "SRBookmarkMenuProvider.h"
#import "SRMenu.h"
#import "SRSearchField.h"
#import "SREncodings.h"

#import "SRPreference.h"
#import "SRPrefDefaultKeys.h"

#import "SRPlugInController.h"

#import "RSSRepresentation.h"

@interface SRBrowserController (private)
- (NSArray*)_createUntitledLabels:(int)numberOfLabels;
- (NSString*)_createUntitledLabel;
@end

@interface SRBrowserController (actions)
- (void)URLComboBoxAction:(id)sender;
- (void)showPageInfoAction:(id)sender;
@end

@implementation SRBrowserController (action)

//--------------------------------------------------------------//
#pragma mark -- File menu actions --
//--------------------------------------------------------------//

- (void)openLocationAction:(id)sender
{
    // Get toolbar
    NSToolbar*  toolbar;
    toolbar = [[self window] toolbar];
    
    // When no URL combo box on toolbar
    if (![toolbar isVisible] || 
        ![self URLComboBox] || 
        [toolbar displayMode] == NSToolbarDisplayModeLabelOnly) 
    {
        if (![self URLComboBoxOnSheet]) {
            // Create URL combo box
            HMImageComboBox*    locationURLComboBox;
            locationURLComboBox = [[HMImageComboBox alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)];
            [locationURLComboBox autorelease];
            [[locationURLComboBox cell] setControlSize:NSSmallControlSize];
            [locationURLComboBox setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
            //[locationURLComboBox setImage:[[WebIconDatabase sharedIconDatabase] defaultIconWithSize:NSMakeSize(16, 16)]];
            [[locationURLComboBox cell] setSendsActionOnEndEditing:NO];
            [locationURLComboBox setCompletes:YES];
            [locationURLComboBox setDelegate:self];
            [locationURLComboBox setTarget:self];
            [locationURLComboBox setAction:@selector(closeLocationPanelAction:)];
            [locationURLComboBox sizeToFit];
            
            // Set data source
            [locationURLComboBox setUsesDataSource:YES];
            _locationURLDataSource = [[SRURLCompleteDataSource alloc] init];
            [locationURLComboBox setDataSource:_locationURLDataSource];
            
            NSRect  frame;
            frame = [[self locationURLView] frame];
            frame.origin = NSZeroPoint;
            [locationURLComboBox setFrame:frame];
            [locationURLComboBox setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
            
            [[self locationURLView] addSubview:locationURLComboBox];
        }
        
        // Show location panel
        [NSApp beginSheet:[self locationPanel] 
                modalForWindow:[self window] 
                modalDelegate:self 
                didEndSelector:@selector(_locationPanelDidEnd:returnCode:contextInfo:) 
                contextInfo:NULL];
        return;
    }
    
    // Make combo box first responder
    [[self window] makeFirstResponder:[self URLComboBox]];
}

- (void)closeLocationPanelAction:(id)sender
{
    // End sheet
    [NSApp endSheet:[self locationPanel] returnCode:[sender tag]];
}

- (void)_locationPanelDidEnd:(NSWindow*)sheet 
        returnCode:(int)returnCode 
        contextInfo:(void*)contextInfo
{
    // Close location panel
    [sheet orderOut:self];
    
    // For not go button
    if (returnCode != 0) {
        return;
    }
    
    // Treat as URL combo action
    [self URLComboBoxAction:[self URLComboBoxOnSheet]];
}

- (void)newTabAction:(id)sender
{
    // Create untitled label
    NSString*   label;
    label = [self _createUntitledLabel];
    
    // Add new tab
    [self addNewTabWithLabel:label frameName:nil groupName:nil select:YES];
}

- (void)closeTabAction:(id)sender
{
    // Count current tab
    int count;
    count = [_tabView numberOfTabViewItems];
    if (count < 2) {
        // Do nothing
        return;
    }
    
    // Get index for closing
    int index;
    
    // By clicking close button on the tab
    if ([sender isKindOfClass:[NSButton class]]) {
        index = [_tabView indexOfCloseButton:sender];
    }
    else {
        // Get selected index
        index = [_tabView indexOfSelectedTabViewItem];
        
        int i;
        for (i = 0; i < count; i++) {
            HMTabViewItem*  tabViewItem;
            tabViewItem = [_tabView tabViewItemAtIndex:index];
            if (tabViewItem) {
                if ([tabViewItem status] == HMTabViewItemNormal) {
                    break;
                }
            }
            
            index--;
            if (index < 0) {
                index = count - 1;
            }
        }
        
        if (i == count) {
            index = NSNotFound;
        }
    }
    
    if (index == NSNotFound) {
        // Do nothing
        return;
    }
    
    // Remove tab
    [self removeTabAtIndex:index];
}

- (void)emailPageLocationAction:(id)sender
{
    // Get selected web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    
    // Get URL string
    NSString*   URLString;
    URLString = [[[[[webView mainFrame] dataSource] request] URL] absoluteString];
    if (!URLString) {
        return;
    }
    
    NSString*   title;
    NSString*   subject;
    title = [[[webView mainFrame] dataSource] pageTitle];
    subject = [NSString stringWithFormat:@"SUBJECT=%@",
            [title stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    
    // enclose URL in angle-brackets so that long URLs survive linebreaks
    // in transit. e.g. <http://hmdt-web.net/shiira/en>
    NSString *body = [NSString stringWithFormat:@"BODY=%@",
            [[NSString stringWithFormat:@"\n\n<%@>", URLString] 
            stringByAddingPercentEscapesUsingEncoding: NSASCIIStringEncoding]];
    
    NSString *urlString = [NSString stringWithFormat:@"mailto:%@?%@&%@",
            @"", subject, body];
    
    NSURL *mailtoUrl = [NSURL URLWithString: urlString];
    [[NSWorkspace sharedWorkspace] openURL: mailtoUrl];
}

- (void)emailPageContentsAction:(id)sender
{
    OSStatus    err;
    
    // Get application for mailto scheme
    NSURL*      mailtoURL;
    CFURLRef    mailerURLRef;
    NSString*   mailerPath;
    NSURL*      mailerURL;
    mailtoURL = [NSURL URLWithString:@"mailto:xxx"];
    err = LSGetApplicationForURL((CFURLRef)mailtoURL, kLSRolesAll, NULL, &mailerURLRef);
    if (err != noErr) {
        // Error
        NSLog(@"Can't decide mailer, %d", err);
        return;
    }
    mailerPath = [(NSURL*)mailerURLRef path];
    CFRelease(mailerURLRef);
    
    // Get mailer bundle
    NSBundle*   bundle;
    bundle = [NSBundle bundleWithPath:mailerPath];
    if (!bundle) {
        // Error
        NSLog(@"Can't get bundle for mailer, %@", mailerURL);
        return;
    }
    
    // Check mailer availability
    NSDictionary*   infoPlist;
    NSNumber*       mailPageSupported;
    infoPlist = [bundle infoDictionary];
    mailPageSupported = [infoPlist objectForKey:@"MailPageSupported"];
    if (!mailPageSupported || ![mailPageSupported boolValue]) {
        // Show alert
        NSAlert*    alert;
        alert = [[NSAlert alloc] init];
        [alert setMessageText:NSLocalizedString(@"Couldn't send a page contents email", nil)];
        [alert setInformativeText:[NSString stringWithFormat:
                NSLocalizedString(@"Because %@ doesn't support sending Web pages.", nil), 
                [mailerPath lastPathComponent]]];
        [alert setAlertStyle:NSWarningAlertStyle];
        [alert beginSheetModalForWindow:[self window] 
                modalDelegate:self 
                didEndSelector:@selector(mailPageAlertDidEnd:returnCode:contextInfo:) 
                contextInfo:nil];
        
        return;
    }
    
    // Get bundle identifier
    NSString*   bundleId;
    const char* bundleIdChar;
    bundleId = [bundle bundleIdentifier];
    bundleIdChar = [bundleId UTF8String];
    if (!bundleIdChar) {
        // Error
        NSLog(@"bundleIdChar is NULL");
        return;
    }
    
    // Launch mailer
    if (![[NSWorkspace sharedWorkspace] 
            launchAppWithBundleIdentifier:bundleId 
            options:NSWorkspaceLaunchAsync 
            additionalEventParamDescriptor:nil 
            launchIdentifier:NULL])
    {
        // Error
        NSLog(@"Failed to launch application, %@", bundleId);
        return;
    }
    
    // Get web archive
    WebView*    webView;
    WebArchive* webArchive;
    webView = [[self selectedPageController] webView];
    webArchive = [[[webView mainFrame] dataSource] webArchive];
    if (!webArchive) {
        return;
    }
    
    // Get title
    NSString*   title;
    title = [[[webView mainFrame] dataSource] pageTitle];
    
    // Create AppleEvent
    NSAppleEventDescriptor* tdtaDesc;
    NSAppleEventDescriptor* titleDesc;
    NSAppleEventDescriptor* targetDesc;
    NSAppleEventDescriptor* appleEvent;
    tdtaDesc = [NSAppleEventDescriptor 
            descriptorWithDescriptorType:'tdta' data:[webArchive data]];
    titleDesc = [NSAppleEventDescriptor 
            descriptorWithString:title];
    targetDesc = [NSAppleEventDescriptor 
            descriptorWithDescriptorType:typeApplicationBundleID 
            bytes:bundleIdChar 
            length:strlen(bundleIdChar)];
    
    appleEvent = [NSAppleEventDescriptor 
            appleEventWithEventClass:'mail' 
            eventID:'mlpg' 
            targetDescriptor:targetDesc 
            returnID:kAutoGenerateReturnID 
            transactionID:kAnyTransactionID];
    [appleEvent setParamDescriptor:tdtaDesc forKeyword:keyDirectObject];
    [appleEvent setParamDescriptor:titleDesc forKeyword:'urln'];
    
    // Send AppleEvent
    err = AESendMessage([appleEvent aeDesc], NULL, kAECanInteract, kAEDefaultTimeout);
    if (err != noErr) {
        // Error
        NSLog(@"Failed to send AppleEvent, %d", err);
        return;
    }
}

- (void)mailPageAlertDidEnd:(NSAlert*)alert returnCode:(int)returnCode contextInfo:(void*)contextInfo
{
    [alert release];
}

- (void)printPageAsPDFAction:(id)sender
{
    // Get selected web view and document view
    WebView*    webView;
    NSView*     documentView;
    webView = [[self selectedPageController] webView];
    documentView = [[[webView mainFrame] frameView] documentView];
    if (!documentView) {
        return;
    }
    
    // Get title
    NSString*   title;
    title = [[[webView mainFrame] dataSource] pageTitle];
    if (!title || [title length] == 0) {
        title = NSLocalizedString(@"Untitled", nil);
    }
    
    // Get accessory view
    SRBrowserDocument*  document;
    NSView*             accessoryView;
    document = [self document];
    accessoryView = [document printAccessoryView];
    
    // Set properties of print panel
    WebPreferences* preferences;
    preferences = [SRPreference webPreferences];
    [document setValue:[NSNumber numberWithBool:[preferences shouldPrintBackgrounds]] 
            forKey:SRBrowserDocumentPrintBackground];
    
    // Show save dialog
    NSSavePanel*    savePanel;
    savePanel = [NSSavePanel savePanel];
    [savePanel setAccessoryView:accessoryView];
    [savePanel beginSheetForDirectory:nil 
            file:[title stringByAppendingPathExtension:@"pdf"] 
            modalForWindow:[self window] 
            modalDelegate:self 
            didEndSelector:@selector(didEndPrintPageAsPDFPanel:returnCode:contextInfo:) 
            contextInfo:NULL];
}

- (void)didEndPrintPageAsPDFPanel:(NSSavePanel*)sheet 
        returnCode:(int)returnCode 
        contextInfo:(void*)contextInfo
{
    if (returnCode != NSOKButton) {
        return;
    }
    
    // Get selected web view and document view
    WebView*    webView;
    NSView*     documentView;
    webView = [[self selectedPageController] webView];
    documentView = [[[webView mainFrame] frameView] documentView];
    if (!documentView) {
        return;
    }
    
    // Get file name
    NSString*   fileName;
    fileName = [sheet filename];
    if (!fileName) {
        return;
    }
    
    // Print page as a PDF
    [[documentView dataWithPDFInsideRect:[documentView frame]] 
            writeToFile:fileName atomically:YES];
}

//--------------------------------------------------------------//
#pragma mark -- Edit menu actions --
//--------------------------------------------------------------//

- (void)findByToolbarAction:(id)sender
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Get toolbar
    NSToolbar*  toolbar;
    toolbar = [[self window] toolbar];
    
    // When no search field on toolbar
    if (![toolbar isVisible] || 
        ![self searchField] || 
        [toolbar displayMode] == NSToolbarDisplayModeLabelOnly) 
    {
        if (![self searchFieldOnSheet]) {
            // Create search field
            SRSearchField*  searchFieldOnSheet;
            searchFieldOnSheet = [[SRSearchField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)];
            [searchFieldOnSheet autorelease];
            [[searchFieldOnSheet cell] setControlSize:NSSmallControlSize];
            [searchFieldOnSheet setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
            [searchFieldOnSheet sizeToFit];
            [searchFieldOnSheet setTag:0];
            [searchFieldOnSheet setTarget:self];
            [searchFieldOnSheet setAction:@selector(closeSearchPanelAction:)];
            [[searchFieldOnSheet cell] setWraps:NO];
            [[searchFieldOnSheet cell] setScrollable:YES];
            [[searchFieldOnSheet cell] setSendsWholeSearchString:YES];
            
            NSRect  frame;
            frame = [[self searchFieldView] frame];
            frame.origin = NSZeroPoint;
            [searchFieldOnSheet setFrame:frame];
            [searchFieldOnSheet setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
            
            [[self searchFieldView] addSubview:searchFieldOnSheet];
        }
        
        // Set search field to controller
        [_searchFieldController setSearchField:[self searchFieldOnSheet]];
        
        // Show search panel
        [NSApp beginSheet:[self searchPanel] 
                modalForWindow:[self window] 
                modalDelegate:self 
                didEndSelector:@selector(_searchPanelDidEnd:returnCode:contextInfo:) 
                contextInfo:NULL];
        
        return;
    }
    
    // Focus on search field
    [[self window] makeFirstResponder:[self searchField]];
}

//--------------------------------------------------------------//
#pragma mark -- View menu actions --
//--------------------------------------------------------------//

- (void)toggleToolbarAction:(id)sender
{
    // Toogle toolbar
    [[self window] toggleToolbarShown:sender];
}

- (void)toggleBookmarksBarAction:(id)sender
{
    // Toggle bookmarks bar
    [self setBookmarkBarVisible:![self isBookmarkBarVisible] display:YES];
}

- (void)showShelfAction:(id)sender
{
    // Get selected web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    
    // Check URL
    NSString*   URLString;
    URLString = [[[[[webView mainFrame] dataSource] request] URL] absoluteString];
    if ([URLString hasPrefix:@"shiira://shelf"]) {
        return;
    }
    
    // Open 'shiira://shelf'
    NSURLRequest*   request;
    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"shiira://shelf"]];
    [[webView mainFrame] loadRequest:request];
}

- (void)customizeToolbarAction:(id)sender
{
    // Run toolbar customize panel
    [[[self window] toolbar] runCustomizationPalette:self];
}

- (void)reloadPageAction:(id)sender
{
    // Get selected web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    
    // Get URL string
    NSString*   urlString;
    urlString = [[[[[webView mainFrame] dataSource] request] URL] absoluteString];
    
    // For error URL
    if ([urlString hasSuffix:@"Shiira/template/tmpError.html"]) {
        // Get URL from address field
        urlString = [_browserContent valueForKey:@"URLString"];
        if (urlString && [urlString length] > 0) {
            [self openURLString:urlString];
            return;
        }
    }
    
    // Get modifier key
    unsigned    modifierFlags;
    unsigned    shiftFlag;
    modifierFlags = [[NSApp currentEvent] modifierFlags];
    shiftFlag = modifierFlags & NSShiftKeyMask;
    
    if (!shiftFlag) {
        // Reload page
        [webView reload:sender];
    }
    else {
        // Reload without cache
        NSURLRequest*   request;
        NSURLRequest*   requestWithoutCache;
        request = [[[webView mainFrame] dataSource] request];
        requestWithoutCache = [NSURLRequest requestWithURL:[request URL] 
                cachePolicy:NSURLRequestReloadIgnoringCacheData 
                timeoutInterval:[request timeoutInterval]];
        [self openRequest:requestWithoutCache];
    }
}

- (void)stopLoadingAction:(id)sender
{
    // Get selected web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    
    // Stop loading
    [webView stopLoading:sender];
}

- (void)biggerTextAction:(id)sender
{
    // Get selected web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    
    // Bigger text
    [webView makeTextLarger:sender];
}

- (void)smallerTextAction:(id)sender
{
    // Get selected web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    
    // Smaller text
    [webView makeTextSmaller:sender];
}

- (void)setBrowseModeAction:(id)sender
{
    int tag = 0;
    
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(tag)]) {
        tag = [sender tag];
    }
    
    // Set browse mode
    int browseMode = -1;
    switch (tag) {
    case SRDefaultBrowsingTag: {
        browseMode = SRDefaultBrowseMode;
        break;
    }
    case SRSingleWindowModeTag: {
        browseMode = SRSingleWindowMode;
        break;
    }
    case SRSmartBrowseModeTag: {
        browseMode = SRSmartBrowseMode;
        break;
    }
    }
    
    if (browseMode > -1) {
        [[NSUserDefaults standardUserDefaults] setInteger:browseMode forKey:SRBrowseMode];
    }
}

- (void)switchToFullScreenAction:(id)sender
{
    [self switchToFullScreenWithMenu:NO];
}

- (void)switchToFullScreenWithMenuAction:(id)sender
{
    [self switchToFullScreenWithMenu:YES];
}

- (void)backToNormalModeAction:(id)sender
{
    [self backToNormalMode];
}

- (void)viewPageSourceAction:(id)sender
{
    // Get page controller
    SRPageController*   pageController;
    pageController = [self selectedPageController];
    
    // Get page info controller
    SRPageInfoController*   pageInfoController;
    pageInfoController = [SRPageInfoController pageInfoControllerWithPageController:pageController];
    
    // Show window
    [[pageInfoController window] makeKeyAndOrderFront:self];
    
    // Select source
    [pageInfoController setProfileWithTitle:NSLocalizedString(@"HTML", nil)];
}

- (void)setTextEncodingAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(tag)]) {
        // Get web view
        WebView*    webView;
        webView = [[self selectedPageController] webView];
        
        // Get encoding value
        int encoding;
        encoding = [sender tag];
        
        // For default
        if (encoding == SRTextEncodingDefaultTag) {
            [webView setCustomTextEncodingName:nil];
            return;
        }
        
        // Get encoding name
        NSString*   encodingName;
        encodingName = [[NSValueTransformer valueTransformerForName:SREncodingToIANATransformerName] 
                transformedValue:[NSNumber numberWithInt:encoding]];
        if (encodingName) {
            [webView setCustomTextEncodingName:encodingName];
        }
    }
}

//--------------------------------------------------------------//
#pragma mark -- Browse menu actions --
//--------------------------------------------------------------//

- (void)openURLWithAction:(id)sender
{
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Get bundle identifier
            NSString*   bundleId;
            bundleId = [representedObject path];
            
            // Get current URL
            NSURL*  url;
            url = [[[[[[self selectedPageController] webView] mainFrame] dataSource] request] URL];
            if (!url) {
                return;
            }
            
            // Open URL
            [[NSWorkspace sharedWorkspace] 
                    openURLs:[NSArray arrayWithObject:url] 
                    withAppBundleIdentifier:bundleId 
                    options:0 
                    additionalEventParamDescriptor:nil 
                    launchIdentifiers:nil];
        }
    }
}

//--------------------------------------------------------------//
#pragma mark -- History menu actions --
//--------------------------------------------------------------//

- (void)goBackAction:(id)sender
{
    // Get selected web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    
    // Send action to web view
    [webView goBack:sender];
}

- (void)goForwardAction:(id)sender
{
    // Get selected web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    
    // Send action to web view
    [webView goForward:sender];
}

- (void)goHomeAction:(id)sender
{
    // Get home page URL
    NSString*   URLString;
    URLString = [[NSUserDefaults standardUserDefaults] stringForKey:SRGeneralHomePage];
    if (!URLString || [URLString length] == 0) {
        return;
    }
    
    [self openURLString:URLString];
}

- (void)openHistoryItemAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For WebHistoryItem
        if ([representedObject isKindOfClass:[WebHistoryItem class]]) {
            // Check in back forward list
            WebView*            webView;
            WebBackForwardList* list;
            webView = [[self selectedPageController] webView];
            list = [webView backForwardList];
            if ([list containsItem:representedObject]) {
                // Go to item
                [webView goToBackForwardItem:representedObject];
                
                // Notify it
                //[[NSNotificationCenter defaultCenter] 
                //        postNotificationName:SRMainWindowGoToHistotyItem object:webView];
            }
            else {
                // Open URL
                [self openURLString:[representedObject URLString]];
            }
        }
    }
}

//--------------------------------------------------------------//
#pragma mark -- Bookmark menu actions --
//--------------------------------------------------------------//

- (void)addToBookmarkAction:(id)sender
{
    // Get current page URL, title
    NSString*   URLString = nil;
    NSString*   title;
    
#if 0
    // For RSS
    BOOL    isRSS = NO;
#endif
    
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSDictionary
        if ([representedObject isKindOfClass:[NSDictionary class]]) {
            // Get URL and title
            NSURL*      linkURL;
            linkURL = [representedObject objectForKey:WebElementLinkURLKey];
            URLString = [linkURL _web_userVisibleString];
            if (!URLString) {
                return;
            }
            title = [representedObject objectForKey:WebElementLinkLabelKey];
            if (!title) {
                title = URLString;
            }
        }
    }
    
    // Get address from selected web view
    if (!URLString) {
        // Get request and page info
        WebDataSource*  dataSource;
        NSURLRequest*   request;
        dataSource = [[[[self selectedPageController] webView] mainFrame] dataSource];
        request = [dataSource request];
        if (!request) {
            return;
        }
        URLString = [[request URL] _web_userVisibleString];
        title = [dataSource pageTitle];
        if (!title) {
            title = URLString;
        }
        
#if 0
        // Get MIME type
        NSURLResponse*  response;
        NSString*       MIMEType;
        response = [dataSource response];
        MIMEType = [response MIMEType];
        if ([[SRRSSRepresentation RSSMimes] containsObject:MIMEType]) {
            isRSS = YES;
        }
#endif
    }
    
    // Set title to add bookmark text field
    NSText* text;
    text = [[self addBookmarkTextField] currentEditor];
    [[self addBookmarkTextField] setStringValue:title];
    [text moveToBeginningOfDocument:self];
    [text selectAll:self];
    
    // Set URL string
    [_addBookmarkURLString release];
    _addBookmarkURLString = [URLString copy];
    
#if 0
    // For RSS
    if (isRSS) {
        [bookmark setType:SRBookmarkTypeRSS];
    }
#endif
    
    // Set folder menu
    NSMenu* folderMenu;
    folderMenu = SRBookmarkFolderMenu(
            [[SRAppController sharedInstance] rootBookmarkOfBrowser:SRBrowserShiira]);
    [[self addBookmarkPopup] removeAllItems];
    [[self addBookmarkPopup] setMenu:folderMenu];
    
    // Show add bookmark panel
    [NSApp beginSheet:[self addBookmarkPanel] 
            modalForWindow:[self window] 
            modalDelegate:self 
            didEndSelector:@selector(_didEndAddBookmarkSheet:returnCode:contextInfo:) 
            contextInfo:NULL];
}

- (void)_didEndAddBookmarkSheet:(NSPanel*)sheet 
        returnCode:(int)returnCode 
        contextInfo:(void*)contextInfo
{
    // Close sheet
    [sheet orderOut:self];
    
    // Check return code
    if (returnCode != NSOKButton) {
        return;
    }
    
    // Get bookmark title
    NSString*   title;
    title = [[self addBookmarkTextField] stringValue];
    if (!title) {
        title = @"";
    }
    
    // Create bookmark
    SRBookmark* bookmark;
    bookmark = [SRBookmark bookmarkWithTitle:title 
            URLString:_addBookmarkURLString 
            context:[[SRAppController sharedInstance] managedObjectContext] 
            persistentStore:[[SRAppController sharedInstance] persistentStore]];
    if (!bookmark) {
        return;
    }
    
    // Get parent
    SRBookmark* parent;
    parent = [[[self addBookmarkPopup] selectedItem] representedObject];
    if (!parent) {
        return;
    }
    
    // Add bookmark
    [parent addBookmarks:[NSArray arrayWithObject:bookmark]];
}

- (void)closeAddBookmarkSheetAction:(id)sender
{
    // Close sheet
    [NSApp endSheet:[self addBookmarkPanel] returnCode:[sender tag]];
}

- (void)showNewFolderAction:(id)sender
{
    // Show new folder dialog as modal
    int result;
    result = [NSApp runModalForWindow:[self newFolderPanel]];
    [[self newFolderPanel] orderOut:self];
    if (result != NSOKButton) {
        return;
    }
    
    // Get folder name
    NSString*   folderName;
    folderName = [[self newFolderTextField] stringValue];
    if (!folderName || [folderName length] == 0) {
        return;
    }
    
    //
    // Create new bookmark folder
    //
    
    // Get bookmark popup
    NSPopUpButton*  popup = nil;
    if ([[self addBookmarkPanel] isVisible]) {
        popup = [self addBookmarkPopup];
    }
#if 0
    if ([[self bookmarkAllPanel] isVisible]) {
        popup = [self bookmarkAllPopup];
    }
#endif
    if (!popup) {
        return;
    }
    
    // Get parent bookmark folder
    SRBookmark* parent = nil;
    parent = [[popup selectedItem] representedObject];
    if (!parent) {
        return;
    }
    
    // Add bookmark folder
    SRBookmark* folder;
    folder = [SRBookmark folderWithTitle:folderName 
            context:[[SRAppController sharedInstance] managedObjectContext] 
            persistentStore:[[SRAppController sharedInstance] persistentStore]];
    [parent addBookmarks:[NSArray arrayWithObject:folder]];
    
    // Update folder menu
    NSMenu* folderMenu;
    folderMenu = SRBookmarkFolderMenu(
            [[SRAppController sharedInstance] rootBookmarkOfBrowser:SRBrowserShiira]);
    [popup removeAllItems];
    [popup setMenu:folderMenu];
    
    // Select new one
    int index;
    index = [popup indexOfItemWithRepresentedObject:folder];
    if (index != -1) {
        [popup selectItemAtIndex:index];
    }
}

- (void)closeNewFolderPanelAction:(id)sender
{
    // Cloase new folder panel
    [NSApp stopModalWithCode:[sender tag]];
}

//--------------------------------------------------------------//
#pragma mark -- Window menu actions --
//--------------------------------------------------------------//

- (void)showAllTabsAction:(id)sender
{
    // Deexpose
    if ([SRTabExposeController isExposing]) {
        [_tabExposeController deexpose];
        return;
    }
    
    // Check number of tab
    if ([_tabView numberOfTabViewItems] < 2) {
        return;
    }
    
    // Expose
    [_tabExposeController expose];
}

- (void)previousTabAction:(id)sender
{
    // Get selected index
    int selectedIndex;
    int numberOfItems;
    selectedIndex = [_tabView indexOfSelectedTabViewItem];
    numberOfItems = [_tabView numberOfTabViewItems];
    if (selectedIndex == -1) {
        return;
    }
    
    // Select previous tab
    if (selectedIndex > 0) {
        [_tabView selectTabViewItemAtIndex:selectedIndex - 1];
    }
    else {
        [_tabView selectTabViewItemAtIndex:numberOfItems - 1];
    }
}

- (void)nextTabAction:(id)sender
{
    // Get item number and selected index
    int numberOfItems;
    int selectedIndex;
    numberOfItems = [_tabView numberOfTabViewItems];
    selectedIndex = [_tabView indexOfSelectedTabViewItem];
    if (selectedIndex == -1) {
        return;
    }
    
    // Select next tab
    if (numberOfItems > selectedIndex + 1) {
        [_tabView selectTabViewItemAtIndex:selectedIndex + 1];
    }
    else {
        [_tabView selectTabViewItemAtIndex:0];
    }
}

- (void)showPageInfoAction:(id)sender
{
    // Get page controller
    SRPageController*   pageController;
    pageController = [self selectedPageController];
    
    // Get page info controller
    SRPageInfoController*   pageInfoController;
    pageInfoController = [SRPageInfoController pageInfoControllerWithPageController:pageController];
    
    // Show window
    [[pageInfoController window] makeKeyAndOrderFront:self];
    
    // Select general
    [pageInfoController setProfileWithTitle:NSLocalizedString(@"General Info", nil)];
}

- (void)showWebInspectorAction:(id)sender
{
    // Get Web inspector
    WebInspector*   inspector;
    inspector = [NSClassFromString(@"WebInspector") sharedWebInspector];
    if (!inspector) {
        return;
    }
    
    // Get page controller
    SRPageController*   pageController;
    pageController = [self selectedPageController];
    
    // Set Web frame
    [inspector setWebFrame:[[pageController webView] mainFrame]];
    
    // Show window
    [inspector showWindow:self];
}

//--------------------------------------------------------------//
#pragma mark -- Toolbar actions --
//--------------------------------------------------------------//

- (void)processComboBoxURLString:(NSString*)URLString
{
    // Check argument
    if (!URLString || [URLString length] == 0 || [URLString isEqualToString:@"http://"]) {
        // Do not open page
        [[self window] makeFirstResponder:[self URLComboBox]];
        return;
    }
    
    // Get selected page controller
    SRPageController*   pageController;
    pageController = [self selectedPageController];
    
    // Create request
    NSURLRequest*   request;
    request = [self createRequestWithURLString:URLString];
    
    // Open request with action
    SROpenActionType    openAction;
    openAction = SROpenActionTypeFromModifierFlags([[NSApp currentEvent] modifierFlags], YES, YES);
    [self openRequest:request frameName:nil groupName:nil withOpenAction:openAction];
}

- (void)URLComboBoxAction:(id)sender
{
    // Get string
    NSString*   string;
    string = [sender stringValue];
    
    // handle search keyword if one was entered
    NSDictionary* searchEngine = nil;
#if 0
    NSRange whitespaceRange;
    whitespaceRange = [string rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]];
    
    if(whitespaceRange.length) {
        NSString* keyword;
        keyword = [string substringWithRange:NSMakeRange(0,whitespaceRange.location)];
        
        NSEnumerator* enumerator;
        enumerator = [[[SRSearchEnginesManager sharedInstance] searchEngines] objectEnumerator];
        
        NSDictionary* eachEngine;
        
        while((searchEngine == nil) && (eachEngine = [enumerator nextObject])) {
            if([[eachEngine objectForKey:@"keyword"] isEqualToString:keyword]) {
                searchEngine = eachEngine;
            }
        }
    }
#endif
    
    NSString*   URLString = nil;
    
    // Create URL string from search engine template
    if(searchEngine) {
#if 0
        NSRange searchTermRange;
        searchTermRange = NSMakeRange(NSMaxRange(whitespaceRange),[string length] - NSMaxRange(whitespaceRange));
                                      
        NSString* searchTerm;
        searchTerm = [string substringWithRange:searchTermRange];
        
        URLString = SRCreateSearchURLStringFromSearchEngine(searchTerm, searchEngine);
#endif
    }
    else {
        // Get URL string from combo box
        URLString = [[sender dataSource] absoluteURLStringOfCompletedString:string];
    }
    
    // Open URL string
    [self processComboBoxURLString:URLString];
}

- (void)searchAction:(id)sender
{
}

- (void)openPlugInAction:(id)sender
{
    // Get identifier
    NSString*   itemIdentifier;
    itemIdentifier = [sender itemIdentifier];
    
    // Get info dicts
    NSArray*        plugInInfoDicts;
    NSEnumerator*   enumerator;
    NSDictionary*   infoDict;
    plugInInfoDicts = [[SRPlugInController sharedInstance] plugInInfoDicts];
    enumerator = [plugInInfoDicts objectEnumerator];
    while (infoDict = [enumerator nextObject]) {
        if ([itemIdentifier isEqualToString:[infoDict objectForKey:@"CFBundleIdentifier"]]) {
            // Get scheme
            NSString*   scheme;
            scheme = [infoDict objectForKey:@"SRPlugInScheme"];
            if (scheme) {
                // Open shceme
                [self openURLString:scheme];
            }
        }
    }
}

//--------------------------------------------------------------//
#pragma mark -- Bookmark bar actions --
//--------------------------------------------------------------//

- (void)openBookmarkBarBookmarkAction:(id)sender
{
    // Get bookmark
    SRBookmark* bookmark = nil;
    if ([sender respondsToSelector:@selector(bookmark)]) {
        bookmark = [sender bookmark];
    }
    if (!bookmark) {
        return;
    }
    
    // For folder
    if ([[bookmark isFolder] boolValue]) {
        if ([[bookmark isAutoTab] boolValue]) {
            // Open in tabs
            [self openInTabsBookmark:bookmark];
        }
    }
    // For HTML
    else {
        // Open bookmark
        [self openBookmark:bookmark];
    }
}

- (void)openBookmarkAction:(id)sender
{
    // Get bookmark as represented object
    SRBookmark* bookmark;
    bookmark = [sender representedObject];
    if (!bookmark || ![bookmark isKindOfClass:[SRBookmark class]]) {
        return;
    }
    
    // Open bookmark
    [self openBookmark:bookmark];
}

- (void)openBookmarkInTabsAction:(id)sender
{
    // Get bookmarks as represented object
    NSArray*    bookmarks;
    bookmarks = [sender representedObject];
    if (!bookmarks || ![bookmarks isKindOfClass:[NSArray class]]) {
        return;
    }
    
    // Open bookmark in tabs
    [self openInTabsBookmarks:bookmarks];
}

//--------------------------------------------------------------//
#pragma mark -- Status bar actions --
//--------------------------------------------------------------//

- (void)togglePageDockAction:(id)sender
{
    // Toggle page dock
    BOOL    isVisible;
    isVisible = [self isPageDockVisible];
    [self setPageDockVisible:!isVisible];
}

- (void)toggleFeedAction:(id)sender
{
    // Get web view and data source
    WebView*        webView;
    WebDataSource*  dataSource;
    webView = [[self selectedPageController] webView];
    dataSource = [[webView mainFrame] dataSource];
    
    // Get representation
    id<WebDocumentRepresentation>   representation;
    representation = [dataSource representation];
    
    // For RSS representation
    if ([representation isKindOfClass:NSClassFromString(@"RSSRepresentation")]) {
        // Get link
        NSString*   link;
        link = [(RSSRepresentation*)representation link];
        if (link) {
            // Open HTML
            [self openURLString:link];
        }
        
        return;
    }
    
    // Get RSS links
    NSArray*    links;
    links = [webView RSSLinks];
    if ([links count] < 1) {
        return;
    }
    
    // Open RSS
    NSString*   URLString;
    URLString = [links objectAtIndex:0];
    [self openURLString:URLString];
}

- (void)toggleIDNAction:(id)sender
{
    // Get URL string
    NSString*   urlString;
    urlString = [[[[[[[self selectedPageController] webView] mainFrame] 
            dataSource] request] URL] absoluteString];
    if (!urlString || [urlString length] == 0) {
        return;
    }
    
    // Create URL
    NSURL*  url;
    url = [NSURL _web_URLWithUserTypedString:urlString];
    
    // Use Punycode
    if ([_IDNButton state] == NSOnState) {
        [_browserContent setValue:[url _web_userVisibleString] forKey:@"URLString"];
    }
    // Use ASCII
    else {
        [_browserContent setValue:[url absoluteString] forKey:@"URLString"];
    }
}

- (void)toggleLockedAction:(id)sender
{
}

- (void)showCookieAction:(id)sender
{
    // Get page controller
    SRPageController*   pageController;
    pageController = [self selectedPageController];
    
    // Get page info controller
    SRPageInfoController*   pageInfoController;
    pageInfoController = [SRPageInfoController pageInfoControllerWithPageController:pageController];
    
    // Show window
    [[pageInfoController window] makeKeyAndOrderFront:self];
    
    // Select source
    [pageInfoController setProfileWithTitle:NSLocalizedString(@"Cookies", nil)];
}

//--------------------------------------------------------------//
#pragma mark -- Tab context menu actions --
//--------------------------------------------------------------//

- (void)closeThisTabAction:(id)sender
{
    // For NSMenuItem
    if ([sender isKindOfClass:[NSMenuItem class]]) {
        // Get represented object
        id  representedObject;
        representedObject = [sender representedObject];
        
        // Get tab index
        int index;
        index = [_tabView indexOfTabViewItem:representedObject];
        if (index != NSNotFound) {
            // Remove tab
            [self removeTabAtIndex:index];
        }
    }
}

- (void)closeAllRightTabsAction:(id)sender
{
    // For NSMenuItem
    if ([sender isKindOfClass:[NSMenuItem class]]) {
        // Get represented object
        id  representedObject;
        representedObject = [sender representedObject];
        
        // Get tab index
        int index;
        index = [_tabView indexOfTabViewItem:representedObject];
        if (index != NSNotFound) {
            // Remove tabs
            NSIndexSet* indexSet;
            indexSet = [NSIndexSet indexSetWithIndexesInRange:
                    NSMakeRange(index + 1, [_tabView numberOfTabViewItems] - (index + 1))];
            [self removeTabAtIndexes:indexSet];
        }
    }
}

- (void)closeAllLeftTabsAction:(id)sender
{
    // For NSMenuItem
    if ([sender isKindOfClass:[NSMenuItem class]]) {
        // Get represented object
        id  representedObject;
        representedObject = [sender representedObject];
        
        // Get tab index
        int index;
        index = [_tabView indexOfTabViewItem:representedObject];
        if (index != NSNotFound) {
            // Remove tabs
            NSIndexSet* indexSet;
            indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, index)];
            [self removeTabAtIndexes:indexSet];
        }
    }
}

- (void)closeAllOtherTabsAction:(id)sender
{
    // For NSMenuItem
    if ([sender isKindOfClass:[NSMenuItem class]]) {
        // Get represented object
        id  representedObject;
        representedObject = [sender representedObject];
        
        // Get tab index
        int index;
        index = [_tabView indexOfTabViewItem:representedObject];
        if (index != NSNotFound) {
            // Remove tabs
            NSMutableIndexSet*  indexSet;
            indexSet = [NSMutableIndexSet indexSet];
            [indexSet addIndexesInRange:
                    NSMakeRange(0, index)];
            [indexSet addIndexesInRange:
                    NSMakeRange(index + 1, [_tabView numberOfTabViewItems] - (index + 1))];
            [self removeTabAtIndexes:indexSet];
        }
    }
}

//--------------------------------------------------------------//
#pragma mark -- Bookmark context menu actions --
//--------------------------------------------------------------//

- (void)openBookmarkInNewTabAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For SRBookmark
        if ([representedObject isKindOfClass:[SRBookmark class]]) {
            [self openInNewTabBookmark:representedObject select:YES];
        }
    }
}

- (void)openBookmarkInNewWindowAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For SRBookmark
        if ([representedObject isKindOfClass:[SRBookmark class]]) {
            [self openInNewWindowBookmark:representedObject];
        }
    }
}

- (void)openBookmarkInNewBackgroundTabAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For SRBookmark
        if ([representedObject isKindOfClass:[SRBookmark class]]) {
            [self openInNewTabBookmark:representedObject select:NO];
        }
    }
}

- (void)openBookmarkInNewBackgroundWindowAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For SRBookmark
        if ([representedObject isKindOfClass:[SRBookmark class]]) {
            [self openInNewBackgroundWindowBookmark:representedObject];
        }
    }
}

- (void)deleteBookmarkAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For SRBookmark
        if ([representedObject isKindOfClass:[SRBookmark class]]) {
            // Get parent
            SRBookmark* parent;
            parent = [representedObject valueForKey:@"parent"];
            
            // Remove bookmark
            [parent removeBookmarks:[NSArray arrayWithObject:representedObject]];
        }
    }
}

- (void)createNewBookmarkFolderAction:(id)sender
{

}

//--------------------------------------------------------------//
#pragma mark -- Web view context menu actions --
//--------------------------------------------------------------//

- (void)openLinkInNewTabAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Open request in new tab
            [self openInNewTabURL:representedObject select:YES];
        }
    }
}

- (void)openLinkInNewBackgroundTabAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Open request in new tab
            [self openInNewTabURL:representedObject select:NO];
        }
    }
}

- (void)openLinkInNewWindowAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Open request in new window
            [self openInNewWindowURL:representedObject];
        }
    }
}

- (void)openLinkInNewBackgroundWindowAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Open request in new backround window
            [self openInNewBackgroundWindowURL:representedObject];
        }
    }
}

- (void)openAllLinksInNewTabsAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSArray
        if ([representedObject isKindOfClass:[NSArray class]]) {
            // Open request in new tabs
            [self openInNewTabsURLStrings:representedObject select:YES];
        }
    }
}

- (void)openAllLinksInNewBackgroundTabsAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSArray
        if ([representedObject isKindOfClass:[NSArray class]]) {
            // Open request in background tabs
            [self openInNewTabsURLStrings:representedObject select:NO];
        }
    }
}

- (void)downloadLinkedFileAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Download it
            [self openURL:representedObject withOpenAction:SROpenOptionAction];
        }
    }
}

- (void)downloadLinkedFileToLocationAction:(id)sender
{
}

- (void)copyLinkURLToClipboardAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSDictionary
        if ([representedObject isKindOfClass:[NSDictionary class]]) {
            // Get pasteboard
            NSPasteboard*   pboard;
            NSArray*        types;
            pboard = [NSPasteboard generalPasteboard];
            types = [NSPasteboard _web_writableTypesForURL];
            
            // Copy link
            [pboard declareTypes:types owner:self];
            [pboard _web_writeURL:[representedObject objectForKey:WebElementLinkURLKey] 
                    andTitle:[representedObject objectForKey:WebElementLinkLabelKey] 
                    types:types];
        }
    }
}

- (void)downloadImageAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Download it
            [self openURL:representedObject withOpenAction:SROpenOptionAction];
        }
    }
}

- (void)downloadImageToLocationAction:(id)sender
{
}

- (void)copyImageToClipboardAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSDictionary
        if ([representedObject isKindOfClass:[NSDictionary class]]) {
            // Get pasteboard
            NSPasteboard*   pboard;
            NSArray*        types;
            pboard = [NSPasteboard generalPasteboard];
            types = [NSPasteboard _web_writableTypesForImageIncludingArchive:
                    ([representedObject objectForKey:WebElementDOMNodeKey] != nil)];
            
            // Get link URL
            NSURL*  linkURL;
            linkURL = [representedObject objectForKey:WebElementLinkURLKey];
            
            // Copy image
            [pboard declareTypes:types owner:self];
            [pboard _web_writeImage:[representedObject objectForKey:WebElementImageKey] 
                    URL:linkURL ? linkURL : (NSURL*)[representedObject objectForKey:WebElementImageURLKey] 
                    title:[representedObject objectForKey:WebElementImageAltStringKey] 
                    archive:[[representedObject objectForKey:WebElementDOMNodeKey] webArchive] 
                    types:types];
        }
    }
}

- (void)copyImageURLToClipboardAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSDictionary
        if ([representedObject isKindOfClass:[NSDictionary class]]) {
            // Get pasteboard
            NSPasteboard*   pboard;
            NSArray*        types;
            pboard = [NSPasteboard generalPasteboard];
            types = [NSPasteboard _web_writableTypesForURL];
            
            // Copy link
            [pboard declareTypes:types owner:self];
            [pboard _web_writeURL:[representedObject objectForKey:WebElementImageURLKey] 
                    andTitle:[representedObject objectForKey:WebElementImageAltStringKey] 
                    types:types];
        }
    }
}

- (void)openImageInFullScreenAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSDictionary
        if ([representedObject isKindOfClass:[NSDictionary class]]) {
            // Get image
            id  image;
            image = [representedObject objectForKey:WebElementImageKey];
            if (![image isKindOfClass:[NSImage class]]) {
                if ([image respondsToSelector:@selector(image)]) {
                    image = [image image];
                }
            }
            if (!image) {
                return;
            }
            
            // Create full screen image window
            if (!_fullScreenImageController) {
                _fullScreenImageController = [[SRFullScreenImageController alloc] init];
            }
            [_fullScreenImageController showWindow:self];
            
            // Set image
            [_fullScreenImageController setImage:image];
        }
    }
}

- (void)openTextAsURLAction:(id)sender
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Get selected string
    NSString*   string = nil;
    if ([sender respondsToSelector:@selector(representedObject)]) {
        string = [sender representedObject];
    }
    if (!string) {
        return;
    }
    
    // Remove white characters
    string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    
    // Try it as URL
    NSURL*  url;
    url = [NSURL URLWithString:string];
    if (url) {
        // Get scheme
        NSString*   scheme;
        scheme = [url scheme];
        if ([scheme isEqualToString:@"ttp"] || 
            [scheme isEqualToString:@"tp"] || 
            [scheme isEqualToString:@"p"])
        {
            string = [NSString stringWithFormat:@"http%@", [string substringFromIndex:[scheme length]]];
        }
    }
    else {
        // Insert 'http://'
        if (![string hasPrefix:@"http://"]) {
            string = [NSString stringWithFormat:@"http://%@", string];
        }
    }
    
    // Check tab browsing
    BOOL    selectNewTabs;
    selectNewTabs = [defaults boolForKey:SRTabSelectNewTabs];
    
    // Always search with new tab or new window action
    SROpenActionType    openAction;
    openAction = SROpenActionTypeFromModifierFlags(
            [[NSApp currentEvent] modifierFlags], YES, selectNewTabs);
    if (openAction == SROpenOptionAction || openAction == SROpenAction) {
        openAction = selectNewTabs ? SROpenInNewTabAction : SROpenInNewBackgroundTabAction;
    }
    [self openURLString:string withOpenAction:openAction];
}

- (void)openFrameInNewTabAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Open URL
            [self openInNewTabURL:representedObject select:YES];
        }
    }
}

- (void)openFrameInNewBackgroundTabAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Open URL
            [self openInNewTabURL:representedObject select:NO];
        }
    }
}

- (void)openFrameInNewWindowAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Open URL
            [self openInNewWindowURL:representedObject];
        }
    }
}

- (void)openFrameInNewBackgroundWindowAction:(id)sender
{
    // For NSMenuItem
    if ([sender respondsToSelector:@selector(representedObject)]) {
        id  representedObject;
        representedObject = [sender representedObject];
        
        // For NSURL
        if ([representedObject isKindOfClass:[NSURL class]]) {
            // Open URL
            [self openInNewBackgroundWindowURL:representedObject];
        }
    }
}

- (void)viewFrameSourceAction:(id)sender
{
}

- (void)findBySearchEngineAction:(id)sender
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    if (![self searchField]) {
        return;
    }
    
    // Get web view
    WebView*    webView;
    webView = [[self selectedPageController] webView];
    if (!webView) {
        return;
    }
    
    // Get information for search
    NSDictionary*   searchItem;
    NSString*       searchString;
    NSString*       engineName;
    NSString*       engineUUID;
    NSString*       URLString;
    searchItem = [sender representedObject];
    searchString = [searchItem objectForKey:@"string"];
    engineName = [searchItem objectForKey:@"title"];
    engineUUID = [searchItem objectForKey:@"engineUuid"];
    URLString = [searchItem objectForKey:@"URLString"];
    
    // Add to recent item
//    [[SRSearchEnginesManager sharedInstance] addRecentWord:searchString 
//            engineName:engineName 
//            engineUUID:engineUUID 
//            URLString:URLString];
    
    // Check tab browsing
    BOOL    selectNewTabs;
    selectNewTabs = [defaults boolForKey:SRTabSelectNewTabs];
    
    // Always search with new tab or new window action
    SROpenActionType    openAction;
    openAction = SROpenActionTypeFromModifierFlags(
            [[NSApp currentEvent] modifierFlags], YES, selectNewTabs);
    if (openAction == SROpenOptionAction || openAction == SROpenAction) {
        openAction = selectNewTabs ? SROpenInNewTabAction : SROpenInNewBackgroundTabAction;
    }
    [self openURLString:URLString withOpenAction:openAction];
}

@end

