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

#if os(OSX) || os(iOS)
    import Darwin
#elseif os(Linux)
    import Glibc
#endif

// TODO: It's not clear who is responsibile for defining these CGTypes, but we'll do it here.

public struct CGFloat {
    /// The native type used to store the CGFloat, which is Float on
    /// 32-bit architectures and Double on 64-bit architectures.
    /// We assume 64 bit for now
    public typealias NativeType = Double
    public init() {
        self.native = 0.0
    }
    public init(_ value: Float) {
        self.native = NativeType(value)
    }
    public init(_ value: Double) {
        self.native = NativeType(value)
    }
    /// The native value.
    public var native: NativeType
    
    private var hash: Int {
#if arch(i386) || arch(arm)
        return Int(Float(self.native).bitPattern)
#else
        return Int(self.native.bitPattern)
#endif
    }
}

extension CGFloat: Comparable { }

public func ==(lhs: CGFloat, rhs: CGFloat) -> Bool {
    return lhs.native == rhs.native
}

public func <(lhs: CGFloat, rhs: CGFloat) -> Bool {
    return lhs.native < rhs.native
}

public func *(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
    return CGFloat(lhs.native * rhs.native)
}

public func +(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
    return CGFloat(lhs.native + rhs.native)
}

public func -(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
    return CGFloat(lhs.native - rhs.native)
}

public func /(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
    return CGFloat(lhs.native / rhs.native)
}

prefix public func -(x: CGFloat) -> CGFloat {
    return CGFloat(-x.native)
}

public func +=(lhs: inout CGFloat, rhs: CGFloat) {
    lhs.native = lhs.native + rhs.native
}

extension Double {
    public init(_ value: CGFloat) {
        self = Double(value.native)
    }
}

public struct CGPoint {
    public var x: CGFloat
    public var y: CGFloat
    public init() {
        self.init(x: CGFloat(), y: CGFloat())
    }
    public init(x: CGFloat, y: CGFloat) {
        self.x = x
        self.y = y
    }
}

extension CGPoint: Equatable { }

public func ==(lhs: CGPoint, rhs: CGPoint) -> Bool {
    return lhs.x == rhs.x && lhs.y == rhs.y
}

extension CGPoint: NSSpecialValueCoding {
    init(bytes: UnsafePointer<Void>) {
        let buffer = UnsafePointer<CGFloat>(bytes)

        self.x = buffer.pointee
        self.y = buffer.advanced(by: 1).pointee
    }
    
    init?(coder aDecoder: NSCoder) {
        if aDecoder.allowsKeyedCoding {
            self = aDecoder.decodePointForKey("NS.pointval")
        } else {
            self = aDecoder.decodePoint()
        }
    }
    
    func encodeWithCoder(_ aCoder: NSCoder) {
        if aCoder.allowsKeyedCoding {
            aCoder.encodePoint(self, forKey: "NS.pointval")
        } else {
            aCoder.encodePoint(self)
        }
    }
    
    static func objCType() -> String {
        return "{CGPoint=dd}"
    }

    func getValue(_ value: UnsafeMutablePointer<Void>) {
        UnsafeMutablePointer<CGPoint>(value).pointee = self
    }

    func isEqual(_ aValue: Any) -> Bool {
        if let other = aValue as? CGPoint {
            return other == self
        } else {
            return false
        }
    }
    
    var hash: Int {
        return self.x.hash &+ self.y.hash
    }
    
     var description: String? {
        return NSStringFromPoint(self)
    }
}

public struct CGSize {
    public var width: CGFloat
    public var height: CGFloat
    public init() {
        self.init(width: CGFloat(), height: CGFloat())
    }
    public init(width: CGFloat, height: CGFloat) {
        self.width = width
        self.height = height
    }
}

extension CGSize: Equatable { }

public func ==(lhs: CGSize, rhs: CGSize) -> Bool {
    return lhs.width == rhs.width && lhs.height == rhs.height
}

extension CGSize: NSSpecialValueCoding {
    init(bytes: UnsafePointer<Void>) {
        let buffer = UnsafePointer<CGFloat>(bytes)

        self.width = buffer.pointee
        self.height = buffer.advanced(by: 1).pointee
    }
    
    init?(coder aDecoder: NSCoder) {
        if aDecoder.allowsKeyedCoding {
            self = aDecoder.decodeSizeForKey("NS.sizeval")
        } else {
            self = aDecoder.decodeSize()
        }
    }
    
    func encodeWithCoder(_ aCoder: NSCoder) {
        if aCoder.allowsKeyedCoding {
            aCoder.encodeSize(self, forKey: "NS.sizeval")
        } else {
            aCoder.encodeSize(self)
        }
    }
    
    static func objCType() -> String {
        return "{CGSize=dd}"
    }
    
    func getValue(_ value: UnsafeMutablePointer<Void>) {
        UnsafeMutablePointer<CGSize>(value).pointee = self
    }
    
    func isEqual(_ aValue: Any) -> Bool {
        if let other = aValue as? CGSize {
            return other == self
        } else {
            return false
        }
    }
    
    var hash: Int {
        return self.width.hash &+ self.height.hash
    }
    
    var description: String? {
        return NSStringFromSize(self)
    }
}

public struct CGRect {
    public var origin: CGPoint
    public var size: CGSize
    public init() {
        self.init(origin: CGPoint(), size: CGSize())
    }
    public init(origin: CGPoint, size: CGSize) {
        self.origin = origin
        self.size = size
    }
}

extension CGRect: Equatable { }

public func ==(lhs: CGRect, rhs: CGRect) -> Bool {
    return lhs.origin == rhs.origin && lhs.size == rhs.size
}

public typealias NSPoint = CGPoint

public typealias NSPointPointer = UnsafeMutablePointer<NSPoint>
public typealias NSPointArray = UnsafeMutablePointer<NSPoint>

public typealias NSSize = CGSize

public typealias NSSizePointer = UnsafeMutablePointer<NSSize>
public typealias NSSizeArray = UnsafeMutablePointer<NSSize>

public typealias NSRect = CGRect

public typealias NSRectPointer = UnsafeMutablePointer<NSRect>
public typealias NSRectArray = UnsafeMutablePointer<NSRect>

extension CGRect: NSSpecialValueCoding {
    init(bytes: UnsafePointer<Void>) {
        let buffer = UnsafePointer<CGFloat>(bytes)

        self.origin = CGPoint(x: buffer.pointee, y: buffer.advanced(by: 1).pointee)
        self.size = CGSize(width: buffer.advanced(by: 2).pointee, height: buffer.advanced(by: 3).pointee)
    }

    init?(coder aDecoder: NSCoder) {
        if aDecoder.allowsKeyedCoding {
            self = aDecoder.decodeRectForKey("NS.rectval")
        } else {
            self = aDecoder.decodeRect()
        }
    }
    
    func encodeWithCoder(_ aCoder: NSCoder) {
        if aCoder.allowsKeyedCoding {
            aCoder.encodeRect(self, forKey: "NS.rectval")
        } else {
            aCoder.encodeRect(self)
        }
    }
    
    static func objCType() -> String {
        return "{CGRect={CGPoint=dd}{CGSize=dd}}"
    }
    
    func getValue(_ value: UnsafeMutablePointer<Void>) {
        UnsafeMutablePointer<CGRect>(value).pointee = self
    }
    
    func isEqual(_ aValue: Any) -> Bool {
        if let other = aValue as? CGRect {
            return other == self
        } else {
            return false
        }
    }
    
    var hash: Int {
        return self.origin.hash &+ self.size.hash
    }
    
    var description: String? {
        return NSStringFromRect(self)
    }
}

public enum NSRectEdge : UInt {
    
    case MinX
    case MinY
    case MaxX
    case MaxY
}

public enum CGRectEdge : UInt32 {
    
    case MinXEdge
    case MinYEdge
    case MaxXEdge
    case MaxYEdge
}

extension NSRectEdge {
    public init(rectEdge: CGRectEdge) {
        switch rectEdge {
        case .MinXEdge: self = .MinX
        case .MinYEdge: self = .MinY
        case .MaxXEdge: self = .MaxX
        case .MaxYEdge: self = .MaxY
        }
    }
}


public struct NSEdgeInsets {
    public var top: CGFloat
    public var left: CGFloat
    public var bottom: CGFloat
    public var right: CGFloat

    public init() {
        self.init(top: CGFloat(), left: CGFloat(), bottom: CGFloat(), right: CGFloat())
    }

    public init(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) {
        self.top = top
        self.left = left
        self.bottom = bottom
        self.right = right
    }
}

extension NSEdgeInsets: NSSpecialValueCoding {
    init(bytes: UnsafePointer<Void>) {
        let buffer = UnsafePointer<CGFloat>(bytes)

        self.top = buffer.pointee
        self.left = buffer.advanced(by: 1).pointee
        self.bottom = buffer.advanced(by: 2).pointee
        self.right = buffer.advanced(by: 3).pointee
    }

    init?(coder aDecoder: NSCoder) {
        if aDecoder.allowsKeyedCoding {
            self.top = aDecoder._decodeCGFloatForKey("NS.edgeval.top")
            self.left = aDecoder._decodeCGFloatForKey("NS.edgeval.left")
            self.bottom = aDecoder._decodeCGFloatForKey("NS.edgeval.bottom")
            self.right = aDecoder._decodeCGFloatForKey("NS.edgeval.right")
        } else {
            NSUnimplemented()
        }
    }
    
    func encodeWithCoder(_ aCoder: NSCoder) {
        if aCoder.allowsKeyedCoding {
            aCoder._encodeCGFloat(self.top, forKey: "NS.edgeval.top")
            aCoder._encodeCGFloat(self.left, forKey: "NS.edgeval.left")
            aCoder._encodeCGFloat(self.bottom, forKey: "NS.edgeval.bottom")
            aCoder._encodeCGFloat(self.right, forKey: "NS.edgeval.right")
        } else {
            NSUnimplemented()
        }
    }
    
    static func objCType() -> String {
        return "{NSEdgeInsets=dddd}"
    }
    
    func getValue(_ value: UnsafeMutablePointer<Void>) {
        UnsafeMutablePointer<NSEdgeInsets>(value).pointee = self
    }
    
    func isEqual(_ aValue: Any) -> Bool {
        if let other = aValue as? NSEdgeInsets {
            return other.top == self.top && other.left == self.left &&
                other.bottom == self.bottom && other.right == self.right
        } else {
            return false
        }
    }
    
    var hash: Int {
        return self.top.hash &+ self.left.hash &+ self.bottom.hash &+ self.right.hash
    }
    
    var description: String? {
        return nil
    }
}

public struct NSAlignmentOptions : OptionSet {
    public var rawValue : UInt64
    public init(rawValue: UInt64) { self.rawValue = rawValue }
    
    public static let AlignMinXInward = NSAlignmentOptions(rawValue: 1 << 0)
    public static let AlignMinYInward = NSAlignmentOptions(rawValue: 1 << 1)
    public static let AlignMaxXInward = NSAlignmentOptions(rawValue: 1 << 2)
    public static let AlignMaxYInward = NSAlignmentOptions(rawValue: 1 << 3)
    public static let AlignWidthInward = NSAlignmentOptions(rawValue: 1 << 4)
    public static let AlignHeightInward = NSAlignmentOptions(rawValue: 1 << 5)
    
    public static let AlignMinXOutward = NSAlignmentOptions(rawValue: 1 << 8)
    public static let AlignMinYOutward = NSAlignmentOptions(rawValue: 1 << 9)
    public static let AlignMaxXOutward = NSAlignmentOptions(rawValue: 1 << 10)
    public static let AlignMaxYOutward = NSAlignmentOptions(rawValue: 1 << 11)
    public static let AlignWidthOutward = NSAlignmentOptions(rawValue: 1 << 12)
    public static let AlignHeightOutward = NSAlignmentOptions(rawValue: 1 << 13)
    
    public static let AlignMinXNearest = NSAlignmentOptions(rawValue: 1 << 16)
    public static let AlignMinYNearest = NSAlignmentOptions(rawValue: 1 << 17)
    public static let AlignMaxXNearest = NSAlignmentOptions(rawValue: 1 << 18)
    public static let AlignMaxYNearest = NSAlignmentOptions(rawValue: 1 << 19)
    public static let AlignWidthNearest = NSAlignmentOptions(rawValue: 1 << 20)
    public static let AlignHeightNearest = NSAlignmentOptions(rawValue: 1 << 21)

    // pass this if the rect is in a flipped coordinate system. This allows 0.5 to be treated in a visually consistent way.
    public static let AlignRectFlipped = NSAlignmentOptions(rawValue: 1 << 63)
    
    // convenience combinations
    public static let AlignAllEdgesInward = [NSAlignmentOptions.AlignMinXInward, NSAlignmentOptions.AlignMaxXInward, NSAlignmentOptions.AlignMinYInward, NSAlignmentOptions.AlignMaxYInward]
    public static let AlignAllEdgesOutward = [NSAlignmentOptions.AlignMinXOutward, NSAlignmentOptions.AlignMaxXOutward, NSAlignmentOptions.AlignMinYOutward, NSAlignmentOptions.AlignMaxYOutward]
    public static let AlignAllEdgesNearest = [NSAlignmentOptions.AlignMinXNearest, NSAlignmentOptions.AlignMaxXNearest, NSAlignmentOptions.AlignMinYNearest, NSAlignmentOptions.AlignMaxYNearest]
}

public let NSZeroPoint: NSPoint = NSPoint()
public let NSZeroSize: NSSize = NSSize()
public let NSZeroRect: NSRect = NSRect()
public let NSEdgeInsetsZero: NSEdgeInsets = NSEdgeInsets()

public func NSMakePoint(_ x: CGFloat, _ y: CGFloat) -> NSPoint {
    return NSPoint(x: x, y: y)
}

public func NSMakeSize(_ w: CGFloat, _ h: CGFloat) -> NSSize {
    return NSSize(width: w, height: h)
}

public func NSMakeRect(_ x: CGFloat, _ y: CGFloat, _ w: CGFloat, _ h: CGFloat) -> NSRect {
    return NSRect(origin: NSPoint(x: x, y: y), size: NSSize(width: w, height: h))
}

public func NSMaxX(_ aRect: NSRect) -> CGFloat { return CGFloat(aRect.origin.x.native + aRect.size.width.native) }

public func NSMaxY(_ aRect: NSRect) -> CGFloat { return CGFloat(aRect.origin.y.native + aRect.size.height.native) }

public func NSMidX(_ aRect: NSRect) -> CGFloat { return CGFloat(aRect.origin.x.native + (aRect.size.width.native / 2)) }

public func NSMidY(_ aRect: NSRect) -> CGFloat { return CGFloat(aRect.origin.y.native + (aRect.size.height.native / 2)) }

public func NSMinX(_ aRect: NSRect) -> CGFloat { return aRect.origin.x }

public func NSMinY(_ aRect: NSRect) -> CGFloat { return aRect.origin.y }

public func NSWidth(_ aRect: NSRect) -> CGFloat { return aRect.size.width }

public func NSHeight(_ aRect: NSRect) -> CGFloat { return aRect.size.height }

public func NSRectFromCGRect(_ cgrect: CGRect) -> NSRect { return cgrect }

public func NSRectToCGRect(_ nsrect: NSRect) -> CGRect { return nsrect }

public func NSPointFromCGPoint(_ cgpoint: CGPoint) -> NSPoint { return cgpoint }

public func NSPointToCGPoint(_ nspoint: NSPoint) -> CGPoint { return nspoint }

public func NSSizeFromCGSize(_ cgsize: CGSize) -> NSSize { return cgsize }

public func NSSizeToCGSize(_ nssize: NSSize) -> CGSize { return nssize }

public func NSEdgeInsetsMake(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> NSEdgeInsets {
    return NSEdgeInsets(top: top, left: left, bottom: bottom, right: right)
}

public func NSEqualPoints(_ aPoint: NSPoint, _ bPoint: NSPoint) -> Bool { return aPoint == bPoint }

public func NSEqualSizes(_ aSize: NSSize, _ bSize: NSSize) -> Bool { return aSize == bSize }

public func NSEqualRects(_ aRect: NSRect, _ bRect: NSRect) -> Bool { return aRect == bRect }

public func NSIsEmptyRect(_ aRect: NSRect) -> Bool { return (aRect.size.width.native <= 0) || (aRect.size.height.native <= 0) }

public func NSEdgeInsetsEqual(_ aInsets: NSEdgeInsets, _ bInsets: NSEdgeInsets) -> Bool {
    return (aInsets.top == bInsets.top) && (aInsets.left == bInsets.left) && (aInsets.bottom == bInsets.bottom) && (aInsets.right == bInsets.right)
}

public func NSInsetRect(_ aRect: NSRect, _ dX: CGFloat, _ dY: CGFloat) -> NSRect {
    let x = CGFloat(aRect.origin.x.native + dX.native)
    let y = CGFloat(aRect.origin.y.native + dY.native)
    let w = CGFloat(aRect.size.width.native - (dX.native * 2))
    let h = CGFloat(aRect.size.height.native - (dY.native * 2))
    return NSMakeRect(x, y, w, h)
}

public func NSIntegralRect(_ aRect: NSRect) -> NSRect {
    if aRect.size.height.native <= 0 || aRect.size.width.native <= 0 {
        return NSZeroRect
    }
    
    return NSIntegralRectWithOptions(aRect, [.AlignMinXOutward, .AlignMaxXOutward, .AlignMinYOutward, .AlignMaxYOutward])
}
public func NSIntegralRectWithOptions(_ aRect: NSRect, _ opts: NSAlignmentOptions) -> NSRect {
    let listOfOptionsIsInconsistentErrorMessage = "List of options is inconsistent"
    
    if opts.contains(.AlignRectFlipped) {
        NSUnimplemented()
    }

    var width = Double.nan
    var height = Double.nan
    var minX = Double.nan
    var minY = Double.nan
    var maxX = Double.nan
    var maxY = Double.nan

    if aRect.size.height.native < 0 {
        height = 0
    }
    if aRect.size.width.native < 0 {
        width = 0
    }
    

    if opts.contains(.AlignWidthInward) && width != 0 {
        guard width.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        width = floor(aRect.size.width.native)
    }
    if opts.contains(.AlignHeightInward) && height != 0 {
        guard height.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        height = floor(aRect.size.height.native)
    }
    if opts.contains(.AlignWidthOutward) && width != 0 {
        guard width.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        width = ceil(aRect.size.width.native)
    }
    if opts.contains(.AlignHeightOutward) && height != 0 {
        guard height.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        height = ceil(aRect.size.height.native)
    }
    if opts.contains(.AlignWidthNearest) && width != 0 {
        guard width.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        width = round(aRect.size.width.native)
    }
    if opts.contains(.AlignHeightNearest) && height != 0 {
        guard height.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        height = round(aRect.size.height.native)
    }

    
    if opts.contains(.AlignMinXInward) {
        guard minX.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        minX = ceil(aRect.origin.x.native)
    }
    if opts.contains(.AlignMinYInward) {
        guard minY.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        minY = ceil(aRect.origin.y.native)
    }
    if opts.contains(.AlignMaxXInward) {
        guard maxX.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        maxX = floor(aRect.origin.x.native + aRect.size.width.native)
    }
    if opts.contains(.AlignMaxYInward) {
        guard maxY.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        maxY = floor(aRect.origin.y.native + aRect.size.height.native)
    }

    
    if opts.contains(.AlignMinXOutward) {
        guard minX.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        minX = floor(aRect.origin.x.native)
    }
    if opts.contains(.AlignMinYOutward) {
        guard minY.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        minY = floor(aRect.origin.y.native)
    }
    if opts.contains(.AlignMaxXOutward) {
        guard maxX.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        maxX = ceil(aRect.origin.x.native + aRect.size.width.native)
    }
    if opts.contains(.AlignMaxYOutward) {
        guard maxY.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        maxY = ceil(aRect.origin.y.native + aRect.size.height.native)
    }
    

    if opts.contains(.AlignMinXNearest) {
        guard minX.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        minX = round(aRect.origin.x.native)
    }
    if opts.contains(.AlignMinYNearest) {
        guard minY.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        minY = round(aRect.origin.y.native)
    }
    if opts.contains(.AlignMaxXNearest) {
        guard maxX.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        maxX = round(aRect.origin.x.native + aRect.size.width.native)
    }
    if opts.contains(.AlignMaxYNearest) {
        guard maxY.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
        maxY = round(aRect.origin.y.native + aRect.size.height.native)
    }
    
    var resultOriginX = Double.nan
    var resultOriginY = Double.nan
    var resultWidth = Double.nan
    var resultHeight = Double.nan
    
    if !minX.isNaN {
        resultOriginX = minX
    }
    if !width.isNaN {
        resultWidth = width
    }
    if !maxX.isNaN {
        if width.isNaN {
            guard resultWidth.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
            resultWidth = maxX - minX
        } else {
            guard resultOriginX.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
            resultOriginX = maxX - width
        }
    }
    
    
    if !minY.isNaN {
        resultOriginY = minY
    }
    if !height.isNaN {
        resultHeight = height
    }
    if !maxY.isNaN {
        if height.isNaN {
            guard resultHeight.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
            resultHeight = maxY - minY
        } else {
            guard resultOriginY.isNaN else { fatalError(listOfOptionsIsInconsistentErrorMessage) }
            resultOriginY = maxY - height
        }
    }
    
    if resultOriginX.isNaN || resultOriginY.isNaN
        || resultHeight.isNaN || resultWidth.isNaN {
        fatalError(listOfOptionsIsInconsistentErrorMessage)
    }
    
    var result = NSZeroRect
    result.origin.x.native = resultOriginX
    result.origin.y.native = resultOriginY
    result.size.width.native = resultWidth
    result.size.height.native = resultHeight
    
    return result
}

public func NSUnionRect(_ aRect: NSRect, _ bRect: NSRect) -> NSRect {
    let isEmptyFirstRect = NSIsEmptyRect(aRect)
    let isEmptySecondRect = NSIsEmptyRect(bRect)
    if isEmptyFirstRect && isEmptySecondRect {
        return NSZeroRect
    } else if isEmptyFirstRect {
        return bRect
    } else if isEmptySecondRect {
        return aRect
    }
    let x = min(NSMinX(aRect), NSMinX(bRect))
    let y = min(NSMinY(aRect), NSMinY(bRect))
    let width = max(NSMaxX(aRect), NSMaxX(bRect)) - x
    let height = max(NSMaxY(aRect), NSMaxY(bRect)) - y
    return NSMakeRect(x, y, width, height)
}

public func NSIntersectionRect(_ aRect: NSRect, _ bRect: NSRect) -> NSRect {
    if NSMaxX(aRect) <= NSMinX(bRect) || NSMaxX(bRect) <= NSMinX(aRect) || NSMaxY(aRect) <= NSMinY(bRect) || NSMaxY(bRect) <= NSMinY(aRect) {
        return NSZeroRect
    }
    let x = max(NSMinX(aRect), NSMinX(bRect))
    let y = max(NSMinY(aRect), NSMinY(bRect))
    let width = min(NSMaxX(aRect), NSMaxX(bRect)) - x
    let height = min(NSMaxY(aRect), NSMaxY(bRect)) - y
    return NSMakeRect(x, y, width, height)
}

public func NSOffsetRect(_ aRect: NSRect, _ dX: CGFloat, _ dY: CGFloat) -> NSRect {
    var result = aRect
    result.origin.x += dX
    result.origin.y += dY
    return result
}

public func NSDivideRect(_ inRect: NSRect, _ slice: UnsafeMutablePointer<NSRect>, _ rem: UnsafeMutablePointer<NSRect>, _ amount: CGFloat, _ edge: NSRectEdge) {
    if NSIsEmptyRect(inRect) {
        slice.pointee = NSZeroRect
        rem.pointee = NSZeroRect
        return
    }

    let width = NSWidth(inRect)
    let height = NSHeight(inRect)

    switch (edge, amount) {
    case (.MinX, let amount) where amount > width:
        slice.pointee = inRect
        rem.pointee = NSMakeRect(NSMaxX(inRect), NSMinY(inRect), CGFloat(0.0), height)

    case (.MinX, _):
        slice.pointee = NSMakeRect(NSMinX(inRect), NSMinY(inRect), amount, height)
        rem.pointee = NSMakeRect(NSMaxX(slice.pointee), NSMinY(inRect), NSMaxX(inRect) - NSMaxX(slice.pointee), height)

    case (.MinY, let amount) where amount > height:
        slice.pointee = inRect
        rem.pointee = NSMakeRect(NSMinX(inRect), NSMaxY(inRect), width, CGFloat(0.0))

    case (.MinY, _):
        slice.pointee = NSMakeRect(NSMinX(inRect), NSMinY(inRect), width, amount)
        rem.pointee = NSMakeRect(NSMinX(inRect), NSMaxY(slice.pointee), width, NSMaxY(inRect) - NSMaxY(slice.pointee))

    case (.MaxX, let amount) where amount > width:
        slice.pointee = inRect
        rem.pointee = NSMakeRect(NSMinX(inRect), NSMinY(inRect), CGFloat(0.0), height)

    case (.MaxX, _):
        slice.pointee = NSMakeRect(NSMaxX(inRect) - amount, NSMinY(inRect), amount, height)
        rem.pointee = NSMakeRect(NSMinX(inRect), NSMinY(inRect), NSMinX(slice.pointee) - NSMinX(inRect), height)

    case (.MaxY, let amount) where amount > height:
        slice.pointee = inRect
        rem.pointee = NSMakeRect(NSMinX(inRect), NSMinY(inRect), width, CGFloat(0.0))

    case (.MaxY, _):
        slice.pointee = NSMakeRect(NSMinX(inRect), NSMaxY(inRect) - amount, width, amount)
        rem.pointee = NSMakeRect(NSMinX(inRect), NSMinY(inRect), width, NSMinY(slice.pointee) - NSMinY(inRect))
    }
}

public func NSPointInRect(_ aPoint: NSPoint, _ aRect: NSRect) -> Bool {
    return NSMouseInRect(aPoint, aRect, true)
}

public func NSMouseInRect(_ aPoint: NSPoint, _ aRect: NSRect, _ flipped: Bool) -> Bool {
    if flipped {
        return aPoint.x >= NSMinX(aRect) && aPoint.y >= NSMinX(aRect) && aPoint.x < NSMaxX(aRect) && aPoint.y < NSMaxY(aRect)
    }
    return aPoint.x >= NSMinX(aRect) && aPoint.y > NSMinY(aRect) && aPoint.x < NSMaxX(aRect) && aPoint.y <= NSMaxY(aRect)
}

public func NSContainsRect(_ aRect: NSRect, _ bRect: NSRect) -> Bool {
    return !NSIsEmptyRect(bRect) && NSMaxX(bRect) <= NSMaxX(aRect) && NSMinX(bRect) >= NSMinX(aRect) &&
        NSMaxY(bRect) <= NSMaxY(aRect) && NSMinY(bRect) >= NSMinY(aRect)
}

public func NSIntersectsRect(_ aRect: NSRect, _ bRect: NSRect) -> Bool {
    return !(NSIsEmptyRect(aRect) || NSIsEmptyRect(bRect) ||
        NSMaxX(aRect) <= NSMinX(bRect) || NSMaxX(bRect) <= NSMinX(aRect) || NSMaxY(aRect) <= NSMinY(bRect) || NSMaxY(bRect) <= NSMinY(aRect))
}

public func NSStringFromPoint(_ aPoint: NSPoint) -> String {
    return "{\(aPoint.x.native), \(aPoint.y.native)}"
}

public func NSStringFromSize(_ aSize: NSSize) -> String {
    return "{\(aSize.width.native), \(aSize.height.native)}"
}

public func NSStringFromRect(_ aRect: NSRect) -> String {
    let originString = NSStringFromPoint(aRect.origin)
    let sizeString = NSStringFromSize(aRect.size)
    
    return "{\(originString), \(sizeString)}"
}

private func _scanDoublesFromString(_ aString: String, number: Int) -> [Double] {
    let scanner = NSScanner(string: aString)
    let digitSet = NSMutableCharacterSet.decimalDigits()
    digitSet.addCharacters(in: "-")
    var result = [Double](repeating: 0.0, count: number)
    var index = 0

    let _ = scanner.scanUpToCharactersFromSet(digitSet)
    while !scanner.atEnd && index < number {
        if let num = scanner.scanDouble() {
            result[index] = num
        }
        let _ = scanner.scanUpToCharactersFromSet(digitSet)
        index += 1
    }

    return result
}

public func NSPointFromString(_ aString: String) -> NSPoint {
    if aString.isEmpty {
        return NSZeroPoint
    }

    let parsedNumbers = _scanDoublesFromString(aString, number: 2)
    
    let x = parsedNumbers[0]
    let y = parsedNumbers[1]
    let result = NSMakePoint(CGFloat(x), CGFloat(y))
    
    return result
}

public func NSSizeFromString(_ aString: String) -> NSSize {
    if aString.isEmpty {
        return NSZeroSize
    }
    let parsedNumbers = _scanDoublesFromString(aString, number: 2)
    
    let w = parsedNumbers[0]
    let h = parsedNumbers[1]
    let result = NSMakeSize(CGFloat(w), CGFloat(h))
    
    return result
}

public func NSRectFromString(_ aString: String) -> NSRect {
    if aString.isEmpty {
        return NSZeroRect
    }
    
    let parsedNumbers = _scanDoublesFromString(aString, number: 4)
    
    let x = parsedNumbers[0]
    let y = parsedNumbers[1]
    let w = parsedNumbers[2]
    let h = parsedNumbers[3]
    
    let result = NSMakeRect(CGFloat(x), CGFloat(y), CGFloat(w), CGFloat(h))
    
    return result
}

extension NSValue {
    public convenience init(point: NSPoint) {
        self.init()
        self._concreteValue = NSSpecialValue(point)
    }
    
    public convenience init(size: NSSize) {
        self.init()
        self._concreteValue = NSSpecialValue(size)
    }
    
    public convenience init(rect: NSRect) {
        self.init()
        self._concreteValue = NSSpecialValue(rect)
    }
    
    public convenience init(edgeInsets insets: NSEdgeInsets) {
        self.init()
        self._concreteValue = NSSpecialValue(insets)
    }
    
    public var pointValue: NSPoint {
        let specialValue = self._concreteValue as! NSSpecialValue
        return specialValue._value as! NSPoint
    }
    
    public var sizeValue: NSSize {
        let specialValue = self._concreteValue as! NSSpecialValue
        return specialValue._value as! NSSize
    }
    
    public var rectValue: NSRect {
        let specialValue = self._concreteValue as! NSSpecialValue
        return specialValue._value as! NSRect
    }
    
    public var edgeInsetsValue: NSEdgeInsets {
        let specialValue = self._concreteValue as! NSSpecialValue
        return specialValue._value as! NSEdgeInsets
    }
}

extension NSCoder {
    
    public func encodePoint(_ point: NSPoint) {
        self._encodeCGFloat(point.x)
        self._encodeCGFloat(point.y)
    }
    
    public func decodePoint() -> NSPoint {
        return NSPoint(x: _decodeCGFloat(), y: _decodeCGFloat())
    }
    
    public func encodeSize(_ size: NSSize) {
        self._encodeCGFloat(size.width)
        self._encodeCGFloat(size.height)
    }
    
    public func decodeSize() -> NSSize {
        return NSSize(width: _decodeCGFloat(), height: _decodeCGFloat())
    }
    
    public func encodeRect(_ rect: NSRect) {
        self.encodePoint(rect.origin)
        self.encodeSize(rect.size)
    }
    
    public func decodeRect() -> NSRect {
        return NSRect(origin: decodePoint(), size: decodeSize())
    }
}

extension NSCoder {
    
    public func encodePoint(_ point: NSPoint, forKey key: String) {
        self.encodeObject(NSStringFromPoint(point).bridge(), forKey: key)
    }
    
    public func encodeSize(_ size: NSSize, forKey key: String) {
        self.encodeObject(NSStringFromSize(size).bridge(), forKey: key)
    }
    
    public func encodeRect(_ rect: NSRect, forKey key: String) {
        self.encodeObject(NSStringFromRect(rect).bridge(), forKey: key)
    }
    
    public func decodePointForKey(_ key: String) -> NSPoint {
        if let string = self.decodeObjectOfClass(NSString.self, forKey: key) {
            return NSPointFromString(string.bridge())
        } else {
            return NSPoint()
        }
    }
    
    public func decodeSizeForKey(_ key: String) -> NSSize {
        if let string = self.decodeObjectOfClass(NSString.self, forKey: key) {
            return NSSizeFromString(string.bridge())
        } else {
            return NSSize()
        }
    }
    
    public func decodeRectForKey(_ key: String) -> NSRect {
        if let string = self.decodeObjectOfClass(NSString.self, forKey: key) {
            return NSRectFromString(string.bridge())
        } else {
            return NSRect()
        }
    }
}

private extension NSCoder {
    func _encodeCGFloat(_ value: CGFloat) {
        if let keyedArchiver = self as? NSKeyedArchiver {
            keyedArchiver._encodeValue(NSNumber(value: value.native))
        } else {
            NSUnimplemented()
        }
    }
    
    func _decodeCGFloat() -> CGFloat {
        if let keyedUnarchiver = self as? NSKeyedUnarchiver {
            guard let result : NSNumber = keyedUnarchiver._decodeValue() else {
                return CGFloat(0.0)
            }
            return CGFloat(result.doubleValue)
        } else {
            NSUnimplemented()
        }
    }
    
    func _encodeCGFloat(_ value: CGFloat, forKey key: String) {
        self.encodeDouble(value.native, forKey: key)
    }
    
    func _decodeCGFloatForKey(_ key: String) -> CGFloat {
        return CGFloat(self.decodeDoubleForKey(key))
    }
}
