#############################################################################*/


from __future__ import absolute_import
from __future__ import print_function
from __future__ import division


import string
import traceback
import sys
import numpy
import math
import time

from os.path import basename
import os.path
import os


FILA=[0]

import mpi4py.MPI as MPI


from . import setCpuSet

import glymur

import threading

from . import EdfFile

from . import  Parameters_module 
P=Parameters_module.Parameters

GLobalLock = threading.Lock()
WriteLock = threading.Lock()


myrank = MPI.COMM_WORLD.Get_rank()
nprocs = MPI.COMM_WORLD.Get_size()
mypname = MPI.Get_processor_name()
comm = MPI.COMM_WORLD
    

npjs = P.numpjs
ppproc = int( ( npjs*1.0/nprocs)+0.999999)
my_nprocs = min( ppproc,  npjs-myrank*ppproc       )
seqnum_list = range(myrank*ppproc , myrank*ppproc+my_nprocs)
partial_proj_num_list = numpy.array(seqnum_list )* P.FILE_INTERVAL+ P.NUM_FIRST_IMAGE


class ProcessingObject:
    def __init__( self , source, target ) :
        self.source = source
        self.target = target
    def process(self):
        # print( " PROCESS ", EdfFile)

        a=glymur.Jp2k( self.source )
        # print( " conversione OK ", self.target)
        data=a[:]
        data=data.T
        print( self.target )
        
        f = EdfFile.EdfFile(self.target,"wb")
        f.WriteImage({},data)
        f=None
        # print( " waiting " )
        with WriteLock:
            FILA[0] -=1


    # def processa( i) :
    #     a=glymur.Jp2k( edf_sources[i] )
    #     # print( " conversione OK ", self.target)
    #     data=a[:]
    #     data=data.T
    #     print( edf_targets[i])
    #     f = EdfFile.EdfFile(edf_targets[i],"wb")
    #     f.WriteImage({},data)
    #     f=None


class threadLauncher(threading.Thread):
    def __init__(self, processingObject=None ):
        threading.Thread.__init__(self)
        self.processingObject=processingObject        

    def run(self):
        self.processingObject.process()

def jp2edf(ncpus) :

    myrank = MPI.COMM_WORLD.Get_rank()
    nprocs = MPI.COMM_WORLD.Get_size()
    mypname = MPI.Get_processor_name()
    comm = MPI.COMM_WORLD
    

    edfargs = {"FILE_PREFIX":P.FILE_PREFIX, "LENGTH_OF_NUMERICAL_PART":P.LENGTH_OF_NUMERICAL_PART, 
               "NUMBER_LENGTH_VARIES":P.NUMBER_LENGTH_VARIES,"FILE_POSTFIX": ".edf" }
    edf_targets  = [ Parameters_module.get_name_edf_proj(i,**edfargs)  for i in partial_proj_num_list] 
    
    edfargs["FILE_POSTFIX"]= ".jp2" 
    edfargs["FILE_PREFIX"]= P.ORIGINAL_FILE_PREFIX
    edf_sources  = [ Parameters_module.get_name_edf_proj(i,**edfargs)  for i in partial_proj_num_list] 
    
    


    nsources = len(edf_sources)

    FILA[0]=0
    i=0
    while(1):
        with WriteLock:
            if FILA[0]<ncpus:
                ido = i 
                FILA[0]+=1

                pobject = ProcessingObject( edf_sources[ido],  edf_targets[ido]  )
                t = threadLauncher( pobject )
                # print( " START ", EdfFile)
                t.start()
                i+=1
                #        time.sleep(0.01)            
        if i==nsources:
            break



def removejp2() :

    myrank = MPI.COMM_WORLD.Get_rank()
    nprocs = MPI.COMM_WORLD.Get_size()
    mypname = MPI.Get_processor_name()
    comm = MPI.COMM_WORLD
    
 
    edfargs = {"FILE_PREFIX":P.FILE_PREFIX, "LENGTH_OF_NUMERICAL_PART":P.LENGTH_OF_NUMERICAL_PART, 
               "NUMBER_LENGTH_VARIES":P.NUMBER_LENGTH_VARIES,"FILE_POSTFIX": ".edf" }
    edf_targets  = [ Parameters_module.get_name_edf_proj(i,**edfargs)  for i in partial_proj_num_list] 
    
    for t in edf_targets:
        os.remove(t)

        

if sys.argv[2] =="jp2edf":
    ncpus = int(sys.argv[3])
    jp2edf(ncpus)
else:
    removejp2()
