/*==LICENSE==*

CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011  Cyan Worlds, Inc.

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 3 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/>.

You can contact Cyan Worlds, Inc. by email legal@cyan.com
 or by snail mail at:
      Cyan Worlds, Inc.
      14617 N Newport Hwy
      Mead, WA   99021

*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  plBitmap Class Functions                                                 //
//  Base bitmap class for all the types of bitmaps (mipmaps, cubic envmaps,  //
//  etc.                                                                     //
//  Cyan, Inc.                                                               //
//                                                                           //
//// Version History //////////////////////////////////////////////////////////
//                                                                           //
//  6.7.2001 mcn - Created.                                                  //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include "hsTypes.h"
#include "plBitmap.h"

#include "hsResMgr.h"
#include "hsStream.h"
#include "pnKeyedObject/plKey.h"
#include "plPipeline/hsGDeviceRef.h"


//// Static Members ///////////////////////////////////////////////////////////

UInt8   plBitmap::fGlobalNumLevelsToChop = 0;


//// Constructor & Destructor /////////////////////////////////////////////////

plBitmap::plBitmap()
{
    fPixelSize = 0;
    fSpace = kNoSpace;
    fFlags = 0;
    fCompressionType = kUncompressed;
    fUncompressedInfo.fType = UncompressedInfo::kRGB8888;
    fDeviceRef = nil;
    fLowModifiedTime = fHighModifiedTime = 0;
}

plBitmap::~plBitmap()
{
    if( fDeviceRef != nil )
        hsRefCnt_SafeUnRef( fDeviceRef );
}

bool plBitmap::IsSameModifiedTime(UInt32 lowTime, UInt32 highTime)
{
    return (fLowModifiedTime == lowTime && fHighModifiedTime == highTime);
}

void plBitmap::SetModifiedTime(UInt32 lowTime, UInt32 highTime)
{
    fLowModifiedTime = lowTime;
    fHighModifiedTime = highTime;
}

//// Read /////////////////////////////////////////////////////////////////////

static UInt8    sBitmapVersion = 2;

UInt32  plBitmap::Read( hsStream *s )
{
    UInt8   version = s->ReadByte();
    UInt32  read = 6;


    hsAssert( version == sBitmapVersion, "Invalid bitamp version on Read()" );

    fPixelSize = s->ReadByte();
    fSpace = s->ReadByte();
    fFlags = s->ReadSwap16();
    fCompressionType = s->ReadByte();

    if(( fCompressionType == kUncompressed )||( fCompressionType == kJPEGCompression ))
    {
        fUncompressedInfo.fType = s->ReadByte();
        read++;
    }
    else
    {
        fDirectXInfo.fBlockSize = s->ReadByte();
        fDirectXInfo.fCompressionType = s->ReadByte();
        read += 2;
    }

    fLowModifiedTime = s->ReadSwap32();
    fHighModifiedTime = s->ReadSwap32();

    return read;
}

//// Write ////////////////////////////////////////////////////////////////////

UInt32  plBitmap::Write( hsStream *s )
{
    UInt32  written = 6;


    s->WriteByte( sBitmapVersion );

    s->WriteByte( fPixelSize );
    s->WriteByte( fSpace );
    s->WriteSwap16( fFlags );
    s->WriteByte( fCompressionType );

    if(( fCompressionType == kUncompressed )||(fCompressionType == kJPEGCompression ))
    {
        s->WriteByte( fUncompressedInfo.fType );
        written++;
    }
    else
    {
        s->WriteByte( fDirectXInfo.fBlockSize );
        s->WriteByte( fDirectXInfo.fCompressionType );
        written += 2;
    }

    s->WriteSwap32(fLowModifiedTime);
    s->WriteSwap32(fHighModifiedTime);

    return written;
}

//// SetDeviceRef /////////////////////////////////////////////////////////////

void    plBitmap::SetDeviceRef( hsGDeviceRef *const devRef )
{
    if( fDeviceRef == devRef )
        return;

    hsRefCnt_SafeAssign( fDeviceRef, devRef );
}

void plBitmap::MakeDirty()
{
    if( fDeviceRef )
        fDeviceRef->SetDirty(true);
}