import numpy
import os
from fepydas.datatypes.Dataset import Spectrum, PLE, SpectrumSeries, SparseSpectrumMap
from fepydas.constructors.datareaders.Generic import ASCII
from fepydas.datatypes.Data import Data1D, Data2D, Data3D, DataType
import fepydas.datatypes as datatypes

def Automatic(filename):
  file = open(filename, encoding="Latin-1")
  done = False
  headers = {}
  while not done:
    line = file.readline().strip().split(" = ")
    #print(line)
    if line[0]=="HEADER":
      done = True
    else:
      headers[line[0]] = line[1:]
  #Header Done
  if headers["Measurement Type"][0] == "Mapscan Cube":
    #For Mapscans, the Header is followed by a section showing the mapping using X and O.
    map_x = int(headers["Map Dimension X"][0])
    map_y = int(headers["Map Dimension Y"][0])
    map_x0 = float(headers["Map Edge Position X (µm)"][0])
    map_y0 = float(headers["Map Edge Position Y (µm)"][0])
    map_pitch = float(headers["Map Pitch (µm)"][0])
    file.readline() #---
    mapping = numpy.ndarray(shape=(map_x,map_y,2), dtype=numpy.float)
    bool_mask = numpy.ndarray(shape=(map_x,map_y), dtype=bool)
    mask = numpy.ndarray(shape=(map_x,map_y), dtype=numpy.float)
    num = 0
    for i in range(map_y):
      line = file.readline()
      for j in range(map_x):
        mapping[j,map_y-1-i]=[map_x0+j*map_pitch, map_y0+(map_y-1-i)*map_pitch]
        if (line[j]=="X"):
          bool_mask[j,map_y-1-i] = True
          num+=1
        else:
          bool_mask[j,map_y-1-i] = False
    file.readline() #---
    
    names = file.readline().strip().split("\t")
    units = file.readline().strip().split("\t")
    
    endOfAxis = False
    axisData = []
    while not endOfAxis:
      value = file.readline().strip()
      if value == "---":
        break
      axisData.append(float(value.split("\t")[0]))
    axis = Data1D(numpy.array(axisData),DataType(names[0],units[0]))
    
    data = numpy.ndarray(shape=(num, len(axis.values)))
    raw = numpy.fromfile(file, dtype = numpy.dtype(">u8"))[1:] #64bit uint big-endian
    #It seems that this array is transposed?
    data = raw.reshape((len(axis.values), num)).T
    n = 0
    for i in range(map_x):
      for j in range(map_y):
        if bool_mask[i,j]:
          mask[i,j] = n
          #data[n,:] = raw[n*len(axis.values):(n+1)*len(axis.values)]
          n+=1
        else:
          mask[i,j] = numpy.nan
    return SparseSpectrumMap(axis, Data2D(data, datatypes.COUNTS), Data3D(mapping, datatypes.POS_um), Data2D(mask, datatypes.NUMBER), None)
  else:
    names = file.readline().strip().split("\t")
    units = file.readline().strip().split("\t")
    length = len(headers)+3
    file.close()
    data = ASCII(filename, skip_header=length).T
    axis = Data1D(data[0,:],DataType(names[0],units[0]))
    if headers["Measurement Type"][0] == "Series":
      #2D
      values = Data2D(data[2:,:],datatypes.COUNTS)
      if headers["Measurement Type"][1] == "PLE Xe Arc Lamp":
        dtype = DataType("Excitation Wavelength","nm")
        if int(headers["Dark Frames"][0])>0:
          #Has been corrected and is offset by 1000
          values.values-=1000
      else:
        dtype = DataType(headers["Measurement Type"][1],units[2])
      keys = Data1D(numpy.array(names[2:2+values.values.shape[0]]).astype(numpy.float),dtype)
      if headers["Measurement Type"][1] == "PLE Xe Arc Lamp":
        return PLE(axis,keys,values,None,None)
      else:
        return SpectrumSeries(axis,keys,values)
    elif headers["Measurement Type"][0] == "PLE Response":
      values = Data1D(data[1,:],DataType(names[1],units[1]))
      return Spectrum(axis, values)
    elif headers["Measurement Type"][0] == "Histogram":
      values = Data1D(data[1,:],datatypes.COUNTS)
      return Spectrum(axis,values)
    else:
      #1D
      values = Data1D(data[2,:],datatypes.COUNTS)
      return Spectrum(axis, values)
