//: Playground - noun: a place where people can play
//: OOP : Inheritance
import UIKit

class Point2D : CustomStringConvertible{
    
    var x : Double = 0
    var y : Double = 0
    
    init(x : Double , y : Double) {
        self.x = x
        self.y = y
    }
    
    
    class var origin : Point2D {
        return Point2D(x: 0 , y: 0)
    }
    
    
    func distanceFrom(p : Point2D) -> Double{
        let dx = p.x - self.x
        let dy = p.y - self.y
        return sqrt(dx * dx + dy * dy)
    }
    
    func distanceFromOrigin() -> Double {
        return distanceFrom(p: Point2D.origin)
    }
    
    func display() {
        print("( \(self) )")
    }
    
    public var description : String {
        return "\(self.x) , \(self.y)"
    }
}


var p = Point2D(x: 3, y: 5)

p.display()

print("distance from (1, -1) : \(p.distanceFrom(p: Point2D(x:1, y:-1)))")
print("distance from origin : \(p.distanceFromOrigin())")
print(p)

print("---------------------------")


class Point3D : Point2D {
    var z : Double = 0
    
    init(x: Double, y: Double, z : Double) {
        super.init(x: x, y: y)
        self.z = z
    }
    
    convenience init(point2d : Point2D) {
        self.init(x : point2d.x , y : point2d.y, z : 0)
    }
    
    override var description: String {
        return "\(super.description) , \(self.z)"
    }
    
    override class var origin : Point3D {
        return Point3D(x: 0, y: 0, z: 0)
    }
    
    override func distanceFrom(p: Point2D) -> Double {
        return distanceFrom(p3: Point3D(point2d: p))
    }
    
    func distanceFrom(p3: Point3D) -> Double {
        let d2 = super.distanceFrom(p: p3)
        let dz = p3.z - self.z
        return sqrt(d2*d2 + dz*dz)
    }

}

var p3 : Point3D  = Point3D(x : 6, y : 9, z : 2)
p3.display()

print("distance from (2, 8, 5) : \(p3.distanceFrom(p3: Point3D(x:2, y:8, z:5)))")
print("distance from (1, 7) : \(p3.distanceFrom(p: Point2D(x:1, y:7)))")








