/*
 * pawsmouse.cpp - Author: Andrew Craig
 *
 * Copyright (C) 2003 Atomic Blue (info@planeshift.it, http://www.atomicblue.org)
 *
 *
 * 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 (version 2 of the License)
 * 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.
 *
 */
// pawsmouse.cpp: implementation of the pawsMouse class.
//
//////////////////////////////////////////////////////////////////////
#include <psconfig.h>

#include <csutil/ref.h>
#include <ivideo/graph3d.h>
#include <ivideo/graph2d.h>
#include <igraphic/imageio.h>
#include <iutil/vfs.h>
#include <csutil/databuf.h>

#include "pawsmouse.h"
#include "pawsmanager.h"
#include "pawstexturemanager.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

pawsMouse::pawsMouse()
{
    graphics3D = PawsManager::GetSingleton().GetGraphics3D();
    vfs = CS_QUERY_REGISTRY( PawsManager::GetSingleton().GetObjectRegistry(), iVFS );
    imageLoader = CS_QUERY_REGISTRY( PawsManager::GetSingleton().GetObjectRegistry(), iImageIO );

    currentPosition = psPoint( 0,0 );
    deltas = psPoint( 0, 0 );
    hidden = false;
    crosshair = false;
    cursorImage = new pawsImage( PawsManager::GetSingleton().GetObjectRegistry() );
    crosshairImage = new pawsImage( PawsManager::GetSingleton().GetObjectRegistry() );
    psImageDescription* imageDesc = PawsManager::GetSingleton().GetTextureManager()->GetImageDescription( "Crosshair Mouse Pointer" );   
    if (imageDesc)
        crosshairImage->Description( imageDesc );
    useOS = false;
}

pawsMouse::~pawsMouse()
{
    delete cursorImage;
}

void pawsMouse::SetPosition( int x, int y )
{
    deltas.x = x - currentPosition.x;
    deltas.y = y - currentPosition.y;

    currentPosition.x = x;
    currentPosition.y = y;
}

void pawsMouse::ChangeImage( const char* imageName )
{
    psImageDescription* imageDesc = PawsManager::GetSingleton().GetTextureManager()->GetImageDescription( imageName );   

    if (!imageDesc) return;
    
    CS_ASSERT( imageDesc );

    cursorImage->Description( imageDesc );
    SetOSMouse(imageDesc);
       
}

void pawsMouse::ChangeImage( psImageDescription* desc )
{
    cursorImage->Description( desc );
    SetOSMouse(desc);
}

void pawsMouse::SetOSMouse(psImageDescription* desc)
{
#ifdef CS_PLATFORM_WIN32

    if ( desc->image == 0 )
    {
      csRef<iDataBuffer> buf( vfs->ReadFile( desc->imageFileLocation, false ) );
      
      if ( buf == NULL || buf->GetSize() == 0 )
      {
      Error2( "Could not open image: >%s<", (const char*)desc->imageFileLocation );
      return;
      }
      
      desc->image = imageLoader->Load( buf, CS_IMGFMT_ANY | CS_IMGFMT_ALPHA );

      if ( desc->image == 0)
      {
      Error2( "Could not load image: >%s<", (const char*)desc->imageFileLocation );
      return;
      }

      desc->image->SetName( desc->imageFileLocation );
    }
    iGraphics2D *g2d = graphics3D->GetDriver2D();

    // Attempt to use image to enable OS level cursor
    csRGBcolor color(desc->defaultTransparentColourRed, desc->defaultTransparentColourGreen, desc->defaultTransparentColourBlue);
    if (g2d->SetMouseCursor (desc->image, &color))
    {
      if (!useOS)
          Debug1(LOG_PAWS,NULL,"Using OS Cursor\n");
      useOS = true;
      cursorDesc = desc;
      return;
    }
    else g2d->SetMouseCursor (csmcNone);
#endif
}

void pawsMouse::Draw()
{
    if (!useOS && !hidden)
        cursorImage->Draw(currentPosition.x , currentPosition.y );
    if (crosshair)
        crosshairImage->Draw( graphics3D->GetDriver2D()->GetWidth() / 2, graphics3D->GetDriver2D()->GetHeight() / 2 );
}

void pawsMouse::Hide(bool h)
{
    hidden = h;
#ifdef CS_PLATFORM_WIN32
    if (h)
        graphics3D->GetDriver2D()->SetMouseCursor (csmcNone);
    else
        if (cursorDesc && useOS)
        {
            csRGBcolor color(cursorDesc->defaultTransparentColourRed, cursorDesc->defaultTransparentColourGreen, cursorDesc->defaultTransparentColourBlue);
            graphics3D->GetDriver2D()->SetMouseCursor (cursorDesc->image, &color);
        }
#endif
}
