/************************************************************************
 *
 * This file is part of SuperCollider Qt GUI.
 *
 * Copyright 2013 Jakob Leben (jakob.leben@gmail.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ************************************************************************/

// these functions are useful for the creation of QImage SC objects

#pragma once

#include <QImage>
#include "../image.h"
#include "../type_codec.hpp"

namespace QC = QtCollider;

namespace QtCollider {
    
    inline QC::Image * to_image( struct PyrObject * obj )
    {
        SharedImage *shared_image_ptr =
        reinterpret_cast<SharedImage*>( slotRawPtr(obj->slots) );
        return shared_image_ptr->data();
    }
    
    inline QC::Image * to_image( PyrSlot * slot )
    {
        SharedImage *shared_image_ptr =
        reinterpret_cast<SharedImage*>( slotRawPtr( slotRawObject(slot)->slots ) );
        return shared_image_ptr->data();
    }
    
    inline QRgb color_to_pixel( const QColor & color )
    {
        int r, g, b, a;
        color.getRgb( &r, &g, &b, &a );
        qreal k = a / 255.f;
        r *= k;
        g *= k;
        b *= k;
        QRgb pixel = (a << 24) | (r << 16) | (g << 8) | b;
        return pixel;
    }
    
    inline QColor pixel_to_color( QRgb pixel )
    {
        int r, g, b, a;
        int mask = 0xFF;
        a = pixel >> 24 & mask;
        r = pixel >> 16 & mask;
        g = pixel >> 8 & mask;
        b = pixel & mask;
        if ( a > 0 ) {
            qreal k = a > 0 ? 255.f / a : 0.f;
            r *= k;
            g *= k;
            b *= k;
            return QColor(r,g,b,a);
        }
        else
            return QColor(0,0,0,0);
    }
    
    inline int finalize_image_object( struct VMGlobals *g, struct PyrObject *obj )
    {
        SharedImage *shared_image_ptr =
        reinterpret_cast<SharedImage*>( slotRawPtr(obj->slots) );
        delete shared_image_ptr;
        SetNil( obj->slots+0 );
        return errNone;
    }
    
    inline void initialize_image_object( struct VMGlobals *g, struct PyrObject *obj, Image *image )
    {
        assert( IsNil( obj->slots ) && IsNil( obj->slots+1 ) );
        SharedImage *shared_image_ptr = new SharedImage(image);
        SetPtr( obj->slots, shared_image_ptr ); // dataptr
        InstallFinalizer( g, obj, 1, finalize_image_object ); // finalizer
    }
    
} // namespace QtCollider
