# -*- coding: utf-8 -*-
"""
    File name:      generate_code_act.py
    Author:         Tetsuro Tatsuoka
    Date created:   04/12/2018
    Last modified:  04/12/2018
    Version:        1.0.0
    Python version: 3.6.3
    Description:    Generate C source code of activity data and weights data

    Revision history:
        1.0.0   04/12/2018  - Initial coding.
"""
import os
import numpy as np
import pandas as pd
from load_data_act import load_data
from read_weights import read_weights

Q_FMT = 12
FOLDER_NAME = 'UCI_HAR'

def export_c_source_dat_act(file_name, dat, dtype='double'):
    """
        Export C source code of input activity sensor data
    
        Parameters:
            file_name   save file name
            dat         input data
            dtype       data type
    """
    with open(file_name, 'w')  as f:
        dat = np.array(dat)
        if dtype == 'int32':
            f.write('// Q' + str(Q_FMT) + ' format\n\n')
            dat = np.int32(np.round(dat*(2**Q_FMT)))
        else:
            dtype = 'double'            

        f.write('// ' + str(dat.shape[0]) + ' x ' + str(dat.shape[1]) + ' data\n')
        len_str = str(dat.shape[0] * dat.shape[1])
        f.write('const ' + dtype + ' ADL_DAT[' + len_str + '] = {\n')
        for i in range(dat.shape[0]):
            f.write(', '.join(map(str, dat[i,:])))
            if i == (dat.shape[0]-1):
                f.write('\n')
            else:
                f.write(',\n')                        
        f.write('};\n')
        f.write('\n')
            
def export_c_source_weights(file_name, weights, dtype='double'):
    """
        Export C source code of weight data
    
        Parameters:
            file_name   save file name
            weights     weight data
            dtype       data type
    """
    with open(file_name, 'w')  as f:
        n_b = 1
        n_w = 1
        if dtype == 'int32':
            f.write('// Q' + str(Q_FMT) + ' format\n\n')
        else:
            dtype = 'double'            

        for w in weights:
            if dtype == 'int32':
                w = np.int32(np.round(w*(2**Q_FMT)))
                
            if len(w.shape) == 1:
                len_str = str(w.shape[0])
                f.write('// ' + len_str + ' weights\n')
                f.write('const ' + dtype + ' B' + str(n_b) + '[' + len_str + '] = {\n')
                f.write(', '.join(map(str, w)))
                f.write('\n};\n')
                n_b = n_b + 1
            else:
                w = w.T
                len_str = str(w.shape[0] * w.shape[1])
                f.write('// ' + str(w.shape[0]) + ' x ' + str(w.shape[1]) + ' weights\n')
                f.write('const ' + dtype + ' W' + str(n_w) + '[' + len_str + '] = {\n')
                for i in range(w.shape[0]):
                    f.write(', '.join(map(str, w[i,:])))
                    if i == (w.shape[0]-1):
                        f.write('\n')
                    else:
                        f.write(',\n')                        
                f.write('};\n')
                n_w = n_w + 1
            f.write('\n')

if __name__ == "__main__" :
    if not os.path.exists(FOLDER_NAME):
        os.mkdir(FOLDER_NAME)

    """ Activity test data """
    X_train, X_test, Y_train, Y_test = load_data()

    # Pickup 6 activities x 8 data set    
    dat = pd.DataFrame(np.vstack([X_test[250,:,:],
                                  X_test[290,:,:],
                                  X_test[270,:,:],
                                  X_test[190,:,:],
                                  X_test[160,:,:],
                                  X_test[220,:,:],

                                  X_test[1010,:,:],
                                  X_test[1040,:,:],
                                  X_test[1020,:,:],
                                  X_test[940,:,:],
                                  X_test[910,:,:],
                                  X_test[980,:,:],

                                  X_test[1300,:,:],
                                  X_test[1340,:,:],
                                  X_test[1320,:,:],
                                  X_test[1240,:,:],
                                  X_test[1210,:,:],
                                  X_test[1270,:,:],

                                  X_test[1460,:,:],
                                  X_test[1510,:,:],
                                  X_test[1490,:,:],
                                  X_test[1400,:,:],
                                  X_test[1370,:,:],
                                  X_test[1430,:,:],

                                  X_test[1620,:,:],
                                  X_test[1680,:,:],
                                  X_test[1650,:,:],
                                  X_test[1560,:,:],
                                  X_test[1540,:,:],
                                  X_test[1580,:,:],

                                  X_test[1790,:,:],
                                  X_test[1840,:,:],
                                  X_test[1810,:,:],
                                  X_test[1740,:,:],
                                  X_test[1700,:,:],
                                  X_test[1760,:,:],

                                  X_test[1960,:,:],
                                  X_test[1990,:,:],
                                  X_test[1980,:,:],
                                  X_test[1900,:,:],
                                  X_test[1870,:,:],
                                  X_test[1930,:,:],

                                  X_test[2140,:,:],
                                  X_test[2180,:,:],
                                  X_test[2160,:,:],
                                  X_test[2080,:,:],
                                  X_test[2050,:,:],
                                  X_test[2110,:,:]]))
    
    fname = os.path.join(FOLDER_NAME, 'X_test.csv')
    dat.to_csv(fname, header=None, index=None)
    export_c_source_dat_act('test_data_act.c', dat)
    export_c_source_dat_act('test_data_act_i.c', dat, dtype='int32')
    
    """ Activity Weights """    
    path, weight = read_weights(os.path.join('.', 'model_weights_lstm.h5'))
    export_c_source_weights('weights_act.c', weight)
    export_c_source_weights('weights_act_i.c', weight, dtype='int32')
