/*
 * 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)

#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 LTR;
}

- (BOOL)directionIsDownstream:(WebTextAdjustmentDirection)direction
{
    if (direction == WebTextAdjustmentBackward)
        return NO;
    
    if (direction == WebTextAdjustmentForward)
        return YES;
    
    
    if ([self textDirection] == LTR) {
        return (direction == WebTextAdjustmentRight);
    } else {
        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])];
                
            RefPtr<Range> range = Range::create(document, node, marker->startOffset(), node, marker->endOffset());
            return kit(range.get());
        }
    }
        
    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) {
            RefPtr<Range> range = Range::create(document, node, marker->startOffset(), node, marker->endOffset());
            return kit(range.get());
        }
    }
    
    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
{
#if USE(UIKIT_EDITING)
    // 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)];
    }
#endif
    return [[self rangeOfContents] startPosition];
}

- (WebVisiblePosition *)endPosition
{
#if USE(UIKIT_EDITING)
    // 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)];
    }
#endif
    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)
