/*
 * Copyright information removed for SIGGRAPH anonymous review process.
 * This file is licensed under the GNU General Public License.
 *
 * image.h: image, memory management, RGB output.
 */


#ifndef __IMAGE__
#define __IMAGE__

#include "types.h"

namespace OGF {
    class Image {
    public:
        Image() {
            base_mem_ = nil ; width_ = 0 ; height_ = 0 ; bytes_per_pixel_ = 0 ; 
        }
        Image(unsigned int w, unsigned int h, unsigned int bpp) {
            base_mem_ = nil ; width_ = 0 ; height_ = 0 ; bytes_per_pixel_ = 0 ; 
            allocate(w,h,bpp) ;
        }
        Image(const Image& rhs) { copy(rhs) ;  }
        ~Image() { destroy() ; }
        Image& operator=(const Image& rhs) { 
            if(&rhs != this) {
                destroy() ; copy(rhs) ;  
            }
        }
        unsigned int width() const { return width_ ; }
        unsigned int height() const { return height_ ; }
        unsigned int bytes_per_pixel() const { return bytes_per_pixel_ ; }
        unsigned int bytes() const { return width_ * height_ * bytes_per_pixel_ ; }
        Memory::pointer base_mem() const { return base_mem_ ; }
        Memory::pointer pixel_base(unsigned int x, unsigned int y) const { 
            return base_mem_ + (y * width_ + x) * bytes_per_pixel_ ;
        }
        void destroy() { 
            delete[] base_mem_ ; base_mem_ = nil ; 
            width_ = 0 ; height_ = 0 ; bytes_per_pixel_ = 0 ;
        }
        void allocate(unsigned int w, unsigned int h, unsigned int bpp) {
            destroy() ;
            base_mem_ = new Memory::byte[w*h*bpp] ;
            width_ = w ; height_ = h ; bytes_per_pixel_ = bpp ;
            clear() ;
        }
        void clear() {
            Memory::clear(base_mem_, bytes()) ;
        }
        void save_as_rgb(const std::string& file_name) ;
    protected:
        void copy(const Image& rhs) { 
            if(rhs.bytes() == 0) {
                base_mem_ = nil ;
            } else {
                base_mem_ = new Memory::byte[rhs.bytes()] ;
                Memory::copy(base_mem_, rhs.base_mem(), rhs.bytes()) ;
            }
            width_ = rhs.width() ; height_ = rhs.height() ; bytes_per_pixel_ = rhs.bytes_per_pixel() ;
        }

    private:
        Memory::pointer base_mem_ ;
        unsigned int width_ ;
        unsigned int height_ ;
        unsigned int bytes_per_pixel_ ;
    } ;
}

#endif

