     
     /// Creates a new grid.
     ///
-    /// - parameter size:            The size of the grid.
-    /// - parameter verticalMajor:   The parameters of the vertical major lines of the grid.
-    ///                              Default line width is 0.5, line spacing is 10, line color is 50% gray.
-    /// - parameter horizontalMajor: The parameters of the horizontal major lines of the grid.
-    ///                              Default line width is 0.5, line spacing is 10, line color is 50% gray.
-    /// - parameter verticalMinor:   The parameters of the vertical minor lines of the grid.
-    ///                              If specified `nil`, no vertical minor lines will be drawn.
-    ///                              Default line width is 0.25, line color is 80% gray and the default
-    ///                              number of minor segments per one major segment is 2.
-    /// - parameter horizontalMinor: The parameters of the horizontal minor lines of the grid.
-    ///                              If specified `nil`, no horizontal minor lines will be drawn.
-    ///                              Default line width is 0.25, line color is 80% gray and the default
-    ///                              number of minor segments per one major segment is 2.
-    public init(size: Size,
-                verticalMajor: MajorLineParameters = .default,
-                horizontalMajor: MajorLineParameters = .default,
-                verticalMinor: MinorLineParameters? = .default,
-                horizontalMinor: MinorLineParameters? = .default) {
+    /// - parameter size:   The size of the grid.
+    /// - parameter lines:  The parameters of the vertical and horizontal major and minor lines of the grid.
+    ///                     Default value is `Lines.default`.
+    /// - parameter labels: The parameters of the labels for vertocal and horizontal lines of the grid. If
+    ///                     specified `nil`, no labels will be drawn. Default value is `Labels.default`.
+    /// - parameter serifs: The parameters of the serifs for vertocal and horizontal lines of the grid. If
+    ///                     specified `nil`, no serifs will be drawn. Default value is `Serifs.defalut`.
+    public init(size: Size, lines: Lines = .default, labels: Labels? = .default, serifs: Serifs? = .default) {
         
         self.size = size
-        self.verticalMajor = verticalMajor
-        self.horizontalMajor = horizontalMajor
-        self.verticalMinor = verticalMinor
-        self.horizontalMinor = horizontalMinor
+        self.lines = lines
+        
+        if let labels = labels {
+            self.labels = labels
+        } else {
+            self.labels = Labels(top: nil, bottom: nil, left: nil, right: nil)
+        }
+        
+        if let serifs = serifs {
+            self.serifs = serifs
+        } else {
+            self.serifs = Serifs(top: nil, bottom: nil, left: nil, right: nil)
+        }
     }
     
     /// Creates a new grid.
     ///
-    /// - parameter width:           The width of the grid.
-    /// - parameter height:          The height of the grid.
-    /// - parameter verticalMajor:   The parameters of the vertical major lines of the grid.
-    ///                              Default line width is 0.5, line spacing is 10, line color is 50% gray.
-    /// - parameter horizontalMajor: The parameters of the horizontal major lines of the grid.
-    ///                              Default line width is 0.5, line spacing is 10, line color is 50% gray.
-    /// - parameter verticalMinor:   The parameters of the vertical minor lines of the grid.
-    ///                              If specified `nil`, no vertical minor lines will be drawn.
-    ///                              Default line width is 0.25, line color is 80% gray and the default
-    ///                              number of minor segments per one major segment is 2.
-    /// - parameter horizontalMinor: The parameters of the horizontal minor lines of the grid.
-    ///                              If specified `nil`, no horizontal minor lines will be drawn.
-    ///                              Default line width is 0.25, line color is 80% gray and the default
-    ///                              number of minor segments per one major segment is 2.
+    /// - parameter width:  The width of the grid.
+    /// - parameter height: The height of the grid.
+    /// - parameter lines:  The parameters of the vertical and horizontal major and minor lines of the grid.
+    ///                     Default value is `Lines.default`.
+    /// - parameter labels: The parameters of the labels for vertocal and horizontal lines of the grid. If
+    ///                     specified `nil`, no labels will be drawn. Default value is `Labels.default`.
+    /// - parameter serifs: The parameters of the serifs for vertocal and horizontal lines of the grid. If
+    ///                     specified `nil`, no serifs will be drawn. Default value is `Serifs.defalut`.
     public init(width: Float,
                 height: Float,
-                verticalMajor: MajorLineParameters = .default,
-                horizontalMajor: MajorLineParameters = .default,
-                verticalMinor: MinorLineParameters? = .default,
-                horizontalMinor: MinorLineParameters? = .default) {
-        
-        self.size = Size(width: width, height: height)
-        self.verticalMajor = verticalMajor
-        self.horizontalMajor = horizontalMajor
-        self.verticalMinor = verticalMinor
-        self.horizontalMinor = horizontalMinor
-    }
+                lines: Lines = .default,
+                labels: Labels? = .default,
+                serifs: Serifs? = .default) {
+        
+        self.init(size: Size(width: width, height: height), lines: lines, labels: labels, serifs: serifs)
+    }
+    
+    // MARK: - Helper types
     
     /// Represents the properties of a grid's major lines.
     public struct MajorLineParameters {
         
-        /// Default parameters, where line width is 0.5, line spacing is 10, line color is 50% gray.
-        public static let `default` = MajorLineParameters(lineWidth: 0.5,
-                                                          lineSpacing: 10,
-                                                          lineColor: Color(gray: 0.5)!)
+        /// Default parameters, where line width is 0.5, line spacing is 10, line color is 80% gray.
+        public static let `default` = MajorLineParameters()
         
         /// The width of lines.
         public var lineWidth: Float

    
    private func _drawVerticalMinorLines(context: DrawingContext, initialPoint: Point) {
        
        guard let verticalMinor = verticalMinor else { return }
        
        context.strokeColor = verticalMinor.lineColor
        context.lineWidth = verticalMinor.lineWidth
        
        var path = Path()
        
        for x in stride(from: initialPoint.x,
                        through: initialPoint.x + size.width,
                        by: verticalMajor.lineSpacing / Float(verticalMinor.minorSegmentsPerMajorSegment)) {
                            
                            path.move(toX: x, y: initialPoint.y)
                            path.appendLine(toX: x, y: initialPoint.y + size.height)
        }
        
        context.stroke(path)

        _drawVerticalMajorLines(context: context, initialPoint: position)
        _drawHorizontalMajorLines(context: context, initialPoint: position)
        
        _drawTopSerifs(context: context, initialPoint: position)
        _drawBottomSerifs(context: context, initialPoint: position)
        _drawLeftSerifs(context: context, initialPoint: position)
        _drawRightSerifs(context: context, initialPoint: position)
        
//        _drawTopLabels(context: context, initialPoint: position)
//        _drawBottomLabels(context: context, initialPoint: position)
//        _drawLeftLabels(context: context, initialPoint: position)
//        _drawRightLabels(context: context, initialPoint: position)
        
        // Return to the initial state
        context.lineWidth = _lineWidth
        context.strokeColor = _strokeColor
        context.lineCap = _lineCap
    }
    
    
    // MARK: - Draw lines
    
    private func _strideHorizontally(initialPoint: Point, by _stride: Float) -> StrideThrough<Float> {
        return stride(from: initialPoint.x, through: initialPoint.x + size.width, by: _stride)
    }
    
    private func _strideVertically(initialPoint: Point, by _stride: Float) -> StrideThrough<Float> {
        return stride(from: initialPoint.y, through: initialPoint.y + size.height, by: _stride)
    }
    
    private func _drawVerticalMajorLines(context: DrawingContext, initialPoint: Point) {
        
        context.strokeColor = lines.verticalMajor.lineColor
        context.lineWidth = lines.verticalMajor.lineWidth
        
        var path = Path()
        
        for x in _strideHorizontally(initialPoint: initialPoint, by: lines.verticalMajor.lineSpacing) {
            
            path.move(toX: x, y: initialPoint.y)
            path.appendLine(toX: x, y: initialPoint.y + size.height)
        }
        
        context.stroke(path)
