//
// Copyright (C) 1999-2004 Toshikaz Hirabayashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// TOSHIKAZ HIRABAYASHI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Except as contained in this notice, the name of Toshikaz Hirabayashi shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization from
// Toshikaz Hirabayashi.

#include <WScom.h>
#include <WSCvdrawingArea.h>
#include <WSCclassInformation.h>
#include <WSCdevice.h>
#include <WSCblink.h>
#include <WSCcolorSet.h>
#include <WSCimageSet.h>
#include <WSDdev.h>
#include <WSDcolor.h>
#include <WSCfontSet.h>
#include <WSDappDev.h>

WSMFguiClassInitialize(WSCvdrawingArea, WSCnwbase);
WSMFversion(WSCvdrawingArea, WSCnwbase);

WSCvdrawingArea::WSCvdrawingArea(WSCbase* base, char* objname):
			WSCnwbase(base, objname){

  _begin_draw_fl = 0;
  _use_pixmap = False;

  WSMFpropertyCreateStart
    WSMFparentCheckVerSrc(WSCvdrawingArea);

    WSMFpropertyCreate(WSNusePixmap,    WSCbool,  _use_pixmap,WSSusePixmap);
    WSMFpropertySetSelection(WSRbool4, WSRbool4D);

    WSMFpropertyVisibleOff(WSNblinkColor);
    WSMFpropertyVisibleOff(WSNblinkRate);
    WSMFpropertyVisibleOff(WSNtwinBlink);
    WSMFpropertyVisibleOff(WSNblinkFlag);
    WSMFpropertyVisibleOff(WSNblinkRefreshing);

  WSMFpropertyCreateEnd

}
WSMFproperty(WSCvdrawingArea, WSNusePixmap,  WSCbool, _use_pixmap, False );

void WSCvdrawingArea::setWorkWSNusePixmap(WSCbool) {
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return;
  }

  if (_use_pixmap != False){
    char fl = True;
    dev->setValue(WSDEV_USE_PIXMAP,&fl);
  }else{
    char fl = False;
    dev->setValue(WSDEV_USE_PIXMAP,&fl);
  }
}
void WSCvdrawingArea::getWorkWSNusePixmap(WSCbool*){}

WSCvdrawingArea::~WSCvdrawingArea() {
}

void WSCvdrawingArea::update(){
  if (isNeedUpdate() == True){
    redraw();
    WSCbase::update();
  }
}
long WSCvdrawingArea::_device_initialize(){
  WSCnwbase::_device_initialize();

  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }

  if (_use_pixmap != False){
    char fl = True;
    dev->setValue(WSDEV_USE_PIXMAP,&fl);
  }
  
  return WS_NO_ERR;
}
long WSCvdrawingArea::execEventProc(long ev,void* data){
  if (ev == WSEV_EXPOSE){
    if (data != NULL){
      WSCrect* area = (WSCrect*)data;
      onExpose(area);
      draw();
      if (_expose_op == 1){
        if (beginDraw()== WS_NO_ERR){
          WSDdev* dev = getowndev();
          if (dev != NULL){
            dev->setForeColor(_fore_color);
          }
          execProcedure(ev);
          endDraw();
        }
      }
      return WS_NO_ERR;
    }
  }
  return WSCnwbase::execEventProc(ev,data);
}
long WSCvdrawingArea::beginDraw(){
  if (getVisible() == False){
    return WS_NO_ERR;
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  char fl = _use_pixmap;
  dev->setValue(WSDEV_USE_PIXMAP,&fl);

  short x = _x;
  short y = _y;
  WSCushort w = _w;
  WSCushort h = _h;

  WSCbool absolute = getAbsoluteDraw();
  if (absolute == False && dev->isExposed(x, y, w, h) == False){
    return WS_ERR;
  }
  long err = dev->beginDraw(x, y, w, h, absolute);
  if (err != WS_NO_ERR){
    return WS_ERR;
  }
  WSCbase::update();
  setAbsoluteDraw(False);
  _begin_draw_fl =1;
  return WS_NO_ERR;
}
long WSCvdrawingArea::endDraw(){
  if (getVisible() == False){
    return WS_NO_ERR;
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  if (_begin_draw_fl ==1){
    dev->endDraw();
    _begin_draw_fl =0;
  }
  return WS_NO_ERR;
}
long WSCvdrawingArea::draw(){
  if (getVisible() == False){
    return WS_NO_ERR;
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }

  short x = _x;
  short y = _y;
  WSCushort w = _w;
  WSCushort h = _h;
  WSCbool absolute = getAbsoluteDraw();
  if (absolute == False && dev->isExposed(x, y, w, h) == False){
    return WS_NO_ERR;
  }
  WSCbase::update();
  setAbsoluteDraw(False);

  if (getPropertyEditMode() != False){
    long err = dev->beginDraw(x, y, w, h, absolute);
    if (err != WS_NO_ERR){
       return WS_NO_ERR;
    }
    if (_use_pixmap != False){
      dev->setForeColor(_fore_color);
      dev->drawFillRect(0,0,w,h);
    }

    dev->setForeColor(WSGIappColorSet()->getColorNo("gray55"));
    dev->setLineWidth(1);
    dev->drawRect(0,0,w,h);
    WSCstring str;
    str.setString("DrawingArea");
    dev->drawString(0,0,w,h,&str,WS_DEFAULT_FONT_NO,WS_CENTER,-1,False);
    dev->endDraw();
  }else if (_use_pixmap != False){
    long err = dev->beginDraw(x, y, w, h, absolute);
    if (err != WS_NO_ERR){
       return WS_NO_ERR;
    }
    dev->setForeColor(_fore_color);
    dev->drawFillRect(0,0,w,h);
    dev->endDraw();
  }

  return WS_NO_ERR;
}
long WSCvdrawingArea::drawArc(short x,short y,WSCushort w,WSCushort h,short a1,short a2){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawArc(x,y,w,h,a1,a2);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawFillArc(short x,short y,WSCushort w,WSCushort h,short a1,short a2,char kind){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawFillArc(x,y,w,h,a1,a2,kind);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawLine(short x,short y,short x2,short y2){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawLine(x,y,x2,y2);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawLines(WSCpoint* pt,long num){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawLines(pt,num);
    return WS_NO_ERR;
  }
  return WS_ERR;
}

long WSCvdrawingArea::drawRect(short x,short y,WSCushort w,WSCushort h){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawRect(x,y,w,h);
    return WS_NO_ERR;
  }
  return WS_ERR;
}

long WSCvdrawingArea::drawFillRect(short x,short y,WSCushort w,WSCushort h){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawFillRect(x,y,w,h);
    return WS_NO_ERR;
  }
  return WS_ERR;
}

long WSCvdrawingArea::drawRects(WSCrect* pt,long num){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawRects(pt,num);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawFillRects(WSCrect* pt,long num){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawFillRects(pt,num);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawPoly(WSCpoint* pt,long num){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawPoly(pt,num);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawFillPoly(WSCpoint* pt,long num){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawFillPoly(pt,num);
    return WS_NO_ERR;
  }
  return WS_ERR;
}


long WSCvdrawingArea::drawGradation(long type,short col1,short col2,short col3,
              short x,short y,WSCushort w,WSCushort h,WSCuchar grad_margin){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawGradation(type,col1,col2,col3,x,y,w,h,grad_margin);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawGradation(long type,char* col1,char* col2,char* col3,
              short x,short y,WSCushort w,WSCushort h,WSCuchar grad_margin){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    short color1 = WSGIappColorSet()->getColorNo(col1);
    short color2 = WSGIappColorSet()->getColorNo(col2);
    short color3 = WSGIappColorSet()->getColorNo(col3);
    
    dev->drawGradation(type,color1,color2,color3,x,y,w,h,grad_margin);
    return WS_NO_ERR;
  }
  return WS_ERR;
}


long WSCvdrawingArea::drawImage(short x,short y,WSCushort w,WSCushort h,WSDimage* image,char align){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawImage(x,y,w,h,image,align);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawImage(short x,short y,WSCushort w,WSCushort h,
                                char* imagename,char align){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    WSDimage* image = WSGIappImageSet()->getImage(imagename);
    if (image == NULL){
      return WS_ERR;
    }
    dev->drawImage(x,y,w,h,image,align);
    return WS_NO_ERR;
  }
  return WS_ERR;
}

long WSCvdrawingArea::drawStretchedImage(short x,short y,WSCushort w,WSCushort h,WSDimage* image){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawStretchedImage(x,y,w,h,image);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawStretchedImage(short x,short y,WSCushort w,WSCushort h,char* imagename){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    WSDimage* image = WSGIappImageSet()->getImage(imagename);
    if (image == NULL){
      return WS_ERR;
    }
    dev->drawStretchedImage(x,y,w,h,image);
    return WS_NO_ERR;
  }
  return WS_ERR;
}


long WSCvdrawingArea::drawString(long x,long y,WSCulong w,WSCulong h,char fontno,char align,
                                 char* str,long encoding){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawString(x,y,w,h,fontno,align,str,encoding);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::drawFillString(long x,long y,WSCulong w,WSCulong h,char fontno,char align,
                                 char* str,long encoding){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->drawFillString(x,y,w,h,fontno,align,str,encoding);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::setForeColor(char* cname){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    short cno = WSGIappColorSet()->getColorNo(cname);
    dev->setForeColor(cno);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::setBackColor(char* cname){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    short cno = WSGIappColorSet()->getColorNo(cname);
    dev->setBackColor(cno);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::setLineWidth(short lw){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->setLineWidth(lw);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::setLineDashType(char no){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->setLineDashType(no);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::setHatchPattern(char no){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->setHatchPattern(no);
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSCvdrawingArea::setRegion(short x,short y,WSCushort w,WSCushort h){
  if (_begin_draw_fl ==1){
    WSDdev* dev = getowndev();
    if (dev == NULL){
      return WS_ERR;
    }
    dev->setRegion(x,y,w,h);
    return WS_NO_ERR;
  }
  return WS_ERR;
}


