import numpy as np
import logging
import mrcfile

from .file_handler import get_mrc_file
"""
This class can be used to extract data from the text file
generated by Cockpit, including the linked image. The image
and values are then held as attributes.
"""


class UnstitchedImage():

    def __init__(self, filepath):
        '''
        Returns ImageExtractor class with attributes:
            images               image stack as numpy array
            
            exposures            exposure time of each frame in seconds
            exposure_minmax      min and max of each frame
            
            img_size             frame size (x, y) in stage coordinates
            img_pixels           number of pixels in each frame
            
            pixel_size           size of each pixel in stage coordinates
            pix2edge             number of pixels from the centre of a frame to the edge
            
            mosaic_centre        the centre of the mosaic, according to where the first image was taken (stage coordinates)
            stage_positionlist   list of coordinates (in stage coordinate) relative to centre
            pix_positionlist     list of coordinates (in pixels), relative to centre
            boundaries           mosaic boundaries in pixels, relative to centre
            
            img_count            number of images taken
            modified_timestamp   timestamp when the txt file was last modified
            
            
        '''
        mrc_path, location_array = get_mrc_file(filepath, True)
        self.modified_timestamp = filepath.stat().st_mtime

        # Open mrc file:
        logging.info("Opening mrc file at %s", str(mrc_path))
        # x pixel order is backwards for each image:
        with mrcfile.open(mrc_path, permissive=True) as mrc:
            self.images = np.asarray(mrc.data, dtype='i')[:, ::-1, :]

        self.exposures = location_array[:, 2]
        self.exposure_minmax = location_array[:, 7:9]

        self.img_size = location_array[0, 3:5]
        self.img_pixels = location_array[0, 5:7].astype(int)
        self.pixel_size = self.img_size[0] / self.img_pixels[0]  # Assuming square pixels
        self.pix2edge = [(self.img_pixels[0]) // 2, (self.img_pixels[1]) // 2]

        self.mosaic_centre = location_array[0, :2]
        self.stage_positionlist = location_array[:, :2] - self.mosaic_centre
        self.img_count = self.stage_positionlist.shape[0]
        self.pix_positionlist = (self.stage_positionlist / self.pixel_size).astype(int)

        self.boundaries = self.__calculate_boundaries()

    def __calculate_boundaries(self):
        min_coords = (self.pix_positionlist[:, 0].min(), self.pix_positionlist[:, 1].min())
        max_coords = (self.pix_positionlist[:, 0].max(), self.pix_positionlist[:, 1].max())

        return np.array([[min_coords[0] - self.pix2edge[0],
                          min_coords[1] - self.pix2edge[1]],
                         [max_coords[0] + self.pix2edge[0],
                          max_coords[1] + self.pix2edge[1]]], dtype=int)
