/**
 * Copyright (c) 2017 ~ present NAVER Corp.
 * billboard.js project is licensed under the MIT license
 */
/**
 * State class.
 * @class State
 * @ignore
 * @private
 */
export default class State {
	constructor() {
		return {
			// chart drawn area dimension, excluding axes
			width: 0,
			width2: 0,
			height: 0,
			height2: 0,
			margin: {
				top: 0,
				bottom: 0,
				left: 0,
				right: 0
			},
			margin2: {
				top: 0,
				bottom: 0,
				left: 0,
				right: 0
			},
			margin3: {
				top: 0,
				bottom: 0,
				left: 0,
				right: 0
			},
			arcWidth: 0,
			arcHeight: 0,
			xAxisHeight: 0,

			hasAxis: false,
			hasFunnel: false,
			hasRadar: false,
			hasTreemap: false,
			isCanvasMode: false,
			canvasShape: null,
			canvasFocusKey: <string | null>null,
			canvasSubchartBrushDragging: false,
			canvasSubchartBrushMode: <"select" | "move" | "resize-start" | "resize-end" | null>null,
			canvasSubchartBrushStart: <number | null>null,
			canvasSubchartBrushOrigin: <[number, number] | null>null,
			canvasSubchartBrushMoved: false,
			canvasFlowFrame: <number | null>null,
			canvasFlowFinish: <(() => void) | null>null,
			canvasFocusMainRedraw: false,

			// for data CSS rule index (used when boost.useCssRule is true)
			cssRule: {},

			// Data loading state (used in scale calculation)
			loading: <"append" | "load" | undefined>undefined,

			// Zoom/subchart domain (different from current.domain which is for rendering)
			domain: <number[] | undefined>undefined,

			current: {
				// current domain value. Assigned when is zoom is called
				domain: undefined,

				// chart whole dimension
				width: 0,
				height: 0,
				dataMax: 0,

				maxTickSize: {
					x: {
						width: 0,
						height: 0,
						ticks: <(number | string)[]>[],
						clipPath: 0,
						domain: ""
					},
					y: {width: 0, height: 0, domain: ""},
					y2: {width: 0, height: 0, domain: ""}
				},

				// current used chart type list
				types: <string[]>[],
				needle: undefined, // arc needle current value
				zoomDomain: null // zoomed domain value
			},

			// legend
			isLegendRight: false,
			isLegendInset: false,
			isLegendTop: false,
			isLegendLeft: false,
			legendStep: 0,
			legendItemWidth: 0,
			legendItemHeight: 0,
			legendHasRendered: false,
			canvasInlineStyle: {
				minHeight: ""
			},
			canvasSelection: new Set<string>(),
			canvasSelectionDragStart: <number[] | null>null,
			canvasSelectionDragIncluded: new Set<string>(),
			canvasSelectionDragging: false,
			canvasSelectionDragMoved: false,
			canvasSelectionDragMoveHandler: null,
			canvasSelectionDragEndHandler: null,

			eventReceiver: {
				currentIdx: -1, // current event interaction index
				rect: {}, // event rect's clientBoundingRect
				data: [], // event data bound of previoous eventRect
				coords: [] // coordination value of previous eventRect
			},

			axis: {
				x: {
					padding: {left: 0, right: 0},
					tickCount: 0
				}
			},

			rotatedPadding: {
				left: 30,
				right: 0,
				top: 5
			},

			withoutFadeIn: {},
			inputType: "",

			datetimeId: "",

			// clip id string
			clip: {
				id: "",
				idXAxis: "",
				idYAxis: "",
				idXAxisTickTexts: "",
				idGrid: "",
				idSubchart: "", // clipIdForSubchart
				path: "",
				pathXAxis: "",
				pathYAxis: "",
				pathXAxisTickTexts: "",
				pathGrid: ""
			},

			// state
			event: null, // event object
			dragStart: null,
			dragging: false,
			flowing: false,
			cancelClick: false,
			mouseover: false,
			rendered: false,
			transiting: false,
			redrawing: false, // if redraw() is on process
			resizing: false, // resize event called
			toggling: false, // legend toggle
			zooming: false,
			hasNegativeValue: false,
			hasPositiveValue: true,

			orgAreaOpacity: "0.2",
			orgConfig: {}, // user original genration config

			// ID strings (Set for O(1) lookup — see isTargetToShow, classFocused, etc.)
			hiddenTargetIds: new Set<string>(),
			hiddenLegendIds: new Set<string>(),
			focusedTargetIds: new Set<string>(),
			defocusedTargetIds: new Set<string>(),

			// value for Arc
			radius: 0,
			innerRadius: <Record<string, number> | number>0,
			outerRadius: <Record<string, number> | number | undefined>undefined,
			innerRadiusRatio: 0,
			gaugeArcWidth: 0,
			radiusExpanded: 0,

			// xgrid attribute
			xgridAttr: {
				x1: <number | null>null,
				x2: <number | null>null,
				y1: <number | null>null,
				y2: <number | null>null
			},

			// RAF batching for zoom/drag interactions
			pendingRaf: <number | null>null,
			rafBatchQueue: <Array<() => void>>[],

			// Dirty flags for selective redraw
			dirty: {
				data: false, // data changed (load/unload)
				visibility: false, // show/hide toggled
				size: false // dimensions changed
			},

			// Performance: generation counters for cache invalidation
			redrawGeneration: 0, // increments every redraw (for per-redraw caches)
			dataGeneration: 0, // increments on data/visibility changes (for data-dependent caches)

			// Performance: cached values for reuse within redraw cycle
			_targetsToShow: <any[] | null>null,
			_cachedDrawShape: <any>null,
			_canvasVisibleRangeCache: <Map<string, any> | null>null,
			_canvasXDataTickCache: <any>null,
			_canvasXTickValuesCache: <Map<string, any> | null>null,
			_eventRectFingerprint: <string | null>null,

			// Performance: throttle tooltip position updates on mousemove
			_lastTooltipMouse: <number[] | null>null,

			// Performance: cached grid focus D3 selection
			_gridFocusEl: <any>null,

			// Performance: generateClass() result cache (series IDs are fixed per chart)
			generateClassCache: new Map<string, string>()
		};
	}
}
