//
// 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 <WSCprform.h>
#include <WSCclassInformation.h>
#include <WSCdevice.h>
#include <WSDdev.h>
#include <WSCfontSet.h>
#include <WSDprDev.h>
#include <WSDfileSystem.h>
#include <WSDnwDev.h>
#include <WSDpsdraw.h>
#include <WSDappDev.h>

WSMFguiClassInitialize(WSCprform,WSCform);
WSMFversion(WSCprform,WSCform);


WSMFpropertyValueChange( WSCprform, WSNbackColor , short,WS_DF_WORKBACKCOLOR);

WSCprform::WSCprform(WSCbase* base,char* objname):
                WSCform(base,objname){

  _pr_dev = NULL;
  _file_name = WSGFstrdup("tmp.ps");
  _w_x = 10;
  _w_y = 10;
  _w_w = 512;
  _w_h = 724;
  _format = WS_PR_A4;
  _type = WS_PR_PS;
  _orientation = WS_VERTICAL;
  _back_color = WS_DF_WORKBACKCOLOR;

  WSMFpropertyCreateStart
    WSMFparentCheckVerSrc(WSCprform);
    WSMFpropertyCreate(WSNfileName,char*,_file_name,WSSfileName);
    WSMFpropertyCreate(WSNworkX,short,_w_x,WSSworkX);
    WSMFpropertyCreate(WSNworkY,short,_w_y,WSSworkY);
    WSMFpropertyCreate(WSNworkWidth,WSCushort,_w_w,WSSworkWidth);
    WSMFpropertyCreate(WSNworkHeight,WSCushort,_w_h,WSSworkHeight);
    WSMFpropertyCreate(WSNformat,WSCuchar,_format,WSSformat);
      WSMFpropertySetSelection(WSRprformat, WSRprformatD);

    WSMFpropertyCreate(WSNtype,WSCuchar,_type,WSStype);
      WSMFpropertySetSelection(WSRprOut, WSRprOutD);

    WSMFpropertyCreate(WSNorientation,WSCuchar,_orientation,WSSorientation);
      WSMFpropertySetSelection(WSRorientation2, WSRorientation2D);

    WSMFpropertyValueChangeDef( WSCprform,WSNbackColor ,short);


  WSMFpropertyCreateEnd

}

WSMFproperty(WSCprform,WSNfileName,char*,_file_name,WSGFstrdup("tmp.ps"));
WSMFproperty(WSCprform,WSNworkX,short,_w_x,10);
WSMFproperty(WSCprform,WSNworkY,short,_w_y,10);
WSMFproperty(WSCprform,WSNworkWidth,WSCushort,_w_w,512);
WSMFproperty(WSCprform,WSNworkHeight,WSCushort,_w_h,724);
WSMFproperty(WSCprform,WSNformat,WSCuchar,_format,WS_PR_A4);
WSMFproperty(WSCprform,WSNtype,WSCuchar,_type,WS_PR_PS);
WSMFproperty(WSCprform,WSNorientation,WSCuchar,_orientation,WS_VERTICAL);

void WSCprform::setWorkWSNfileName(char*){}
void WSCprform::getWorkWSNfileName(char**){}
void WSCprform::setWorkWSNworkX(short){}
void WSCprform::getWorkWSNworkX(short*){}
void WSCprform::setWorkWSNworkY(short){}
void WSCprform::getWorkWSNworkY(short*){}
void WSCprform::setWorkWSNworkWidth(WSCushort){}
void WSCprform::getWorkWSNworkWidth(WSCushort*){}
void WSCprform::setWorkWSNworkHeight(WSCushort){}
void WSCprform::getWorkWSNworkHeight(WSCushort*){}
void WSCprform::setWorkWSNformat(WSCuchar){}
void WSCprform::getWorkWSNformat(WSCuchar*){}
void WSCprform::setWorkWSNtype(WSCuchar){}
void WSCprform::getWorkWSNtype(WSCuchar*){}
void WSCprform::setWorkWSNorientation(WSCuchar){}
void WSCprform::getWorkWSNorientation(WSCuchar*){}

WSCprform::~WSCprform(){
  if (_pr_dev != NULL){
    delete _pr_dev;
    _pr_dev = NULL;
  }
}

long WSCprform::draw(){
  if (_no_refresh != False){
    WSCbase::update();
    setAbsoluteDraw(False);
    return WS_NO_ERR;
  }
  if (getVisible() == False){
    return WS_NO_ERR;
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }

  WSCbool absolute = getAbsoluteDraw();
  if (absolute == False  ){
      if ( dev->isExposed(0,0,_w,_h) == False ){
        return WS_NO_ERR;
      }
  }

  long err = dev->beginDraw(0,0,_w,_h,absolute);
  if (err != WS_NO_ERR){
    return WS_NO_ERR;
  }
  short ex = 0;
  short ey = 0;
  WSCushort ew = _w;
  WSCushort eh = _h;
  if (absolute == False){
    dev->getExposedArea(&ex,&ey,&ew,&eh);
  }
  WSCbase::update();
  setAbsoluteDraw(False);

  if (_bp_color == -1){
    if (_grad_no == 0){
      dev->setForeColor(_back_color);
      dev->drawFillRect(0,0,_w,_h);
      if ((WSGIappDev()->getGuiPolicy() & WS_POLICY_AQUA) != 0 &&
           _bp_color == -1){
        if (_a1_color == -1){
          WSGFgetShadowColor(_back_color,&_a1_color,&_a2_color,&_a3_color);
        }
        WSGFdrawStripes(dev,_w,_h,_a1_color,_a2_color,_a3_color);
      }
      dev->setForeColor(_back_color);

    }else{
      dev->drawGradation(_grad_no,_ts_color,_back_color,_bs_color,0,0,_w,_h,_grad_margin);
    }
  }

  if (getDotMode() == True){
    dev->setForeColor(_fore_color);
    long i,j;
    for(i=0; i<_w; i+=10){
      for(j=0; j<_h; j+=10){
        if (ex < i && i < ex+ ew &&
            ey < j && j < ey+ eh ){
          dev->drawFillRect(i,j,1,1);
        }
      }
    }
  }
  dev->setForeColor(_fore_color);
  dev->drawRect(_w_x,_w_y,_w_w,_w_h);

  WSGFdrawShadow(dev,_shadow_type,_shadow_thick,_fore_color,_ts_color,_bs_color,_back_color,0,0,_w,_h);
  dev->endDraw();
  return WS_NO_ERR;


}

long WSCprform::prdraw(){
  if (_pr_dev == NULL){
    _pr_dev = new WSDprDev();
  }

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

  long type = _type;
#ifndef MSW
  if (type == 2){
    type = WS_PR_PS;
  }
#endif

  WSDfile* file = NULL;
  if (type != WS_PR_PRINTER){
    file = WSDfile::getNewInstance();
    if (file == NULL){
      return WS_ERR;
    }

    long ret = file->open(WSGIappFileSystem()->adjustFileName(_file_name),"w");
    if (ret != WS_NO_ERR){
      delete file;
      return WS_ERR;
    }

    _pr_dev->setFile(file);
  }else{
    WSDdraw* draw = WSDdev::getDraw();
    if (draw->cast("WSDwindraw") != NULL){
      long val = _w_x;
      draw->setValue(WSDEV_WORK_X,val);
      val = _w_y;
      draw->setValue(WSDEV_WORK_Y,val);
      val = _w_w;
      draw->setValue(WSDEV_WORK_WIDTH,val);
      val = _w_h;
      draw->setValue(WSDEV_WORK_HEIGHT,val);
      val = 1;
      long ret = draw->setValue(WSDEV_PR_PRINTER,val);
      if (ret == WS_ERR){
        return WS_ERR;
      } 
    }
  }
  _pr_dev->setValue(WSDEV_X,(void*)&_x);
  _pr_dev->setValue(WSDEV_Y,(void*)&_y);
  _pr_dev->setValue(WSDEV_WIDTH,(void*)&_w);
  _pr_dev->setValue(WSDEV_HEIGHT,(void*)&_h);
  long val = _w_x;
  _pr_dev->setValue(WSDEV_WORK_X,(void*)&val);
  val = _w_y;
  _pr_dev->setValue(WSDEV_WORK_Y,(void*)&val);
  val = _w_w;
  _pr_dev->setValue(WSDEV_WORK_WIDTH,(void*)&val);
  val = _w_h;
  _pr_dev->setValue(WSDEV_WORK_HEIGHT,(void*)&val);
  val = _type;
  _pr_dev->setValue(WSDEV_PR_TYPE,(void*)&val);
  val = _format;
  _pr_dev->setValue(WSDEV_PR_FORMAT,(void*)&val);
  val = _orientation;
  _pr_dev->setValue(WSDEV_PR_ORIENTATION,(void*)&val);


  WSDdev* bk = _dev;
  WSDdraw* psdraw = NULL;
  WSDdraw* draw_bk = WSDdev::getDraw();
  if (type != WS_PR_PRINTER){
    _dev = _pr_dev;
    psdraw = new WSDpsdraw();
    WSDdev::setDraw(psdraw);
  }

  dev->setExposedArea(0,0,_w,_h);
  long err = dev->beginDraw(0,0,_w,_h,True);
  if (err != WS_NO_ERR){
    return WS_NO_ERR;
  }

  execProcedure(WSEV_EXPOSE);

  WSClistData children = getChildren();
  long num = children.getNum();
  long i;
  WSCrect area;
  area.setRect(0,0,_w,_h);
  for(i=0; i<num; i++){
    WSCbase* child = (WSCbase*)children[i];
    WSDdev* childdev = child->getdev();
    WSDnwDev* ndev = (WSDnwDev*)childdev->cast("WSDnwDev");
    dev->setExposedArea(0,0,_w,_h);
    if (ndev != NULL){
      WSDdev* bk1 = ndev->getParentDev();
      WSDdev* bk2 = ndev->getEventParentDev();
      ndev->setParentDev(dev);
      ndev->setEventParentDev(dev);
      child->setAbsoluteDraw(True);
      child->draw();
      dev->setExposedArea(0,0,_w,_h);
      child->execEventProc(WSEV_EXPOSE,&area);
      ndev->setParentDev(bk1);
      ndev->setEventParentDev(bk2);
    }else{
      child->draw();
      dev->setExposedArea(0,0,_w,_h);
      child->execEventProc(WSEV_EXPOSE,&area);
    }
  }
  dev->endDraw();

  if (type != WS_PR_PRINTER){
    WSDdev::setDraw(draw_bk);
    delete psdraw;
    _dev = bk;
    if (file != NULL){
      file->close();
      delete file;
    }
  }else{
    WSDdraw* draw = WSDdev::getDraw();
    if (draw->cast("WSDwindraw") != NULL){
      long val = 0;
      long ret = draw->setValue(WSDEV_PR_PRINTER,val);
      if (ret == WS_ERR){
        return WS_ERR;
      } 
    }
  }

  return WS_NO_ERR;
}
