// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//


public class NSIndexPath : NSObject, NSCopying, NSSecureCoding {
    
    internal var _indexes : [Int]
    override public init() {
        _indexes = []
    }
    public init(indexes: UnsafePointer<Int>, length: Int) {
        _indexes = Array(UnsafeBufferPointer(start: indexes, count: length))
    }
    
    private init(indexes: [Int]) {
        _indexes = indexes
    }
    
    public override func copy() -> AnyObject {
        return copyWithZone(nil)
    }
    
    public func copyWithZone(_ zone: NSZone) -> AnyObject { NSUnimplemented() }
    public convenience init(index: Int) {
        self.init(indexes: [index])
    }
    
    public func encodeWithCoder(_ aCoder: NSCoder) {
        NSUnimplemented()
    }
    
    public required init?(coder aDecoder: NSCoder) {
        NSUnimplemented()
    }
    
    public static func supportsSecureCoding() -> Bool { return true }
    
    public func indexPathByAddingIndex(_ index: Int) -> NSIndexPath {
        return NSIndexPath(indexes: _indexes + [index])
    }
    public func indexPathByRemovingLastIndex() -> NSIndexPath {
        if _indexes.count <= 1 {
            return NSIndexPath(indexes: [])
        } else {
            return NSIndexPath(indexes: [Int](_indexes[0..<_indexes.count - 1]))
        }
    }
    
    public func indexAtPosition(_ position: Int) -> Int {
        return _indexes[position]
    }
    public var length: Int  {
        return _indexes.count
    }
    
    /*!
     @abstract Copies the indexes stored in this index path from the positions specified by positionRange into indexes.
     @param indexes Buffer of at least as many NSUIntegers as specified by the length of positionRange. On return, this memory will hold the index path's indexes.
     @param positionRange A range of valid positions within this index path.  If the location plus the length of positionRange is greater than the length of this index path, this method raises an NSRangeException.
     @discussion
        It is the developer’s responsibility to allocate the memory for the C array.
     */
    public func getIndexes(_ indexes: UnsafeMutablePointer<Int>, range positionRange: NSRange) {
        for (pos, idx) in _indexes[positionRange.location ..< NSMaxRange(positionRange)].enumerated() {
            indexes.advanced(by: pos).pointee = idx
        }
    }
    
    // comparison support
    // sorting an array of indexPaths using this comparison results in an array representing nodes in depth-first traversal order
    public func compare(_ otherObject: NSIndexPath) -> NSComparisonResult {
        let thisLength = length
        let otherLength = otherObject.length
        let minLength = thisLength >= otherLength ? otherLength : thisLength
        for pos in 0..<minLength {
            let otherValue = otherObject.indexAtPosition(pos)
            let thisValue = indexAtPosition(pos)
            if thisValue < otherValue {
                return .orderedAscending
            } else if thisValue > otherValue {
                return .orderedDescending
            }
        }
        if thisLength > otherLength {
            return .orderedDescending
        } else if thisLength < otherLength {
            return .orderedAscending
        }
        return .orderedSame
    }
}
