//
//  ChartContext.swift
//  USB Meter
//
//  Created by Bogdan Timofte on 14/04/2020.
//  Copyright © 2020 Bogdan Timofte. All rights reserved.
//

import CoreGraphics
import SwiftUI

class ChartContext {
    private var rect : CGRect?
    private var pad: CGFloat = 0

    var isValid: Bool {
        get {
            return rect != nil && rect!.width > 0 && rect!.height > 0
        }
    }

    var size: CGSize {
        get {
            guard rect != nil else {
                track("Invalid Context")
                fatalError()
            }
            return rect!.size
        }
    }

    var origin: CGPoint {
        get {
            guard rect != nil else {
                track("Invalid Context")
                fatalError()
            }
            return rect!.origin
        }
    }

    var minValue: Double {
        return rect == nil ? .nan : Double(rect!.minY)
    }

    var maxValue: Double {
        get {
            return rect == nil ? .nan : Double(rect!.maxY)
        }
    }

    func reset() {
        rect = nil
        padding()
    }
    func include( point: CGPoint )  {
        if rect == nil {
            rect = CGRect(origin: point, size: .zero)
            padding()
        } else {
            rect = rect!.union(CGRect(origin: point, size: .zero))
            padding()
        }
    }
    
    func padding() {
        guard rect != nil else {
            track("Invalid Context")
            pad = 0
            fatalError()
        }
        pad = rect!.size.height * Constants.chartUnderscan
    }
    
    func yAxisLabel( for itemNo: Int, of items: Int ) -> Double {
        let labelSpace = Double(rect!.height) / Double(items - 1)
        let labelRelativeValue = labelSpace * Double(itemNo - 1)
        return minValue + labelRelativeValue
    }
    
    // MARK: Conversii dubioase
    func xAxisLabel( for itemNo: Int, of items: Int ) -> Double {
        let labelSpace = Double(rect!.width) / Double(items - 1)
        let labelRelativeValue = labelSpace * Double(itemNo - 1)
        return Double(rect!.origin.x) + labelRelativeValue
    }
    
    func placeInRect (point: CGPoint) -> CGPoint {
        guard rect != nil else {
            track("Invalid Context")
            fatalError()
        }
        guard rect!.width != 0 else {
            fatalError()
        }
        guard rect!.height != 0 else {
            fatalError()
        }

        let x = (point.x - rect!.origin.x)/rect!.width
        let y = (pad + point.y - rect!.origin.y)/rect!.height
        return CGPoint(x: x, y: 1 - y * Constants.chartOverscan)
    }
}
