import xarray as xr
import numpy as np
#from pathlib import Path
#import os
#import yaml

class scalelabels:
    
    def scalelabels(self,
               main_field_i,
               cbar_nlevels,
               cbar_extend,
               cbar_ticks,
               cbar_minmax
              ):


        #AUTOMATIC NUMBER OF DECIMALS IN ROUNDED LEVELS:
        cbar_labels_string = ['0']*cbar_nlevels
        cbar_labels_check = [0]*cbar_nlevels
        mindecimals = 1 #metric_parameters['cbar_ndecimals']
        for ndecimals in range(mindecimals, mindecimals+10):
            if len(cbar_labels_string) == len(set(cbar_labels_string)): # when there are no repeated values in cbar_labels_string (i.e. the list of cbar_labels_string is equal to the list of unique values in cbar_labels_string)
                #removing negative symbol in -0.0:
                if cbar_labels_string[0] == '-0.0':
                    cbar_labels_string[0] = '0.0'
                elif cbar_labels_string[0] == '-0.00':
                    cbar_labels_string[0] = '0.00'
                elif cbar_labels_string[0] == '-0.000':
                    cbar_labels_string[0] = '0.000'
                
                ndecimals = ndecimals -1 #reset to the value in the previous step of the loop
                break
            else:
                if cbar_extend == 'both':
                    if main_field_i.min().min()>=0 and np.round(cbar_minmax[0],ndecimals) == 0: # and cbar_extend == 'both':
                        cbar_extend = 'max'
                    else: 
                        cbar_extend = 'both'
                    if main_field_i.max().max()<=0 and np.round(cbar_minmax[1],ndecimals) == 0:
                        cbar_extend = 'min'
                    else:
                        cbar_extend = 'both'
                    if main_field_i.min().min()>=0 and np.round(cbar_minmax[0],ndecimals) == 0 and main_field_i.max().max()<=0 and np.round(cbar_minmax[1],ndecimals) == 0:
                        cbar_extend = 'neither'
                
                for tick_position in range(1,len(cbar_ticks)+1):
                    round_instruction = '{:.' + str(ndecimals) + 'f}'
                    cbar_labels_string[tick_position-1] = str(round_instruction.format(float(np.round(cbar_ticks[tick_position-1],ndecimals)))) #as text

        count_cases = 0
        max_power = 0
        thershold_digits_of_integer = 3
        for tick_position in range(1,len(cbar_ticks)+1):
            if len(str('{:.0f}'.format(abs(float(cbar_labels_string[tick_position-1])))))>thershold_digits_of_integer:
                count_cases = count_cases + 1
                if len(str('{:.0f}'.format(abs(float(cbar_labels_string[tick_position-1]))))) > max_power:
                    max_power = len(str('{:.0f}'.format(abs(float(cbar_labels_string[tick_position-1])))))
                    
        #if count_cases +1 >= len(cbar_ticks): #if all levels are over the threshold_digits_of_integer
        if count_cases > 1: #if some level is over the threshold_digits_of_integer
            ndecimals = 0
            scientific_notation_factor = 10**(max_power-1)
        else:
            scientific_notation_factor = 1/(10**(ndecimals-1))

        #FORMATTING cbar_labels_string TO SCIENTIFIC NOTATION:
        scientific_notation_label = str("{:.0e}".format(scientific_notation_factor)).replace('-0', '-').replace('+0','+')
        if scientific_notation_factor == 1:
            for tick_position in range(0, len(cbar_labels_string)):
                cbar_labels_string[tick_position] = '{:.1f}'.format(float(cbar_labels_string[tick_position]))
            scientific_notation_label = ''
        elif scientific_notation_factor == 0.1:
            for tick_position in range(0, len(cbar_labels_string)):
                cbar_labels_string[tick_position] = '{:.2f}'.format(float(cbar_labels_string[tick_position]))    
            scientific_notation_label = ''
        elif scientific_notation_factor == 10:
            scientific_notation_label = ''
        elif scientific_notation_factor > 10:
            for tick_position in range(1,len(cbar_ticks)+1):
                cbar_labels_string[tick_position-1] = str('{:.1f}'.format(float(cbar_labels_string[tick_position-1])/scientific_notation_factor))
            
            for ndecimals in range(mindecimals, mindecimals+10):
                if len(cbar_labels_string) == len(set(cbar_labels_string)): # when there are no repeated values in cbar_labels_string (i.e. the list of cbar_labels_string is equal to the list of unique values in cbar_labels_string)
                    #removing negative symbol in -0.0:
                    if cbar_labels_string[0] == '-0.0':
                        cbar_labels_string[0] = '0.0'
                    elif cbar_labels_string[0] == '-0.00':
                        cbar_labels_string[0] = '0.00'
                    elif cbar_labels_string[0] == '-0.000':
                        cbar_labels_string[0] = '0.000'
                    
                    if ndecimals > mindecimals:
                        ndecimals = ndecimals -1 #reset to the value in the previous step of the loop
                    break
                else:
                    for tick_position in range(1,len(cbar_ticks)+1):
                        round_instruction = '{:.' + str(ndecimals) + 'f}'
                        cbar_labels_string[tick_position-1] = str('{:.1f}'.format(float(cbar_labels_string[tick_position-1])/scientific_notation_factor))
 
        else: #if scientific_notation_factor != 1 and scientific_notation_factor != 0.1 and scientific_notation_factor != 10 and power != positive:
            for tick_position in range(0, len(cbar_labels_string)):
                cbar_labels_string[tick_position] = str(np.round(float(cbar_labels_string[tick_position])/scientific_notation_factor,1))
                cbar_labels_check[tick_position] = int(float(cbar_labels_string[tick_position]))
            if cbar_labels_check == [0]*cbar_nlevels: #if scientific notation but first figure always zero
                ndecimals = ndecimals + 1
                round_instruction = '{:.' + str(ndecimals) + 'f}'
                scientific_notation_factor = 1/(10**(ndecimals-1))
                scientific_notation_label = str("{:.0e}".format(scientific_notation_factor)).replace('-0', '-').replace('+0','+')
                for tick_position in range(1,len(cbar_ticks)+1):
                    cbar_labels_string[tick_position-1] = str(round_instruction.format(float(np.round(cbar_ticks[tick_position-1],ndecimals)))) #as text
                    cbar_labels_string[tick_position-1] = str(np.round(float(cbar_labels_string[tick_position-1])/scientific_notation_factor,1))

        return cbar_labels_string, scientific_notation_label, cbar_extend