#ifndef n_imagefileImageSource_H
#define n_imagefileImageSource_H

/*
 *
 * nucleo/image/source/imagefileImageSource.H --
 *
 * Copyright (C) Nicolas Roussel
 *
 * See the file LICENSE for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#include <nucleo/utils/FileUtils.H>
#include <nucleo/image/source/ImageSource.H>
#include <nucleo/core/URL.H>
#include <nucleo/image/encoding/Conversion.H>

#include <stdexcept>

namespace nucleo {

  class imagefileImageSource : public ImageSource {

  private:

    Image _image ;
    bool _image_ok, _image_used ;

  public:

    imagefileImageSource(Image::Encoding target_encoding,
					const URL &url, Image::Encoding source_encoding) {
	 std::string query = url.getQuery() ;
	 unsigned int quality = 100 ;
	 URL::getQueryArg(query, "quality", &quality) ;

	 std::string filename = url.isOpaque() ? url.getOpaque() : url.getPath() ;
	 unsigned int size = getFileSize(filename.c_str()) ;
	 unsigned char *data = Image::AllocMem(size) ;
	 readFromFile(filename.c_str(), data, size) ;

	 _image.setEncoding(source_encoding) ;
	 _image.setData(data, size, Image::FREEMEM) ;
	 if (target_encoding==Image::PREFERRED) target_encoding = source_encoding ;
	 _image_ok = convertImage(&_image, target_encoding, quality) ;
    }

    bool start(void) {
	 if (!_image_ok) return false ;
	 _image_used = false ;
	 notifyObservers() ;
	 _chrono.start() ;
	 return true ;
    }

    bool isActive(void) {
	 return (_image_ok && !_image_used) ;
    }

    bool getNextImage(Image *img) {
	 if (_image_used || !_image_ok) return false ;
	 img->copyDataFrom(_image) ;
	 _chrono.tick() ;
	 _image_used = true ;
	 return true ;
    }

    bool stop(void) {
	 if (!isActive()) return false ;
	 _image_used = false ;
	 _chrono.stop() ;
	 return true ;
    }

  } ;

  // ------------------------------------------------------------------

}

#endif
