/*
 * Copyright (C) 2009 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS 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.
 */

#if PLATFORM(IOS_FAMILY)

#import "WebVisiblePosition.h"
#import "WebVisiblePositionInternal.h"

#import <WebCore/DocumentMarkerController.h>
#import <WebCore/Editing.h>
#import <WebCore/FrameSelection.h>
#import <WebCore/HTMLTextFormControlElement.h>
#import <WebCore/Node.h>
#import <WebCore/Position.h>
#import <WebCore/Range.h>
#import <WebCore/RenderTextControl.h>
#import <WebCore/RenderedDocumentMarker.h>
#import <WebCore/TextBoundaries.h>
#import <WebCore/TextFlags.h>
#import <WebCore/TextGranularity.h>
#import <WebCore/TextIterator.h>
#import <WebCore/VisiblePosition.h>
#import <WebCore/VisibleUnits.h>


#import "DOMNodeInternal.h"
#import "DOMRangeInternal.h"

using namespace WebCore;

//-------------------

@implementation WebVisiblePosition (Internal)

// Since VisiblePosition isn't refcounted, we have to use new and delete on a copy.

+ (WebVisiblePosition *)_wrapVisiblePosition:(VisiblePosition)visiblePosition
{
    WebVisiblePosition *vp = [[WebVisiblePosition alloc] init];
    VisiblePosition *copy = new VisiblePosition(visiblePosition);
    vp->_internal = reinterpret_cast<WebObjectInternal *>(copy);
    return [vp autorelease];
}

// Returns nil if visible position is null.
+ (WebVisiblePosition *)_wrapVisiblePositionIfValid:(VisiblePosition)visiblePosition
{
    return (visiblePosition.isNotNull() ? [WebVisiblePosition _wrapVisiblePosition:visiblePosition] : nil);
}

- (VisiblePosition)_visiblePosition
{
    VisiblePosition *vp = reinterpret_cast<VisiblePosition *>(_internal);
    return *vp;
}

@end

@implementation WebVisiblePosition

- (void)dealloc
{
    VisiblePosition *vp = reinterpret_cast<VisiblePosition *>(_internal);
    delete vp;
    _internal = nil;
    [super dealloc];
}

// FIXME: Overriding isEqual: without overriding hash will cause trouble if this ever goes into an NSSet or is the key in an NSDictionary,
// since two equal objects could have different hashes.
- (BOOL)isEqual:(id)other
{
    if (![other isKindOfClass:[WebVisiblePosition class]])
        return NO;
    return [self _visiblePosition] == [(WebVisiblePosition *)other _visiblePosition];
}

- (NSComparisonResult)compare:(WebVisiblePosition *)other
{
    VisiblePosition myVP = [self _visiblePosition];
    VisiblePosition otherVP = [other _visiblePosition];
    
    if (myVP == otherVP)
        return NSOrderedSame;
    else if (myVP < otherVP)
        return NSOrderedAscending;
    else
        return NSOrderedDescending;
}

- (int)distanceFromPosition:(WebVisiblePosition *)other
{
    return distanceBetweenPositions([self _visiblePosition], [other _visiblePosition]);
}

- (NSString *)description
{
    
    NSMutableString *description = [NSMutableString stringWithString:[super description]];
    VisiblePosition vp = [self _visiblePosition];
    int offset = vp.deepEquivalent().offsetInContainerNode();

    [description appendFormat:@"(offset=%d, context=([%c|%c], [u+%04x|u+%04x])", offset, vp.characterBefore(), vp.characterAfter(),
        vp.characterBefore(), vp.characterAfter()];
    
    return description;
}


- (TextDirection)textDirection
{
    // TODO: implement
    return TextDirection::LTR;
}

- (BOOL)directionIsDownstream:(WebTextAdjustmentDirection)direction
{
    if (direction == WebTextAdjustmentBackward)
        return NO;
    
    if (direction == WebTextAdjustmentForward)
        return YES;
    
    
    if ([self textDirection] == TextDirection::LTR)
        return (direction == WebTextAdjustmentRight);
    return (direction == WebTextAdjustmentLeft);
}

- (WebVisiblePosition *)positionByMovingInDirection:(WebTextAdjustmentDirection)direction amount:(UInt32)amount withAffinityDownstream:(BOOL)affinityDownstream
{
    VisiblePosition vp = [self _visiblePosition];
                          
    vp.setAffinity(affinityDownstream ? DOWNSTREAM : VP_UPSTREAM_IF_POSSIBLE);

    switch (direction) {
        case WebTextAdjustmentForward: {
            for (UInt32 i = 0; i < amount; i++)
                vp = vp.next();
            break;
        }
        case WebTextAdjustmentBackward: {
            for (UInt32 i = 0; i < amount; i++)
                vp = vp.previous();
            break;
        }
        case WebTextAdjustmentRight: {
            for (UInt32 i = 0; i < amount; i++)
                vp = vp.right();
            break;
        }
        case WebTextAdjustmentLeft: {
            for (UInt32 i = 0; i < amount; i++)
                vp = vp.left();
            break;
        }
        case WebTextAdjustmentUp: {
            int xOffset = vp.lineDirectionPointForBlockDirectionNavigation();
            for (UInt32 i = 0; i < amount; i++)
                vp = previousLinePosition(vp, xOffset);            
            break;
        }
        case WebTextAdjustmentDown: {
            int xOffset = vp.lineDirectionPointForBlockDirectionNavigation();
            for (UInt32 i = 0; i < amount; i++)
                vp = nextLinePosition(vp, xOffset);            
            break;
        }
        default: {
            ASSERT_NOT_REACHED();
            break;
        }
    }
    return [WebVisiblePosition _wrapVisiblePositionIfValid:vp];
}

- (WebVisiblePosition *)positionByMovingInDirection:(WebTextAdjustmentDirection)direction amount:(UInt32)amount

{
    return [self positionByMovingInDirection:direction amount:amount withAffinityDownstream:YES];
}

static inline TextGranularity toTextGranularity(WebTextGranularity webGranularity)
{
    TextGranularity granularity;
    
    switch (webGranularity) {
        case WebTextGranularityCharacter:
            granularity = CharacterGranularity;
            break;

        case WebTextGranularityWord:
            granularity = WordGranularity;
            break;

        case WebTextGranularitySentence:
            granularity = SentenceGranularity;
            break;

        case WebTextGranularityLine:
            granularity = LineGranularity;
            break;

        case WebTextGranularityParagraph:
            granularity = ParagraphGranularity;
            break;

        case WebTextGranularityAll:
            granularity = DocumentGranularity;
            break;

        default:
            ASSERT_NOT_REACHED();
            break;
    }
            
    return granularity;
}

static inline SelectionDirection toSelectionDirection(WebTextAdjustmentDirection direction)
{
    SelectionDirection result;
    
    switch (direction) {
        case WebTextAdjustmentForward:
            result = DirectionForward;
            break;
            
        case WebTextAdjustmentBackward:
            result = DirectionBackward;
            break;
            
        case WebTextAdjustmentRight:
            result = DirectionRight;
            break;
            
        case WebTextAdjustmentLeft:
            result = DirectionLeft;
            break;
        
        case WebTextAdjustmentUp:
            result = DirectionLeft;
            break;
        
        case WebTextAdjustmentDown:
            result = DirectionRight;
            break;
    }

    return result;
}

// Returnes YES only if a position is at a boundary of a text unit of the specified granularity in the particular direction.
- (BOOL)atBoundaryOfGranularity:(WebTextGranularity)granularity inDirection:(WebTextAdjustmentDirection)direction
{
    return atBoundaryOfGranularity([self _visiblePosition], toTextGranularity(granularity), toSelectionDirection(direction));
}

// Returns the next boundary position of a text unit of the given granularity in the given direction, or nil if there is no such position.
- (WebVisiblePosition *)positionOfNextBoundaryOfGranularity:(WebTextGranularity)granularity inDirection:(WebTextAdjustmentDirection)direction
{
    return [WebVisiblePosition _wrapVisiblePositionIfValid:positionOfNextBoundaryOfGranularity([self _visiblePosition], toTextGranularity(granularity), toSelectionDirection(direction))];
}

// Returns YES if position is within a text unit of the given granularity.  If the position is at a boundary, returns YES only if
// if the boundary is part of the text unit in the given direction.
- (BOOL)withinTextUnitOfGranularity:(WebTextGranularity)granularity inDirectionIfAtBoundary:(WebTextAdjustmentDirection)direction
{
    return withinTextUnitOfGranularity([self _visiblePosition], toTextGranularity(granularity), toSelectionDirection(direction));
}

// Returns range of the enclosing text unit of the given granularity, or nil if there is no such enclosing unit.  Whether a boundary position
// is enclosed depends on the given direction, using the same rule as -[WebVisiblePosition withinTextUnitOfGranularity:inDirectionAtBoundary:].
- (DOMRange *)enclosingTextUnitOfGranularity:(WebTextGranularity)granularity inDirectionIfAtBoundary:(WebTextAdjustmentDirection)direction
{
    return kit(enclosingTextUnitOfGranularity([self _visiblePosition], toTextGranularity(granularity), toSelectionDirection(direction)).get());
}

- (WebVisiblePosition *)positionAtStartOrEndOfWord
{
    // Ripped from WebCore::Frame::moveSelectionToStartOrEndOfCurrentWord
    
    // Note: this is the iOS notion, not the unicode notion.
    // Here, a word starts with non-whitespace or at the start of a line and
    // ends at the next whitespace, or at the end of a line.
    
    // Selection rule: If the selection is before the first character or
    // just after the first character of a word that is longer than one
    // character, move to the start of the word. Otherwise, move to the
    // end of the word.
    
    VisiblePosition pos = [self _visiblePosition];
    VisiblePosition originalPos(pos);
    
    UChar32 ch = pos.characterAfter();
    bool isComplex = requiresContextForWordBoundary(ch);
    if (isComplex) {
        // for complex layout, find word around insertion point
        VisiblePosition visibleWordStart = startOfWord(pos);
        Position wordStart = visibleWordStart.deepEquivalent();
        
        // place caret in front of word if pos is within first 2 characters of word (see Selection Rule above)
        if (wordStart.deprecatedEditingOffset() + 1 >= pos.deepEquivalent().deprecatedEditingOffset()) {
            pos = wordStart;
        } else {
            // calculate end of word to insert caret after word
            VisiblePosition visibleWordEnd = endOfWord(pos);
            Position wordEnd = visibleWordEnd.deepEquivalent();
            pos = wordEnd;
        }
    } else {
        UChar32 c = pos.characterAfter();
        CFCharacterSetRef set = CFCharacterSetGetPredefined(kCFCharacterSetWhitespaceAndNewline);
        if (c == 0 || CFCharacterSetIsLongCharacterMember(set, c)) {
            // search backward for a non-space
            while (1) {
                if (pos.isNull() || isStartOfLine(pos))
                    break;
                c = pos.characterBefore();
                if (!CFCharacterSetIsLongCharacterMember(set, c))
                    break;
                pos = pos.previous(CannotCrossEditingBoundary);  // stay in editable content
            }
        }
        else {
            // See how far the selection extends into the current word.
            // Follow the rule stated above.
            int index = 0;
            while (1) {
                if (pos.isNull() || isStartOfLine(pos))
                    break;
                c = pos.characterBefore();
                if (CFCharacterSetIsLongCharacterMember(set, c))
                    break;
                pos = pos.previous(CannotCrossEditingBoundary);  // stay in editable content
                index++;
                if (index > 1)
                    break;
            }
            if (index > 1) {
                // search forward for a space
                pos = originalPos;
                while (1) {
                    if (pos.isNull() || isEndOfLine(pos))
                        break;
                    c = pos.characterAfter();
                    if (CFCharacterSetIsLongCharacterMember(set, c))
                        break;
                    pos = pos.next(CannotCrossEditingBoundary);  // stay in editable content
                }
            }
        }
    }
    
    return [WebVisiblePosition _wrapVisiblePositionIfValid:pos];
}

- (BOOL)isEditable
{
    return isEditablePosition([self _visiblePosition].deepEquivalent());
}

- (BOOL)requiresContextForWordBoundary
{
    VisiblePosition vp = [self _visiblePosition];
    return requiresContextForWordBoundary(vp.characterAfter()) || requiresContextForWordBoundary(vp.characterBefore());
}    

- (BOOL)atAlphaNumericBoundaryInDirection:(WebTextAdjustmentDirection)direction
{
    static CFCharacterSetRef set = CFCharacterSetGetPredefined(kCFCharacterSetAlphaNumeric);
    VisiblePosition pos = [self _visiblePosition];
    UChar32 charBefore = pos.characterBefore();
    UChar32 charAfter = pos.characterAfter();
    bool before = CFCharacterSetIsCharacterMember(set, charBefore);
    bool after = CFCharacterSetIsCharacterMember(set, charAfter);
    return [self directionIsDownstream:direction] ? (before && !after) : (!before && after);
}

- (DOMRange *)enclosingRangeWithDictationPhraseAlternatives:(NSArray **)alternatives
{
    ASSERT(alternatives);
    if (!alternatives)
        return nil;
        
    // *alternatives should not already point to an array.
    ASSERT(!(*alternatives));
    *alternatives = nil;
        
    VisiblePosition p = [self _visiblePosition];
    if (p.isNull())
        return nil;
        
    int o = p.deepEquivalent().deprecatedEditingOffset();
    if (o < 0)
        return nil;
    unsigned offset = o;
    
    Node* node = p.deepEquivalent().anchorNode();
    Document& document = node->document();
    
    const auto& markers = document.markers().markersFor(*node, DocumentMarker::DictationPhraseWithAlternatives);
    if (markers.isEmpty())
        return nil;
        
    for (size_t i = 0; i < markers.size(); i++) {
        const DocumentMarker* marker = markers[i];
        if (marker->startOffset() <= offset && marker->endOffset() >= offset) {
            const Vector<String>& markerAlternatives = marker->alternatives();
            *alternatives = [NSMutableArray arrayWithCapacity:markerAlternatives.size()];
            for (size_t j = 0; j < markerAlternatives.size(); j++)
                [(NSMutableArray *)*alternatives addObject:(NSString *)(markerAlternatives[j])];
                
            auto range = Range::create(document, node, marker->startOffset(), node, marker->endOffset());
            return kit(range.ptr());
        }
    }
        
    return nil;
}

- (DOMRange *)enclosingRangeWithCorrectionIndicator
{
    VisiblePosition p = [self _visiblePosition];
    if (p.isNull())
        return nil;
    
    int o = p.deepEquivalent().deprecatedEditingOffset();
    if (o < 0)
        return nil;
    unsigned offset = o;
    
    Node* node = p.deepEquivalent().anchorNode();
    Document& document = node->document();
    
    const auto& markers = document.markers().markersFor(*node, DocumentMarker::Spelling);
    if (markers.isEmpty())
        return nil;
    
    for (size_t i = 0; i < markers.size(); i++) {
        const DocumentMarker* marker = markers[i];
        if (marker->startOffset() <= offset && marker->endOffset() >= offset) {
            auto range = Range::create(document, node, marker->startOffset(), node, marker->endOffset());
            return kit(range.ptr());
        }
    }
    
    return nil;
}

- (NSSelectionAffinity)affinity
{
    return (NSSelectionAffinity)[self _visiblePosition].affinity();
}

- (void)setAffinity:(NSSelectionAffinity)affinity
{
    reinterpret_cast<VisiblePosition *>(_internal)->setAffinity((WebCore::EAffinity)affinity);
}

@end

@implementation DOMRange (VisiblePositionExtensions)

- (WebVisiblePosition *)startPosition
{
    Range *range = core(self);
    return [WebVisiblePosition _wrapVisiblePosition:VisiblePosition(range->startPosition())];
}

- (WebVisiblePosition *)endPosition
{
    Range *range = core(self);
    return [WebVisiblePosition _wrapVisiblePosition:VisiblePosition(range->endPosition())];
}

- (DOMRange *)enclosingWordRange
{
    VisibleSelection selection([self.startPosition _visiblePosition], [self.endPosition _visiblePosition]);
    selection = FrameSelection::wordSelectionContainingCaretSelection(selection);
    WebVisiblePosition *start = [WebVisiblePosition _wrapVisiblePosition:selection.visibleStart()];
    WebVisiblePosition *end = [WebVisiblePosition _wrapVisiblePosition:selection.visibleEnd()];
    return [DOMRange rangeForFirstPosition:start second:end];
}

+ (DOMRange *)rangeForFirstPosition:(WebVisiblePosition *)first second:(WebVisiblePosition *)second
{
    VisiblePosition firstVP = [first _visiblePosition];
    VisiblePosition secondVP = [second _visiblePosition];
    
    if (firstVP.isNull() || secondVP.isNull())
        return nil;
    
    RefPtr<Range> range;
    if (firstVP < secondVP) {
        range = Range::create(firstVP.deepEquivalent().deprecatedNode()->document(),
                                     firstVP, secondVP);
    } else {
        range = Range::create(firstVP.deepEquivalent().deprecatedNode()->document(),
                                            secondVP, firstVP);
    }
    
    
    return kit(range.get());
}

@end

@implementation DOMNode (VisiblePositionExtensions)

- (DOMRange *)rangeOfContents
{
    DOMRange *range = [[self ownerDocument] createRange];
    [range setStart:self offset:0];
    [range setEnd:self offset:[[self childNodes] length]];
    return range;    
}

- (WebVisiblePosition *)startPosition
{
    // When in editable content, we need to calculate the startPosition from the beginning of the
    // editable area.
    Node* node = core(self);
    if (node->isContentEditable()) {
        VisiblePosition vp(createLegacyEditingPosition(node, 0), VP_DEFAULT_AFFINITY);
        return [WebVisiblePosition _wrapVisiblePosition:startOfEditableContent(vp)];
    }
    return [[self rangeOfContents] startPosition];
}

- (WebVisiblePosition *)endPosition
{
    // When in editable content, we need to calculate the endPosition from the end of the
    // editable area.
    Node* node = core(self);
    if (node->isContentEditable()) {
        VisiblePosition vp(createLegacyEditingPosition(node, 0), VP_DEFAULT_AFFINITY);
        return [WebVisiblePosition _wrapVisiblePosition:endOfEditableContent(vp)];
    }
    return [[self rangeOfContents] endPosition];
}

@end

@implementation DOMHTMLInputElement (VisiblePositionExtensions)

- (WebVisiblePosition *)startPosition
{
    Node* node = core(self);
    RenderObject* object = node->renderer();
    if (!is<RenderTextControl>(object))
        return [super startPosition];
    
    VisiblePosition visiblePosition = downcast<RenderTextControl>(*object).textFormControlElement().visiblePositionForIndex(0);
    return [WebVisiblePosition _wrapVisiblePosition:visiblePosition];
}

- (WebVisiblePosition *)endPosition
{
    Node* node = core(self);
    RenderObject* object = node->renderer();
    if (!is<RenderTextControl>(object))
        return [super endPosition];
    
    RenderTextControl& textControl = downcast<RenderTextControl>(*object);
    VisiblePosition visiblePosition = textControl.textFormControlElement().visiblePositionForIndex(textControl.textFormControlElement().value().length());
    return [WebVisiblePosition _wrapVisiblePosition:visiblePosition];
}

@end

@implementation DOMHTMLTextAreaElement (VisiblePositionExtensions)

- (WebVisiblePosition *)startPosition
{
    Node* node = core(self);
    RenderObject* object = node->renderer();
    if (!object) 
        return [super startPosition];
    
    VisiblePosition visiblePosition = downcast<RenderTextControl>(*object).textFormControlElement().visiblePositionForIndex(0);
    return [WebVisiblePosition _wrapVisiblePosition:visiblePosition];
}

- (WebVisiblePosition *)endPosition
{
    Node* node = core(self);
    RenderObject* object = node->renderer();
    if (!object) 
        return [super endPosition];
    
    RenderTextControl& textControl = downcast<RenderTextControl>(*object);
    VisiblePosition visiblePosition = textControl.textFormControlElement().visiblePositionForIndex(textControl.textFormControlElement().value().length());
    return [WebVisiblePosition _wrapVisiblePosition:visiblePosition];
}

@end

#endif // PLATFORM(IOS_FAMILY)
