/*
SRPredictEncoding.m

Author: Hiroyuki Yamashita

Copyright 2004 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 "SRPredictEncoding.h"

#import "WebKitEx.h"
#import "SRDOMFilter.h"

@implementation SRPredictEncoding

//--------------------------------------------------------------//
#pragma mark -- Initialize --
//--------------------------------------------------------------//

- (void)dealloc
{
    [_templateURL release];
    [_webView release];
    
    [super dealloc];
}

//--------------------------------------------------------------//
#pragma mark -- Predict encoding --
//--------------------------------------------------------------//

- (void)processPredictionWithTemplateURL:(NSString*)templateURL delegate:(id)delegate
{
    // Set instance variables
    _templateURL = [templateURL copy];
    _delegate = delegate;
    
    // Create request
    NSString*       URLString;
    NSURLRequest*   request;
    URLString = [NSString stringWithFormat:templateURL, @"Shiira"];
    request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString] 
            cachePolicy:NSURLRequestUseProtocolCachePolicy 
            timeoutInterval:5];
    
    // Create web view and send request
    [_webView release];
    _webView = [[WebView alloc] initWithFrame:NSZeroRect];
    [_webView setPreferencesIdentifier:@"PredictEncoding"];
    [[_webView preferences] setDefaultTextEncodingName:@"shift_jis"];
    [_webView setFrameLoadDelegate:self];
    [[_webView mainFrame] loadRequest:request];
}

//--------------------------------------------------------------//
#pragma mark -- Accessors --
//--------------------------------------------------------------//

- (NSString*)templateURL
{
    return _templateURL;
}

- (NSString *)textEncodingName
{
    // Get data source
    WebDataSource*  dataSource;
    dataSource = [[_webView mainFrame] dataSource];
    if (!dataSource || [dataSource isLoading]) {
        // Warning
        NSLog(@"dataSource is nil or loading");
        return nil;
    }
    
    // Get text encoding name
    NSString*   textEncodingName;
    textEncodingName = [dataSource textEncodingName];
    if (textEncodingName) {
        return textEncodingName;
    }
    
    // Get from HTTP equiv
    NSDictionary*   dict;
    dict = [_webView HTTPEquivalents];
    textEncodingName = [dict objectForKey:@"content-type"];
    if (!textEncodingName) {
        textEncodingName = [dict objectForKey:@"Content-type"];
    }
    if (!textEncodingName) {
        textEncodingName = [dict objectForKey:@"Content-Type"];
    }
    if (textEncodingName) {
        NSArray*        components;
        NSEnumerator*   enumerator;
        NSString*       component;
        components = [textEncodingName componentsSeparatedByString:@";"];
        enumerator = [components objectEnumerator];
        while (component = [enumerator nextObject]) {
            if ([component rangeOfString:@"charset"].location != NSNotFound) {
                NSRange range;
                range = [component rangeOfString:@"="];
                if (range.location != NSNotFound) {
                    textEncodingName = [component substringFromIndex:range.location + range.length];
                    textEncodingName = [textEncodingName stringByTrimmingCharactersInSet:
                            [NSCharacterSet whitespaceCharacterSet]];
                    
                    return textEncodingName;
                }
            }
        }
    }
    
    return nil;
}

- (NSStringEncoding)textEncoding
{
    // Get text encoding name
    NSString*   textEncodingName;
    textEncodingName = [self textEncodingName];
    if (!textEncodingName) {
        return 0;
    }
    
    // Convert to text encoding
    CFStringEncoding encoding;

    if ([textEncodingName caseInsensitiveCompare:@"shift_jis"] == NSOrderedSame) {
        return NSShiftJISStringEncoding;
    }
    encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)textEncodingName);
    return CFStringConvertEncodingToNSStringEncoding(encoding);
}

//--------------------------------------------------------------//
#pragma mark -- WebView load frame delegate --
//--------------------------------------------------------------//

- (void)_notify
{
    if (_delegate && [_delegate respondsToSelector:@selector(predictEncodingDone:)]) {
        [_delegate predictEncodingDone:self];
    }
}

- (void)webView:(WebView*)webView didFinishLoadForFrame:(WebFrame*)frame
{
    if ([webView mainFrame] == frame) {
        [self _notify];
    }
}

- (void)webView:(WebView*)webView 
        didFailProvisionalLoadWithError:(NSError*)error 
        forFrame:(WebFrame*)frame
{
    if ([webView mainFrame] == frame) {
        [self _notify];
    }
}

- (void)webView:(WebView*)webView 
        didFailLoadWithError:(NSError*)error 
        forFrame:(WebFrame*)frame
{
    if ([webView mainFrame] == frame) {
        [self _notify];
    }
}

@end
