/*
  libuta - a C++ widget library based on SDL (Simple Direct Layer)
  Copyright (C) 1999-2002  Karsten Laux

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library 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
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA  02111-1307, SA.
*/
// written by Karsten Laux, June 1999  

#ifndef _DIRECTSURFACE_H_
#define _DIRECTSURFACE_H_

#include "surface.h"
#include "application.h"
#include "mutex.h"
#include "mouse.h"

namespace uta {

///
class DirectSurface : public Surface
{
 public:
  ///
  DirectSurface(int x, int y, int w, int h):
    Surface(),
    screen_rect(x,y,w,h)
    {
      //make a copy of the original struct
      sdlSurface_ = new SDL_Surface;
      *sdlSurface_ = *(uapp->rootWindow()->screen()->sdlSurface_);

      //then set new metrics
      sdlSurface_->w = w;
      sdlSurface_->h = h;
      sdlSurface_->offset = y * sdlSurface_->pitch + x * sdlSurface_->format->BytesPerPixel;


#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \
    SDL_VERSIONNUM(1, 1, 5)
      sdlSurface_->clip_rect.x = 0;
      sdlSurface_->clip_rect.y = 0;
      sdlSurface_->clip_rect.w = w;
      sdlSurface_->clip_rect.h = h;
#endif
   
      screen_access = uapp->rootWindow()->access_.mutex;

      
      format = Pixelformat::identify(sdlSurface_->format->BytesPerPixel,
				     sdlSurface_->format->Rmask,
				     sdlSurface_->format->Gmask,
				     sdlSurface_->format->Bmask,
				     sdlSurface_->format->Amask);	  
      gatherPalette();
      
      setAlpha(0);
      setTransColor(Color(0,0,0));
      setTransparency(false);

      uapp->rootWindow()->registerDirect(this);

    }
 
  
  ///
  virtual ~DirectSurface() 
      {
	  uapp->rootWindow()->unregisterDirect(this);
      //this prevents Surface from deleting it
      sdlSurface_ = 0;
    };

  ///
  const Rect& rect() { return screen_rect; };

  ///
  void refresh()
    {
      uapp->rootWindow()->refreshRect(screen_rect);
    }
  ///
  void update()
      {
	  uapp->rootWindow()->refreshRect(screen_rect);
      }
  /// update a part of this surface to the screen
  void updateRect(const Rect& rect)
      {	  
	  Rect _rect = Rect(rect.upperLeft()+screen_rect.upperLeft(),
			    rect.lowerRight()+screen_rect.upperLeft());

	  uapp->rootWindow()->refreshRect(_rect);
      }
  
  /// update a part of this surface to the screen
  void updateRect(int x, int y, int w, int h)
      {	  
	  Rect _rect = Rect(screen_rect.upperLeft().x+x,screen_rect.upperLeft().y+y,w,h); 
	  uapp->rootWindow()->refreshRect(_rect);
      }
  ///
  void beginModify()
    {
      if(!Application::hardwareCursor())	
	  uapp->mouse()->remove();	
    }

  ///
  void endModify()
    {  
      if(!Application::hardwareCursor())
	  uapp->mouse()->paint();	
    }

  ///
  virtual void covered(const Rect&) {};
  ///
  virtual void exposed(const Rect&) {};

 protected:
  ///
  Rect screen_rect;
  ///
  SDL_mutex* screen_access;
  
};

}

#endif



