# Chart Types
class CHART_TYPES:
    LINE = 'line'
    LINE_XY = 'line_xy'
    BAR = 'bar'
    HORIZONTAL_BAR = 'horizontalBar'
    RADAR = 'radar'
    POLAR = 'polarArea'
    PIE = 'pie'
    DOUGHNUT = 'doughnut'
    BUBBLE = 'bubble'
    SCATTER = 'scatter'

    @classmethod
    def is_coordinate_type(cls, type):
        return type in [cls.LINE_XY, cls.BUBBLE, cls.SCATTER]

    get_choices = ((LINE, LINE),
                   (LINE_XY, LINE_XY),
                   (BAR, BAR),
                   (HORIZONTAL_BAR, HORIZONTAL_BAR),
                   (RADAR, RADAR),
                   (POLAR, POLAR),
                   (PIE, PIE),
                   (DOUGHNUT, DOUGHNUT),
                   (BUBBLE, BUBBLE),
                   (SCATTER, SCATTER),)


AXIS_TYPES = [('linear', 'linear'),
              ('logarithmic', 'logarithmic'),
              ('category', 'category'),
              ('time', 'time'),
              ('radial', 'radial'), ]

AXIS_DISPLAY = [('true', 'true'),
              ('false', 'false'),
              ('auto', 'auto'), ]

DATASET_FORMATS = [('rows', 'rows'),
                   ('cols', 'cols'),]

LEGEND_POSITIONS = [('top', 'top'),
                    ('left', 'left'),
                    ('bottom', 'bottom'),
                    ('right', 'right'), ]

OPTION_DATA_TYPES = [('text', 'text'),
                     ('number', 'number'),
                     ('boolean', 'boolean'),
                     ('json', 'json'),
                     ('array', 'array'),
                     ('function', 'function')]

COLOR_LABELS = [('backgroundColor', 'backgroundColor'),
                ('borderColor', 'borderColor'),
                ('hoverBackgroundColor', 'hoverBackgroundColor'),
                ('hoverBorderColor', 'hoverBorderColor'),
                ('pointBackgroundColor', 'pointBackgroundColor'),
                ('pointBorderColor', 'pointBorderColor'),
                ('pointHoverBackgroundColor', 'pointHoverBackgroundColor'),
                ('pointHoverBorderColor', 'pointHoverBorderColor')]

# -------------------------------

# Options

# -------------------------------

CHARTJS_GLOBAL_OPTIONS_LOOKUP = {
    "Chart.defaults.bar": [
        "bar.hover.mode",
        "bar.scales.xAxes",
        "bar.scales.yAxes",
    ],
    "Chart.defaults.bubble": [
        "bubble.hover.mode",
        "bubble.scales.xAxes",
        "bubble.scales.yAxes",
        "bubble.tooltips.callbacks.label",
        "bubble.tooltips.callbacks.title",
    ],
    "Chart.defaults.doughnut": [
        "doughnut.animation.animateRotate",
        "doughnut.animation.animateScale",
        "doughnut.circumference",
        "doughnut.cutoutPercentage",
        "doughnut.hover.mode",
        "doughnut.legend.labels.generateLabels",
        "doughnut.legend.onClick",
        "doughnut.legendCallback",
        "doughnut.rotation",
        "doughnut.tooltips.callbacks.label",
        "doughnut.tooltips.callbacks.title",
    ],
    "Chart.defaults.global": [
        "global.animation.duration",
        "global.animation.easing",
        "global.animation.onComplete",
        "global.animation.onProgress",
        "global.datasets.bar.barPercentage",
        "global.datasets.bar.categoryPercentage",
        "global.datasets.horizontalBar.barPercentage",
        "global.datasets.horizontalBar.categoryPercentage",
        "global.datasets.scatter.showLine",
        "global.defaultColor",
        "global.defaultFontColor",
        "global.defaultFontFamily",
        "global.defaultFontSize",
        "global.defaultFontStyle",
        "global.defaultLineHeight",
        "global.elements.arc.backgroundColor",
        "global.elements.arc.borderAlign",
        "global.elements.arc.borderColor",
        "global.elements.arc.borderWidth",
        "global.elements.line.backgroundColor",
        "global.elements.line.borderCapStyle",
        "global.elements.line.borderColor",
        "global.elements.line.borderDash",
        "global.elements.line.borderDashOffset",
        "global.elements.line.borderJoinStyle",
        "global.elements.line.borderWidth",
        "global.elements.line.capBezierPoints",
        "global.elements.line.fill",
        "global.elements.line.tension",
        "global.elements.point.backgroundColor",
        "global.elements.point.borderColor",
        "global.elements.point.borderWidth",
        "global.elements.point.hitRadius",
        "global.elements.point.hoverBorderWidth",
        "global.elements.point.hoverRadius",
        "global.elements.point.pointStyle",
        "global.elements.point.radius",
        "global.elements.rectangle.backgroundColor",
        "global.elements.rectangle.borderColor",
        "global.elements.rectangle.borderSkipped",
        "global.elements.rectangle.borderWidth",
        "global.events",
        "global.hover.animationDuration",
        "global.hover.intersect",
        "global.hover.mode",
        "global.hover.onHover",
        "global.layout.padding.bottom",
        "global.layout.padding.left",
        "global.layout.padding.right",
        "global.layout.padding.top",
        "global.legend.align",
        "global.legend.display",
        "global.legend.fullWidth",
        "global.legend.labels.boxWidth",
        "global.legend.labels.generateLabels",
        "global.legend.labels.padding",
        "global.legend.onClick",
        "global.legend.onHover",
        "global.legend.onLeave",
        "global.legend.position",
        "global.legend.reverse",
        "global.legend.weight",
        "global.legendCallback",
        "global.maintainAspectRatio",
        "global.onClick",
        "global.plugins.filler.propagate",
        "global.responsive",
        "global.responsiveAnimationDuration",
        "global.showLines",
        "global.title.display",
        "global.title.fontStyle",
        "global.title.fullWidth",
        "global.title.padding",
        "global.title.position",
        "global.title.text",
        "global.title.weight",
        "global.tooltips.backgroundColor",
        "global.tooltips.bodyAlign",
        "global.tooltips.bodyFontColor",
        "global.tooltips.bodySpacing",
        "global.tooltips.borderColor",
        "global.tooltips.borderWidth",
        "global.tooltips.callbacks.afterBody",
        "global.tooltips.callbacks.afterFooter",
        "global.tooltips.callbacks.afterLabel",
        "global.tooltips.callbacks.afterTitle",
        "global.tooltips.callbacks.beforeBody",
        "global.tooltips.callbacks.beforeFooter",
        "global.tooltips.callbacks.beforeLabel",
        "global.tooltips.callbacks.beforeTitle",
        "global.tooltips.callbacks.footer",
        "global.tooltips.callbacks.label",
        "global.tooltips.callbacks.labelColor",
        "global.tooltips.callbacks.labelTextColor",
        "global.tooltips.callbacks.title",
        "global.tooltips.caretPadding",
        "global.tooltips.caretSize",
        "global.tooltips.cornerRadius",
        "global.tooltips.custom",
        "global.tooltips.displayColors",
        "global.tooltips.enabled",
        "global.tooltips.footerAlign",
        "global.tooltips.footerFontColor",
        "global.tooltips.footerFontStyle",
        "global.tooltips.footerMarginTop",
        "global.tooltips.footerSpacing",
        "global.tooltips.intersect",
        "global.tooltips.mode",
        "global.tooltips.multiKeyBackground",
        "global.tooltips.position",
        "global.tooltips.titleAlign",
        "global.tooltips.titleFontColor",
        "global.tooltips.titleFontStyle",
        "global.tooltips.titleMarginBottom",
        "global.tooltips.titleSpacing",
        "global.tooltips.xPadding",
        "global.tooltips.yPadding",
    ],
    "Chart.defaults.horizontalBar": [
        "horizontalBar.elements.rectangle.borderSkipped",
        "horizontalBar.hover.axis",
        "horizontalBar.hover.mode",
        "horizontalBar.scales.xAxes",
        "horizontalBar.scales.yAxes",
        "horizontalBar.tooltips.axis",
        "horizontalBar.tooltips.mode",
    ],
    "Chart.defaults.line": [
        "line.hover.mode",
        "line.scales.xAxes",
        "line.scales.yAxes",
        "line.showLines",
        "line.spanGaps",
    ],
    "Chart.defaults.pie": [
        "pie.animation.animateRotate",
        "pie.animation.animateScale",
        "pie.circumference",
        "pie.cutoutPercentage",
        "pie.hover.mode",
        "pie.legend.labels.generateLabels",
        "pie.legend.onClick",
        "pie.legendCallback",
        "pie.rotation",
        "pie.tooltips.callbacks.label",
        "pie.tooltips.callbacks.title",
    ],
    "Chart.defaults.polarArea": [
        "polarArea.animation.animateRotate",
        "polarArea.animation.animateScale",
        "polarArea.legend.labels.generateLabels",
        "polarArea.legend.onClick",
        "polarArea.legendCallback",
        "polarArea.scale.angleLines.display",
        "polarArea.scale.gridLines.circular",
        "polarArea.scale.pointLabels.display",
        "polarArea.scale.ticks.beginAtZero",
        "polarArea.scale.type",
        "polarArea.startAngle",
        "polarArea.tooltips.callbacks.label",
        "polarArea.tooltips.callbacks.title",
    ],
    "Chart.defaults.radar": [
        "radar.elements.line.fill",
        "radar.elements.line.tension",
        "radar.scale.type",
        "radar.spanGaps",
    ],
    "Chart.defaults.scale": [
        "scale.display",
        "scale.gridLines.borderDash",
        "scale.gridLines.borderDashOffset",
        "scale.gridLines.color",
        "scale.gridLines.display",
        "scale.gridLines.drawBorder",
        "scale.gridLines.drawOnChartArea",
        "scale.gridLines.drawTicks",
        "scale.gridLines.lineWidth",
        "scale.gridLines.offsetGridLines",
        "scale.gridLines.tickMarkLength",
        "scale.gridLines.zeroLineBorderDash",
        "scale.gridLines.zeroLineBorderDashOffset",
        "scale.gridLines.zeroLineColor",
        "scale.gridLines.zeroLineWidth",
        "scale.offset",
        "scale.position",
        "scale.scaleLabel.display",
        "scale.scaleLabel.labelString",
        "scale.scaleLabel.padding.bottom",
        "scale.scaleLabel.padding.top",
        "scale.ticks.autoSkip",
        "scale.ticks.autoSkipPadding",
        "scale.ticks.beginAtZero",
        "scale.ticks.callback",
        "scale.ticks.display",
        "scale.ticks.labelOffset",
        "scale.ticks.maxRotation",
        "scale.ticks.minRotation",
        "scale.ticks.mirror",
        "scale.ticks.padding",
        "scale.ticks.reverse",
    ],
    "Chart.defaults.scatter": [
        "scatter.hover.mode",
        "scatter.scales.xAxes",
        "scatter.scales.yAxes",
        "scatter.tooltips.callbacks.label",
        "scatter.tooltips.callbacks.title",
    ],

}


CACHE_GLOBAL_CHART_OPTIONS = []

def get_chartjs_global_options():
    global CACHE_GLOBAL_CHART_OPTIONS
    if not CACHE_GLOBAL_CHART_OPTIONS:
        CACHE_GLOBAL_CHART_OPTIONS = [(k, [(f'Chart.defaults.{c}', c) for c in v]) for k, v in CHARTJS_GLOBAL_OPTIONS_LOOKUP.items()]
    return CACHE_GLOBAL_CHART_OPTIONS



CHARTJS_CHART_OPTIONS_LOOKUP = {
    "options": [
        "circumference",
        "cutoutPercentage",
        "defaultColor",
        "defaultFontColor",
        "defaultFontFamily",
        "defaultFontSize",
        "defaultFontStyle",
        "defaultLineHeight",
        "events",
        "legendCallback",
        "maintainAspectRatio",
        "onClick",
        "responsive",
        "responsiveAnimationDuration",
        "rotation",
        "showLines",
        "spanGaps",
    ],
    "options.animation": [
        "animation.animateRotate",
        "animation.animateScale",
        "animation.duration",
        "animation.easing",
        "animation.onComplete",
        "animation.onProgress",
    ],
    "options.datasets": [
        "datasets.bar.barPercentage",
        "datasets.bar.categoryPercentage",
        "datasets.horizontalBar.barPercentage",
        "datasets.horizontalBar.categoryPercentage",
        "datasets.scatter.showLine",
    ],
    "options.elements": [
        "elements.arc.backgroundColor",
        "elements.arc.borderAlign",
        "elements.arc.borderColor",
        "elements.arc.borderWidth",
        "elements.line.backgroundColor",
        "elements.line.borderCapStyle",
        "elements.line.borderColor",
        "elements.line.borderDash",
        "elements.line.borderDashOffset",
        "elements.line.borderJoinStyle",
        "elements.line.borderWidth",
        "elements.line.capBezierPoints",
        "elements.line.fill",
        "elements.line.tension",
        "elements.point.backgroundColor",
        "elements.point.borderColor",
        "elements.point.borderWidth",
        "elements.point.hitRadius",
        "elements.point.hoverBorderWidth",
        "elements.point.hoverRadius",
        "elements.point.pointStyle",
        "elements.point.radius",
        "elements.rectangle.backgroundColor",
        "elements.rectangle.borderColor",
        "elements.rectangle.borderSkipped",
        "elements.rectangle.borderWidth",
    ],
    "options.hover": [
        "hover.animationDuration",
        "hover.intersect",
        "hover.mode",
        "hover.onHover",
    ],
    "options.layout": [
        "layout.padding.bottom",
        "layout.padding.left",
        "layout.padding.right",
        "layout.padding.top",
    ],
    "options.legend": [
        "legend.labels.boxWidth",
        "legend.labels.generateLabels",
        "legend.labels.padding",
        "legend.align",
        "legend.display",
        "legend.fullWidth",
        "legend.onClick",
        "legend.onHover",
        "legend.onLeave",
        "legend.position",
        "legend.reverse",
        "legend.weight",
    ],
    "options.plugins": [
        "plugins.filler.propagate",
    ],
    "options.scale": [
        "scale.angleLines.borderDash",
        "scale.angleLines.borderDashOffset",
        "scale.angleLines.color",
        "scale.angleLines.display",
        "scale.angleLines.lineWidth",
        "scale.gridLines.borderDash",
        "scale.gridLines.borderDashOffset",
        "scale.gridLines.circular",
        "scale.gridLines.color",
        "scale.gridLines.display",
        "scale.gridLines.drawBorder",
        "scale.gridLines.drawOnChartArea",
        "scale.gridLines.drawTicks",
        "scale.gridLines.lineWidth",
        "scale.gridLines.offsetGridLines",
        "scale.gridLines.tickMarkLength",
        "scale.gridLines.zeroLineBorderDash",
        "scale.gridLines.zeroLineBorderDashOffset",
        "scale.gridLines.zeroLineColor",
        "scale.gridLines.zeroLineWidth",
        "scale.pointLabels.callback",
        "scale.pointLabels.display",
        "scale.pointLabels.fontSize",
        "scale.scaleLabel.display",
        "scale.scaleLabel.labelString",
        "scale.scaleLabel.lineHeight",
        "scale.scaleLabel.fontColor",
        "scale.scaleLabel.fontFamily",
        "scale.scaleLabel.fontSize",
        "scale.scaleLabel.fontStyle",
        "scale.scaleLabel.padding",
        "scale.ticks.autoSkip",
        "scale.ticks.autoSkipPadding",
        "scale.ticks.backdropColor",
        "scale.ticks.backdropPaddingX",
        "scale.ticks.backdropPaddingY",
        "scale.ticks.beginAtZero",
        "scale.ticks.callback",
        "scale.ticks.display",
        "scale.ticks.labelOffset",
        "scale.ticks.maxRotation",
        "scale.ticks.minRotation",
        "scale.ticks.mirror",
        "scale.ticks.padding",
        "scale.ticks.reverse",
        "scale.ticks.showLabelBackdrop",
        "scale.animate",
        "scale.display",
        "scale.id",
        "scale.offset",
        "scale.position",
        "scale.type",
    ],
    "options.title": [
        "title.display",
        "title.fontStyle",
        "title.fullWidth",
        "title.padding",
        "title.position",
        "title.text",
        "title.weight",
    ],
    "options.tooltips": [
        "tooltips.callbacks.afterBody",
        "tooltips.callbacks.afterFooter",
        "tooltips.callbacks.afterLabel",
        "tooltips.callbacks.afterTitle",
        "tooltips.callbacks.beforeBody",
        "tooltips.callbacks.beforeFooter",
        "tooltips.callbacks.beforeLabel",
        "tooltips.callbacks.beforeTitle",
        "tooltips.callbacks.footer",
        "tooltips.callbacks.label",
        "tooltips.callbacks.labelColor",
        "tooltips.callbacks.labelTextColor",
        "tooltips.callbacks.title",
        "tooltips.backgroundColor",
        "tooltips.bodyAlign",
        "tooltips.bodyFontColor",
        "tooltips.bodyFontFamily",
        "tooltips.bodyFontSize",
        "tooltips.bodySpacing",
        "tooltips.bodyFontStyle",
        "tooltips.borderColor",
        "tooltips.borderWidth",
        "tooltips.caretPadding",
        "tooltips.caretSize",
        "tooltips.cornerRadius",
        "tooltips.custom",
        "tooltips.displayColors",
        "tooltips.enabled",
        "tooltips.footerAlign",
        "tooltips.footerFontColor",
        "tooltips.footerFontStyle",
        "tooltips.footerMarginTop",
        "tooltips.footerSpacing",
        "tooltips.intersect",
        "tooltips.mode",
        "tooltips.multiKeyBackground",
        "tooltips.position",
        "tooltips.titleAlign",
        "tooltips.titleFontColor",
        "tooltips.titleFontStyle",
        "tooltips.titleMarginBottom",
        "tooltips.titleSpacing",
        "tooltips.xPadding",
        "tooltips.yPadding",
    ],

}

CACHE_CHART_OPTIONS = []

def get_chartjs_chart_options():
    global CACHE_CHART_OPTIONS
    if not CACHE_CHART_OPTIONS:
        CACHE_CHART_OPTIONS = [(k, [(f'options.{c}', c) for c in v]) for k, v in CHARTJS_CHART_OPTIONS_LOOKUP.items()]
    return CACHE_CHART_OPTIONS


CHARTJS_DATASET_OPTIONS = [
    'backgroundColor',
    'borderAlign',
    'borderCapStyle',
    'borderColor',
    'borderDash',
    'borderDashOffset',
    'borderJoinStyle',
    'borderSkipped',
    'borderWidth',
    'clip',
    'cubicInterpolationMode',
    'data',
    'fill',
    'hitRadius',
    'hoverBackgroundColor',
    'hoverBorderCapStyle',
    'hoverBorderColor',
    'hoverBorderDash',
    'hoverBorderDashOffset',
    'hoverBorderJoinStyle',
    'hoverBorderWidth',
    'hoverRadius',
    'label',
    'lineTension',
    'order',
    'pointBackgroundColor',
    'pointBorderColor',
    'pointBorderWidth',
    'pointHitRadius',
    'pointHoverBackgroundColor',
    'pointHoverBorderColor',
    'pointHoverBorderWidth',
    'pointHoverRadius',
    'pointRadius',
    'pointRotation',
    'pointStyle',
    'radius',
    'rotation',
    'showLine',
    'spanGaps',
    'steppedLine',
    'weight',
]

CACHE_DATASET_OPTIONS = []

def get_chartjs_dataset_options():
    global CACHE_DATASET_OPTIONS
    if not CACHE_DATASET_OPTIONS:
        CACHE_DATASET_OPTIONS = [(opt, opt) for opt in CHARTJS_DATASET_OPTIONS]
    return CACHE_DATASET_OPTIONS


CHARTJS_AXIS_OPTIONS = {
    'scale': [
        'adapters.date',
        'bounds',
        'distribution',
        'offset',
        'position',
        'scaleLabel',
        'stacked',
        'type',
    ], 'angleLines': [
        'angleLines.display',
        'angleLines.color',
        'angleLines.lineWidth',
        'angleLines.borderDash',
        'angleLines.borderDashOffset',
    ], 'gridLines': [
        'gridLines.display',
        'gridLines.circular',
        'gridLines.color',
        'gridLines.borderDash',
        'gridLines.borderDashOffset',
        'gridLines.lineWidth',
        'gridLines.drawBorder',
        'gridLines.drawOnChartArea',
        'gridLines.drawTicks',
        'gridLines.tickMarkLength',
        'gridLines.zeroLineWidth',
        'gridLines.zeroLineColor',
        'gridLines.zeroLineBorderDash',
        'gridLines.zeroLineBorderDashOffset',
        'gridLines.offsetGridLines',
        'gridLines.z',
    ], 'pointLabels': [
        'pointLabels.display',
        'pointLabels.callback',
        'pointLabels.fontColor',
        'pointLabels.fontFamily',
        'pointLabels.fontSize',
        'pointLabels.fontStyle',
        'pointLabels.lineHeight',
    ], 'scaleLabel': [
        'scaleLabel.display',
        'scaleLabel.labelString',
        'scaleLabel.lineHeight',
        'scaleLabel.fontColor',
        'scaleLabel.fontFamily',
        'scaleLabel.fontSize',
        'scaleLabel.fontStyle',
        'scaleLabel.padding',
    ], 'ticks': [
        'ticks.source',
        'ticks.min',
        'ticks.max',
        'ticks.sampleSize',
        'ticks.autoSkip',
        'ticks.autoSkipPadding',
        'ticks.labelOffset',
        'ticks.maxRotation',
        'ticks.minRotation',
        'ticks.mirror',
        'ticks.padding',
        'ticks.labels',
        'ticks.beginAtZero',
        'ticks.maxTicksLimit',
        'ticks.precision',
        'ticks.stepSize',
        'ticks.suggestedMax',
        'ticks.suggestedMin',
        'ticks.backdropColor',
        'ticks.backdropPaddingX',
        'ticks.backdropPaddingY',
        'ticks.showLabelBackdrop',
    ], 'ticks.minor': [
        'ticks.minor.callback',
        'ticks.minor.fontColor',
        'ticks.minor.fontFamily',
        'ticks.minor.fontSize',
        'ticks.minor.fontStyle',
        'ticks.minor.lineHeight',
        'ticks.major.enabled',
    ], 'ticks.major': [
        'ticks.major.callback',
        'ticks.major.fontColor',
        'ticks.major.fontFamily',
        'ticks.major.fontSize',
        'ticks.major.fontStyle',
        'ticks.major.lineHeight',
    ], 'time': [
        'time.displayFormats',
        'time.isoWeekday',
        'time.minUnit',
        'time.parser',
        'time.round',
        'time.stepSize',
        'time.tooltipFormat',
        'time.unit',
    ]
}

CACHE_AXIS_OPTIONS = []

def get_chartjs_axis_options():
    global CACHE_AXIS_OPTIONS
    if not CACHE_AXIS_OPTIONS:
        CACHE_AXIS_OPTIONS =  [(k, [(c, c) for c in v]) for k, v in CHARTJS_AXIS_OPTIONS.items()]
    return CACHE_AXIS_OPTIONS
