 import UIKit
 
 
-open class ElongationCell: UITableViewCell {
+open class ElongationCell: UITableViewCell, Expandable {
   
   // MARK: Public properties
   open var isExpanded = false
   
-  @IBOutlet public var frontView: UIView!
-  @IBOutlet public var frontViewHeightConstraint: NSLayoutConstraint!
-  
-  @IBOutlet public var backView: UIView!
-  @IBOutlet public var backViewHeightConstraint: NSLayoutConstraint!
-  @IBOutlet public var backViewTopConstraint: NSLayoutConstraint!
+  @IBOutlet public var topView: UIView!
+  @IBOutlet public var topViewHeightConstraint: NSLayoutConstraint!
+  
+  /// This is the top view which can be scaled if `scaleFactor` was configured in `ElongationAppearance`.
+  /// Also to this view can be applied 'parallax' effect.
+  @IBOutlet public var scalableView: UIView!
+  @IBOutlet public var scalableViewTopConstraint: NSLayoutConstraint!
+  @IBOutlet public var scalableViewBottomConstraint: NSLayoutConstraint!
+  
+  @IBOutlet public var bottomView: UIView!
+  @IBOutlet public var bottomViewHeightConstraint: NSLayoutConstraint!
+  @IBOutlet public var bottomViewTopConstraint: NSLayoutConstraint!
+  @IBOutlet public var bottomViewBottomConstraint: NSLayoutConstraint!
   
   // MARK: Private properties
-  fileprivate var dimmingView = UIView()
-  
-  fileprivate var appearance: ElongationAppearance {
-    return ElongationAppearance.defaultAppearance
-  }
+  fileprivate var dimmingView: UIView!
+  fileprivate var topSeparatorLine: UIView?
+  fileprivate var bottomSeparatorLine: UIView?
+  fileprivate var appearance: ElongationConfig {
+    return ElongationConfig.shared
+  }
+  
+  fileprivate var scalableViewTopOffset: CGFloat!
+  fileprivate var scalableViewBottomOffset: CGFloat!
+  fileprivate var scalableViewLastParrallaxOffset: CGFloat!
   
   // MARK: Constructor
   public override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

  // MARK: Private
  fileprivate func updateCellState() {
    let backColor: UIColor = isExpanded ? .black : .white
    self.backgroundColor = backColor
    self.contentView.backgroundColor = backColor
    
    let frontViewHeight = self.appearance.frontViewHeight
    self.backViewTopConstraint.constant = isExpanded ? frontViewHeight - self.appearance.backViewOffset : self.appearance.backViewOffset
    self.backViewHeightConstraint.constant = isExpanded ? self.appearance.backViewHeight : frontViewHeight - self.appearance.backViewOffset
    
    let frontViewScale = isExpanded ? self.appearance.frontViewScaleFactor : 1
    self.frontView.transform = CGAffineTransform(scaleX: frontViewScale, y: frontViewScale)
    
    self.contentView.setNeedsLayout()
    self.contentView.layoutIfNeeded()
  }
  
}

  
  public required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    decode(from: aDecoder)
    commonInit()
  }
  
  private func commonInit() {
    configureCell()
    addDimmingView()
    addCustomSeparatorIfNeeded()
  }
  
  open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    let scalableViewContainsPoint = scalableView.frame.contains(point)
    let backViewContainsPoint = bottomView.frame.contains(point)
    
    if scalableViewContainsPoint {
      return scalableView
    }
    
    if backViewContainsPoint {
      return bottomView
    }
    
    return nil
  }
  
}

// MARK: - Lifecycle 🌎
extension ElongationCell {
  
  open override func willMove(toSuperview newSuperview: UIView?) {
    super.willMove(toSuperview: newSuperview)
    
    topViewHeightConstraint?.constant = appearance.topViewHeight
    guard appearance.parallaxEnabled else { return }
    scalableViewBottomConstraint?.constant -= 2 * appearance.parallaxFactor
    scalableViewTopOffset = scalableViewTopConstraint?.constant ?? 0
    scalableViewBottomOffset = scalableViewBottomConstraint?.constant ?? 0
  }
  
  open override func layoutSubviews() {
    super.layoutSubviews()
    if #available(iOS 10, *) {
      UIView.animate(withDuration: 0.3) { self.contentView.layoutIfNeeded() }
    }
  }
  
  open override func updateConstraints() {
    
    super.updateConstraints()
  }
  
}

// MARK: - Setup ⛏
private extension ElongationCell {
  
  func configureCell() {
    selectionStyle = .none
    selectedBackgroundView = nil
    clipsToBounds = true
    contentView.clipsToBounds = true
  }
  
  func addDimmingView() {
    dimmingView = UIView()
    contentView.addSubview(dimmingView)
    dimmingView.alpha = 0
    dimmingView.backgroundColor = UIColor.black
