#ifndef LIGHT_MODEL_H
#define LIGHT_MODEL_H

//                Light models
// Д. Роджерс "Алгоритмические основы машинной графики" || с.384
// D.F. Rogers "Procedural Elements for Computer Graphics"
//
// N1
//                K * Il                               n
//  I = Ia * Ka + ------ * ( Kd * cos theta  + Ks * cos theta  )
//                D + K
// N3
//        K                                                n
//  I = ----- [ Ia * Ka + Il * ( Kd * cos theta  + Ks * cos theta  ) ]
//      D + K
//

#ifndef MATERIAL_H
#include "Material.h"
#endif

class Light_model
{
public:
    int                         K_;
    int                         Ia_, /*Il, */ Ib_;

    struct
    {
        int  R_, G_, B_;
    }
    diffused_source_, bg_;

    //    void                          I( BYTE *r, BYTE *g, BYTE *b,
    //                                      Material * sp,  int cos_theta, int D=0 );
    void                        I( int * r, int * g, int * b,
                                    Material * sp,  int cos_theta, int D = 0 );

    void                        simple_I( int * r, int * g, int * b,
                                    Material * sp, int cos_theta );

    void                        background( int * r, int * g, int * b );

    Light_model();
};

extern  int pow_tab[ 256 ] [ 50 ];

inline  void  Light_model::
I( int * r, int * g, int * b, Material * m, int cos_theta, int D )
{
    //return;

    int mirror, Il_cos_theta, k, IaKa;

    if( D < 0 )
    {
        D = 0;
        cos_theta = 255;
    }
    mirror         = ( m->Ks_ * pow_tab[ cos_theta ] [ m->n_ ] ) >> 8;
    Il_cos_theta  = ( ( 255 - Ia_ ) * m->Kd_ * cos_theta ) >> 8;
    //                          K
    //  Il = 1 - Ia       k = -------
    //                        D + K
    //                                                    n
    //  I = k*( Ia* Ka + Il * ( Kd * cos theta  + Ks * cos theta  ))
    //
    k = ( 255 * K_ ) / ( D + K_ );
    //k = 255;
    IaKa = ( Ia_ * m->Ka_ ) >> 8;
    * r = ( k * ( ( m->R_ * ( IaKa * diffused_source_.R_ + Il_cos_theta ) >>
       16 ) + mirror ) ) >> 8;
    * g = ( k * ( ( m->G_ * ( IaKa * diffused_source_.G_ + Il_cos_theta ) >>
       16 ) + mirror ) ) >> 8;
    * b = ( k * ( ( m->B_ * ( IaKa * diffused_source_.B_ + Il_cos_theta ) >>
       16 ) + mirror ) ) >> 8;
    * r = ( * r > 255 ) ? 255 : * r;
    * g = ( * g > 255 ) ? 255 : * g;
    * b = ( * b > 255 ) ? 255 : * b;
}

#endif //LIGHT_MODEL_H

