# Path: cmt/mapclient_qt.py
# def addToMap(self, eeobject, vis_params=None, name="", show=True):
#     '''Ads an EE object to the map'''
#         
#     # Flatten any lists to comma separated strings - needed for eeobject.getMapId() call below!
#     if vis_params:
#         vis_params = dict(vis_params)
#         for key in vis_params.keys():
#             item = vis_params.get(key)
#             if (isinstance(item, collections.Iterable) and (not isinstance(item, basestring))):
#                  vis_params[key] = ','.join([str(x) for x in item])
# 
#     def execute_thread(waiting_threads):
#         # get thread before starting
#         with self.thread_lock:
#             pass
#         result = eeobject.getMapId(vis_params)
#         for t in waiting_threads:
#             t.join()
#         with self.thread_lock:
#             self.executing_threads.pop(0)
#         return result
# 
#     with self.thread_lock:
#         self.executing_threads.append(cmt.util.miscUtilities.waitForEeResult(functools.partial(execute_thread, list(self.executing_threads)),
#                     lambda a : self.addOverlay(MakeTileManager(a), eeobject, name, show, vis_params)))
# 
# Path: cmt/util/miscUtilities.py
# def safe_get_info(ee_object, max_num_attempts=5):
#     '''Keep trying to call getInfo() on an Earth Engine object until it succeeds.'''
#     
#     # Do not try again if we get one of these exceptions
#     fail_messages = ['Too many pixels']
#     
#     num_attempts = 0
#     while True:
#         try:
#             return ee_object.getInfo()
#         except Exception as e:
#             # Rethrow the exception if it is not timeout related
#             for message in fail_messages:
#                 if message in str(e):
#                     raise e
#                     
#             print('Earth Engine Error: %s. Waiting 10s and then retrying.' % (e))
#             time.sleep(10)
#             num_attempts += 1
#         if max_num_attempts and (num_attempts >= max_num_attempts):
#             raise Exception('safe_get_info failed to succeed after ' +str(num_attempts)+ ' attempts!')


import ee
import math
from cmt.mapclient_qt import addToMap
from cmt.util.miscUtilities import safe_get_info
from cmt.modis.simple_modis_algorithms import *
from modis_utilities import *


def _create_learning_image(domain, b):
    '''Set up features for the classifier to be trained on'''

    outputBands = _get_modis_learning_bands(domain, b) # Get the standard set of MODIS learning bands
    #outputBands = _get_extensive_modis_learning_bands(domain, b) # Get the standard set of MODIS learning bands
    
    
    # Try to add a DEM
    try:
        dem = domain.get_dem().image
        outputBands.addBands(dem)
        #outputBands = dem
    except AttributeError:
        pass # Suppress error if there is no DEM data
    
    # Try to add Skybox RGB info (NIR is handled separately because not all Skybox images have it)
    # - Use all the base bands plus a grayscale texture measure
    try:
        try: # The Skybox data can be in one of two names
            skyboxSensor = domain.skybox
        except:
            skyboxSensor = domain.skybox_nir
            
        rgbBands    = skyboxSensor.Red.addBands(skyboxSensor.Green).addBands(skyboxSensor.Blue)
        grayBand    = rgbBands.select('Red').add(rgbBands.select('Green')).add(rgbBands.select('Blue')).divide(ee.Image(3.0)).uint16()
        edges       = grayBand.convolve(ee.Kernel.laplacian8(normalize=True)).abs()
        texture     = edges.convolve(ee.Kernel.square(3, 'pixels')).select(['Red'], ['Texture'])
        texture2Raw = grayBand.glcmTexture()

# Path: cmt/mapclient_qt.py
# def addToMap(self, eeobject, vis_params=None, name="", show=True):
#     '''Ads an EE object to the map'''
#         
#     # Flatten any lists to comma separated strings - needed for eeobject.getMapId() call below!
#     if vis_params:
#         vis_params = dict(vis_params)
#         for key in vis_params.keys():
#             item = vis_params.get(key)
#             if (isinstance(item, collections.Iterable) and (not isinstance(item, basestring))):
#                  vis_params[key] = ','.join([str(x) for x in item])
# 
#     def execute_thread(waiting_threads):
#         # get thread before starting
#         with self.thread_lock:
#             pass
#         result = eeobject.getMapId(vis_params)
#         for t in waiting_threads:
#             t.join()
#         with self.thread_lock:
#             self.executing_threads.pop(0)
#         return result
# 
#     with self.thread_lock:
#         self.executing_threads.append(cmt.util.miscUtilities.waitForEeResult(functools.partial(execute_thread, list(self.executing_threads)),
#                     lambda a : self.addOverlay(MakeTileManager(a), eeobject, name, show, vis_params)))
# 
# Path: cmt/util/miscUtilities.py
# def safe_get_info(ee_object, max_num_attempts=5):
#     '''Keep trying to call getInfo() on an Earth Engine object until it succeeds.'''
#     
#     # Do not try again if we get one of these exceptions
#     fail_messages = ['Too many pixels']
#     
#     num_attempts = 0
#     while True:
#         try:
#             return ee_object.getInfo()
#         except Exception as e:
#             # Rethrow the exception if it is not timeout related
#             for message in fail_messages:
#                 if message in str(e):
#                     raise e
#                     
#             print('Earth Engine Error: %s. Waiting 10s and then retrying.' % (e))
#             time.sleep(10)
#             num_attempts += 1
#         if max_num_attempts and (num_attempts >= max_num_attempts):
#             raise Exception('safe_get_info failed to succeed after ' +str(num_attempts)+ ' attempts!')


# Path: cmt/modis/ee_classifiers.py
import ee
import math
from cmt.mapclient_qt import addToMap
from cmt.util.miscUtilities import safe_get_info
from cmt.modis.simple_modis_algorithms import *
from modis_utilities import *



def _create_learning_image(domain, b):
    '''Set up features for the classifier to be trained on'''

    outputBands = _get_modis_learning_bands(domain, b) # Get the standard set of MODIS learning bands
    #outputBands = _get_extensive_modis_learning_bands(domain, b) # Get the standard set of MODIS learning bands
    
    
    # Try to add a DEM
    try:
        dem = domain.get_dem().image
        outputBands.addBands(dem)
        #outputBands = dem
    except AttributeError:
        pass # Suppress error if there is no DEM data
    
    # Try to add Skybox RGB info (NIR is handled separately because not all Skybox images have it)
    # - Use all the base bands plus a grayscale texture measure
    try:
        try: # The Skybox data can be in one of two names
            skyboxSensor = domain.skybox
        except:
            skyboxSensor = domain.skybox_nir
            
        rgbBands    = skyboxSensor.Red.addBands(skyboxSensor.Green).addBands(skyboxSensor.Blue)
        grayBand    = rgbBands.select('Red').add(rgbBands.select('Green')).add(rgbBands.select('Blue')).divide(ee.Image(3.0)).uint16()
        edges       = grayBand.convolve(ee.Kernel.laplacian8(normalize=True)).abs()
        texture     = edges.convolve(ee.Kernel.square(3, 'pixels')).select(['Red'], ['Texture'])
        texture2Raw = grayBand.glcmTexture()

        bandList    = safe_get_info(texture2Raw)['bands']