 import UIKit
 
 
+
 // MARK: - Public API
 prefix operator ~>
 
 public extension UIView {
     
-    /// Set two views layout layout constraints
-    ///
-    /// - parameter left:  subview, right or bottom position view.
-    /// - parameter right: superview, top or left position view.
-    ///
-    /// - returns: LiteAutoLayout
-    static func ~> (left: UIView, right: UIView) -> LiteAutoLayout {
-        let lite = LiteAutoLayout(left: left, right: right)
-        return lite
-    }
-    
-
+    /// Set layout constraints between two views
+    ///
+    /// - parameter left:  the subview, or the view is at the right or bottom.
+    /// - parameter right: the superview, or the view is at the top or left.
+    ///
+    /// - returns: RelationLiteAutoLayout instance
+    public static func ~> (left: UIView, right: UIView) -> RelationLiteAutoLayout {
+    return RelationLiteAutoLayout(left: left, right: right)
+    }
+    
+    
     /// Set view's layout attribute
     ///
-    /// - parameter left: which view to be set
-    ///
-    /// - returns: LiteAutoLayout object
-    static prefix func ~> (view: UIView) -> LiteAutoLayout {
-        let lite = LiteAutoLayout(left: view, right: nil)
-        return lite
-    }
-    
-    
-    /// Set view's layout attribute
-    ///
-    /// - returns: LiteAutoLayout
-    func startLayout() -> LiteAutoLayout {
-        let lite = LiteAutoLayout(left: self, right: nil)
-        return lite
-    }
-    
-    
-    /// Set two views layout layout constraints
-    ///
-    /// - parameter toView: superview, top or left position view.
-    ///
-    /// - returns: LiteAutoLayout
-    func startLayout(toView: UIView) -> LiteAutoLayout {
-        let lite = LiteAutoLayout(left: self, right: toView)
-        return lite
-    }
-    
-}
-
-enum ContraintType
+    /// - parameter left: which view's layout constraints to be set
+    ///
+    /// - returns: ItemLiteAutoLayout instance
+    public static prefix func ~> (view: UIView) -> ItemLiteAutoLayout {
+    return ItemLiteAutoLayout(left: view, right: nil)
+    }
+    
+    
+    /// Set the view's layout attribute
+    ///
+    /// - returns: ItemLiteAutoLayout instance
+    public func startLayout() -> ItemLiteAutoLayout {
+        return ItemLiteAutoLayout(left: self, right: nil)
+    }
+    
+    
+    /// Set layout constraints between two views
+    ///
+    /// - parameter toView: the view's superview, or at the top or left of the view.
+    ///
+    /// - returns: RelationLiteAutoLayout instance
+    public func startLayout(toView: UIView) -> RelationLiteAutoLayout {
+        return RelationLiteAutoLayout(left: self, right: toView)
+    }
+    
+}
+
+fileprivate enum ContraintType
 {
     case equalHeights
     case equalWidths

        self.constant = constants
    }
    
    init(contraintType: ContraintType, constants: Float, relatedBy: NSLayoutRelation, multiplier: Float, priority: UILayoutPriority) {
        self.multiplier = multiplier
        self.priority = priority
        self.type = contraintType
        self.constant = constants
        self.relatedBy = relatedBy
    }
}

public class LiteAutoLayout {
    var constraints: [ContraintModel] = []
    var firstItem: UIView!
    var secondItem: UIView?
    
    init(left: UIView, right: UIView?) {
        left.translatesAutoresizingMaskIntoConstraints = false
        firstItem = left
        secondItem = right
    }
    
    
    @discardableResult func equalHeights(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        let item = ContraintModel(contraintType: .equalHeights, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func equalWidths(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        let item = ContraintModel(contraintType: .equalWidths, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func baseline(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        guard let _ = secondItem else {
            return self
        }
        
        let item = ContraintModel(contraintType: .baseline, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func leading(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        guard let _ = secondItem else {
            return self
        }
        
        let item = ContraintModel(contraintType: .leading, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func bottom(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        guard let _ = secondItem else {
            return self
        }
        
        let item = ContraintModel(contraintType: .bottom, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func top(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        guard let _ = secondItem else {
            return self
        }
        
        let item = ContraintModel(contraintType: .top, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func trailing(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        guard let _ = secondItem else {
            return self
        }
        
        let item = ContraintModel(contraintType: .trailing, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func horizontalSpacing(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        guard let _ = secondItem else {
            return self
        }
        
        let item = ContraintModel(contraintType: .horizontalSpacing, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func verticalSpacing(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        guard let _ = secondItem else {
            return self
        }
        
        let item = ContraintModel(contraintType: .verticalSpacing, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func centerVertically(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        let item = ContraintModel(contraintType: .centerVertically, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func centerHorizontally(_ constant: Float = 0, relatedBy: NSLayoutRelation = .equal, multiplier: Float = 1.0, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        let item = ContraintModel(contraintType: .centerHorizontally, constants: constant, relatedBy: relatedBy, multiplier: multiplier, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    @discardableResult func aspectRatio(width: Float, height: Float, relatedBy: NSLayoutRelation = .equal, priority: Float = UILayoutPriorityRequired) -> LiteAutoLayout {
        let item = ContraintModel(contraintType: .aspectRatio, constants: 0, relatedBy: relatedBy, multiplier: width/height, priority: priority)
        constraints.append(item)
        addContraint(contraintModel: item)
        return self
    }
    
    
    private func addContraint(contraintModel: ContraintModel) -> Void {
        let item = contraintModel
        var layoutConstraint: NSLayoutConstraint!
        var layoutAttributes: (fistAttribute: NSLayoutAttribute, secondAttibute: NSLayoutAttribute)

    case verticalSpacing
}

fileprivate class ContraintModel
{
    var type: ContraintType
    var constant: Float = 0.0
