/*
    ChemCon - molecular mechanics and molecular graphics
    Copyright (C) 1998-2002  Alexei Nikitin

    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, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "Z_buffer.h"

#include <memory.h>

Z_buffer::Z_buffer()
: Value_( 0 ),  width_( 0 ), height_( 0 )
{
    mem_flag_ = false;
}

void  Z_buffer::
init( int w, int h, int bg_v )
{
    destroy();
    if( w <= 0 || h <= 0 )  return;

    width_  = w;
    height_ = h;

    //    Value_ = new int[w*h];

    Value_ = new int * [ w ];
    if( Value_ == 0 )  goto metka;

    int i;
    for( i = width_;  --i >= 0;  )
    {
        Value_[ i ] = new int[ h ];
        if( Value_[ i ] == 0 )  goto metka;
    }
    mem_flag_ = true;

    clear( bg_v );
    return;

    metka:
    //AfxMessageBox(  "void  Z_buffer::void  Z_buffer::\n"
    //                "Error:\n"
    //                "Can not allocat memory for Z buffer." );
    throw;
}

void  Z_buffer::
destroy()
{
    if( Value_ == 0 && mem_flag_ == true )
        throw "Memory leak.";

    if( Value_ != 0 )
        for( int i = width_;  --i >= 0; )
            delete [] Value_[ i ];

    delete [] Value_;
    Value_  = 0;
    width_  = 0;
    height_ = 0;

    mem_flag_ = false;
}

void  Z_buffer::
clear( int v )
{
    //    for( int i=width_;  --i>=0;  )
    //      for( int j=height_;  --j>=0;  )
    //        Value_[i][j] = v;

    for( int j = height_; --j >= 0;  )    Value_[ 0 ] [ j ] = v;
    for( int i = width_;  --i >= 1;  )
    memcpy( Value_[ i ], Value_[ 0 ], height_ * 4 );
    //    for( int i=width_;   --i>=0;  )    Value_[i] = v;
    //    for( int j=height_;  --j>=1;  )    memcpy( Value_ + j * width_,
    // Value_, width_ * 4 );
}

void  Z_buffer::
clear( int left, int right, int top, int bottom, int v )
{
    if( v == 0 )
    {
        //for( int i=right;  --i>=left;  )  memset( Value_[i] + bottom, 0, (
        // top - bottom )*4 );
        for( int i = right;  --i >= left;  )
        memset( Value_[ i ] + top, 0, ( bottom - top ) * 4 );
    }
    else
    {
        //for( int j=top; --j>=bottom;  )    Value_[bottom][j] = v;
        for( int j = bottom; --j >= top;  )    Value_[ bottom ] [ j ] = v;
        throw;
        //for( int i=right;  --i>=1+left;  )    memcpy( Value_[i],
        // Value_[bottom], height_*4 );
    }

    //    for( int i=right;  --i>=left;     )    Value_[left + i] = v;
    //    for( int j=top;    --j>=1+bottom; )
    //      memcpy( Value_ + j * width_ + left, Value_ + left, width_ * 4 );
}

void  Z_buffer::
crude_clear( int left, int right, int top, int bottom, int resolution )
{
    int    incr = 1 << resolution;
    left   = ( left   >> resolution ) << resolution;
    right  = ( right  >> resolution ) << resolution;
    top    = ( top    >> resolution ) << resolution;
    bottom = ( bottom >> resolution ) << resolution;

    for( int x = left;  x < right;  x += incr )
        for( int y = bottom;  y < top;  y += incr )
            Value_[ x ] [ y ] = 0;
}

//Z_buffer    * G3D_output::ini_z_buf_ = NULL;
