# Module related with dataset

import os
import urllib
import zipfile
import numpy as np



def download(dataset_name = 'UCI HAR'):
    """"Download database to local folder
    
    """
    
    # Init
    dataset_valid = False
    dataset_folder = "./"
    download_folder = os.path.abspath("../dataset/donwload/") + "/"
    
    # Porcess dataset identifier
    if dataset_name == 'UCI HAR':
        dataset_folder = os.path.abspath("../dataset/UCI HAR/") + "/"
        dataset_name = "UCI HAR Dataset"
        
        dataset_url = "https://archive.ics.uci.edu/ml/machine-learning-databases/00240/UCI%20HAR%20Dataset.zip"
        dataset_file = "UCI HAR Dataset.zip"
        
        dataset_names_url = "https://archive.ics.uci.edu/ml/machine-learning-databases/00240/UCI%20HAR%20Dataset.names"
        dataset_names_file = "UCI HAR Dataset.names"
        
        dataset_valid = True
    else:
        print "Dataset's identifier not valid!"
    
    
    # Check if database option is valid
    if dataset_valid == True:
        # Check folder for downloading
        if not os.path.exists(download_folder):
            os.makedirs(download_folder)
          
        # Check if dataset was donwloaded previously
        if not os.path.exists(download_folder + dataset_file):
            # Downloading
            try:
                print "Downloading dataset from {}...".format(dataset_url)
                
                ds_file = urllib.URLopener()
                ds_file.retrieve(dataset_url, download_folder + dataset_file)         

                ds_file = urllib.URLopener()
                ds_file.retrieve(dataset_names_url, download_folder + dataset_names_file)

                print "Dataset downloaded in {}".format(os.path.abspath(download_folder))
                
            except ValueError:
                print "Dataset could't be downloaded."
        else:
            print "Dataset is already downloaded."
            
        # Check dataset folder in project structure
        if not os.path.exists(dataset_folder):
            os.makedirs(dataset_folder)
            
            # unzip files
            try:
                print "Unzipping files..."
                
                z = zipfile.ZipFile(download_folder + dataset_file, 'r')
                z.extractall(dataset_folder)
                z.close()
                
                print "Files unzipped in {}".format(dataset_folder)
                
            except:
                print "Error unzipping files."
        else:
            print "Dataset folder {} exist. File is not unzipped".format(dataset_folder)
    
    
def get_data(filenames, dataset_name = 'UCI HAR', print_on = False):
    """ Extract the data from database files
    
    """
    # DataTrain [variable, #sample, samples]
    data = []
    
    for filename in filenames:
        
        if print_on: print filename

        with open(filename) as f:
            sensorData = []

            for row in f:
                if dataset_name == 'UCI HAR':
                    
                    row_formated = row.replace('  ', ' ').strip()
                    str_samples = row_formated.split(' ')

                    samples = np.fromstring(row_formated, dtype=np.float32, sep=' ')
                
                sensorData.append(samples)

            sensorData = np.array(sensorData)

        data.append(sensorData)

    data = np.array(data)
    return data


def get_labels(filename, dataset_name = 'UCI HAR', print_on = False):
    """ Extract the labels from database files
    
    """

    dataLabel = []
    
    with open(filename) as f:
        
        if print_on: print filename
            
        for row in f:
            dataLabel.append(np.float(row.strip()))
    
        dataLabel = np.array(dataLabel)
    
    return dataLabel

def encode_onehot(labels):
    """ Enconde to one-hot the labels' array
    
    """
    LabelMax = int(np.max(labels))

    labels_coded = np.zeros([len(labels), LabelMax + 1])
    for idx, label in enumerate(labels):
        labels_coded[idx,int(labels[idx])] = 1

    return labels_coded

def make_labels_dictionary(descFilename):
    # labelNum labelDescription
    with open(descFilename) as f:
        lines = []
        label_dict = {}
        for row in f:
            line = row.strip().split(' ')
            label_dict[float(line[0])] = line[1]
    return label_dict