 
 import UIKit
 
-// TODO: CAShapeLayer
-// TODO: dark keys semi-transparent, pass through blur; dark theme?
 class KeyboardKeyBackground: UIView, KeyboardView, Connectable {
     
-    var shadowOffset: Double { didSet { self.setNeedsDisplay() }}
+    var underOffset: Double { didSet { self.setNeedsDisplay() }}
     var cornerRadius: Double {
         didSet {
             self.generatePointsForDrawing()

        ]
        
        // actual coordinates for each edge, including translation
        self._segmentPoints = [] // TODO: is this declaration correct?
        
        // actual coordinates for arc centers for each corner
        self._arcCenters = []
        
        self._arcStartingAngles = []
        
        for i in 0 ..< self._startingPoints.count {
            let currentPoint = self._startingPoints[i]
            let nextPoint = self._startingPoints[(i + 1) % self._startingPoints.count]
            
            var xDir = 0.0
            var yDir = 0.0
            
            if (i == 1) {
                xDir = 1.0
                self._arcStartingAngles.append(CGFloat(M_PI))
            }
            else if (i == 3) {
                xDir = -1.0
                self._arcStartingAngles.append(CGFloat(0))
            }
            
            if (i == 0) {
                yDir = -1.0
                self._arcStartingAngles.append(CGFloat(M_PI/2.0))
            }
            else if (i == 2) {
                yDir = 1.0
                self._arcStartingAngles.append(CGFloat(-M_PI/2.0))
            }
            
            let p0 = CGPointMake(
                currentPoint.x + CGFloat(xDir * cornerRadius),
                currentPoint.y + CGFloat(shadowOffset) + CGFloat(yDir * cornerRadius))
            let p1 = CGPointMake(
                nextPoint.x - CGFloat(xDir * cornerRadius),
                nextPoint.y + CGFloat(shadowOffset) - CGFloat(yDir * cornerRadius))
            
            self._segmentPoints.append((p0, p1))
            
            let c = CGPointMake(
                p0.x - CGFloat(yDir * cornerRadius),
                p0.y + CGFloat(xDir * cornerRadius))
            
            self._arcCenters.append(c)
        }
    }
    
    func attachmentPoints(direction: Direction) -> (CGPoint, CGPoint) {
        var returnValue = (
            self._segmentPoints[direction.clockwise().toRaw()].0,
            self._segmentPoints[direction.counterclockwise().toRaw()].1)
        
        // TODO: quick hack
        returnValue.0.y -= CGFloat(self.shadowOffset)
        returnValue.1.y -= CGFloat(self.shadowOffset)
        
        return returnValue
    }
    
    func attachmentDirection() -> Direction? {
        return self._attached
    }
    
    func attach(direction: Direction?) {
        self._attached = direction
    }
}

//class KeyboardKeyPopup: KeyboardKeyBackground {
//    
//    init(frame: CGRect, vertical: Bool) {
//        super.init(frame: frame)
//    }
//    
//    // if action is nil, the key is not selectable
//    func addOption(option: String, action: String?) {
//    }
//}

        var firstEdge = false
        
        for i in 0..<4 {
            if self.attached != nil && self.attached!.toRaw() == i {
                continue
            }
            
            var edgePath = CGPathCreateMutable()
            
            CGPathMoveToPoint(edgePath, nil, self.segmentPoints[i].0.x, self.segmentPoints[i].0.y)
            CGPathAddLineToPoint(edgePath, nil, self.segmentPoints[i].1.x, self.segmentPoints[i].1.y)
            
            // TODO: figure out if this is ncessary
            if !firstEdge {
                CGPathMoveToPoint(fillPath, nil, self.segmentPoints[i].0.x, self.segmentPoints[i].0.y)
                firstEdge = true
            }
            else {
                CGPathAddLineToPoint(fillPath, nil, self.segmentPoints[i].0.x, self.segmentPoints[i].0.y)
            }
            CGPathAddLineToPoint(fillPath, nil, self.segmentPoints[i].1.x, self.segmentPoints[i].1.y)
            
            if (self.attached != nil && self.attached!.toRaw() == ((i + 1) % 4)) {
                // do nothing
            } else {
                CGPathAddRelativeArc(edgePath, nil, self.arcCenters[(i + 1) % 4].x, self.arcCenters[(i + 1) % 4].y, CGFloat(self.cornerRadius), self.arcStartingAngles[(i + 1) % 4], CGFloat(M_PI/2.0))
                CGPathAddRelativeArc(fillPath, nil, self.arcCenters[(i + 1) % 4].x, self.arcCenters[(i + 1) % 4].y, CGFloat(self.cornerRadius), self.arcStartingAngles[(i + 1) % 4], CGFloat(M_PI/2.0))
            }
            
            edgePaths.append(edgePath)
        }
        
        if self.drawUnder && self.attached != Direction.Down {
            CGContextSaveGState(ctx)
                // TODO: is this the right way to do this? either way, it works for now
                CGContextTranslateCTM(ctx, 0, -CGFloat(underOffset))
                CGContextAddPath(ctx, fillPath)
                CGContextTranslateCTM(ctx, 0, CGFloat(underOffset))
                CGContextAddPath(ctx, fillPath)
                CGContextEOClip(ctx)
            
                CGContextTranslateCTM(ctx, 0, CGFloat(underOffset))
                CGContextSetFillColorWithColor(ctx, self.underColor.CGColor)
                CGContextAddPath(ctx, fillPath)
                CGContextFillPath(ctx)
            CGContextRestoreGState(ctx)
        }
        
        // TODO: border stroke outside, not inside
        CGContextTranslateCTM(ctx, 0, -CGFloat(underOffset))
        CGContextSaveGState(ctx)
            if self.drawOver {
                // if we don't clip this draw call, the border will look messed up on account of exceeding the view bounds
                // TODO: OverflowCanvas
                CGContextAddPath(ctx, fillPath)
                CGContextClip(ctx)
                
                CGContextSetFillColorWithColor(ctx, self.color.CGColor)
                CGContextSetStrokeColorWithColor(ctx, self.borderColor.CGColor)
                CGContextSetLineWidth(ctx, 1)
                CGContextAddPath(ctx, fillPath)
                CGContextFillPath(ctx)
            }
        
            if self.drawBorder {
                for path in edgePaths {
                    CGContextAddPath(ctx, path)
                    CGContextStrokePath(ctx)
                }
            }
        CGContextRestoreGState(ctx)
        CGContextTranslateCTM(ctx, 0, CGFloat(underOffset))
    }
    
    func generatePointsForDrawing() {
        let segmentWidth = self.bounds.width
        let segmentHeight = self.bounds.height - CGFloat(underOffset)
        
        // base, untranslated corner points
        self.startingPoints = [
            CGPointMake(0, segmentHeight),
            CGPointMake(0, 0),
            CGPointMake(segmentWidth, 0),
