//
// 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 <WSCvertForm.h>
#include <WSCclassInformation.h>
#include <WSCdevice.h>
#include <WSDdev.h>
#include <WSCfontSet.h>
#include <WSCvradio.h>

WSMFguiClassInitialize(WSCvertForm,WSCform);
WSMFversion(WSCvertForm,WSCform);

WSMFpropertyValueChange( WSCvertForm, WSNshadowType , char,WS_SHADOW_EIN);

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

  _min = 20;
  _margin = 4;
  _vertical = 1;
  _alignment = 0;
  _shadow_type = WS_SHADOW_EIN;
  WSMFpropertyCreateStart
    WSMFparentCheckVerSrc(WSCvertForm);

    WSMFpropertyCreate(WSNminimum,WSCushort,_min,WSSminimum );
    WSMFpropertyCreate(WSNmargin,WSCuchar,_margin,WSSmargin );
    WSMFpropertyCreate(WSNalignmentH,WSCuchar,_alignment,WSSalignmentH2 );
      WSMFpropertySetSelection(WSRalignmentH2,WSRalignmentH2D);

    WSMFpropertyValueChangeDef( WSCvertForm,WSNshadowType ,char);

    WSMFaddTrigger(WSEV_VALUE_CH    );

  WSMFpropertyCreateEnd

}

WSMFproperty(WSCvertForm, WSNminimum, WSCushort,_min,20);
WSMFproperty(WSCvertForm, WSNmargin, WSCuchar,_margin,4);
WSMFproperty(WSCvertForm, WSNalignmentH, WSCuchar,_alignment,0);

void WSCvertForm::setWorkWSNminimum(WSCushort){}
void WSCvertForm::getWorkWSNminimum(WSCushort*){}

void WSCvertForm::setWorkWSNmargin(WSCuchar){
  _adjust();
}
void WSCvertForm::getWorkWSNmargin(WSCuchar*){}

void WSCvertForm::setWorkWSNalignmentH(WSCuchar){}
void WSCvertForm::getWorkWSNalignmentH(WSCuchar*){}

WSCvertForm::~WSCvertForm(){
}

long WSCvertForm::draw(){

  if (_no_refresh != False){
    WSCbase::update();
    setAbsoluteDraw(False);
    return WS_NO_ERR;
  }
  if (getVisible() == False){
    return WS_NO_ERR;
  }
  _adjust();
  return WSCform::draw();
}

void WSCvertForm::onResize(WSCrect* rect){
  WSCform::onResize(rect);
}

void WSCvertForm::update(){
  _adjust();
  if (isNeedUpdate() != False){
    WSCform::update();
  }
}

void WSCvertForm::_adjust(){
  if (_update_registered == 0){
    return;
  }
  WSClistData childlist;
  WSClistData childpos;
  WSClistData children = getChildren();
  long i;
  long num = children.getNum();

  char* wsnpos = WSNy;
  char* wsnpos2 = WSNx;
  char* wsnwidth = WSNheight;
  char* wsnheight = WSNwidth;
  if (_vertical == False){
    wsnpos = WSNx;
    wsnpos2 = WSNy;
    wsnwidth = WSNwidth;
    wsnheight = WSNheight;
  }

  WSCulong pwidth = getProperty(wsnwidth);
  WSCulong pheight = getProperty(wsnheight);

  WSCulong realwidth = 0;
//  WSCulong optwidth = 0;
  for(i=0; i <num; i++){
    WSCbase* child = (WSCbase*)children[i];
    if (child->getInternalObject() != False){
      continue;
    }
    WSCstring noadjust;
    noadjust = child->getProperty(WSNuserString);
    if (!strcmp(noadjust,"no-adjust")){
      continue;
    }
    if (child->getVisible() != False){
      long val = child->getProperty(wsnpos);
      long width = child->getProperty(wsnwidth);
      if (width < _min){
        width = _min;
        child->setProperty(wsnwidth,width);
      }
      realwidth += width;
      if (pwidth > (unsigned long)_margin*2){ 
        pwidth -= _margin*2;
      }else{
        pwidth =1;
      }
//      optwidth += _margin*2;
//      if (width > _min){
//        optwidth += _min;
//      }else{
//        optwidth += width;
//      }
      long cnum = childpos.getNum();
      long k;
      for(k=0; k<cnum; k++){
        long tpos = (long)childpos[k];
        if (val < tpos){
          break;
        }
      }
      childlist.add((void*)child,k);
      childpos.add((void*)val,k);
    }
  }
  WSCbool adjust_lastone = True;
  num = childlist.getNum();
  if ( (unsigned long)(num * _min) > pwidth){
    return;
  }
  for(i=0;i<num -1; i++){
    WSCbase* child = (WSCbase*)childlist[i];
    if (child->cast("WSCvspace") != NULL){
      WSCbool ext = child->getProperty(WSNextension);
      WSCbool vert = child->getProperty(WSNorientation);
      if (ext != 0 && vert == _vertical){
        adjust_lastone = False;
      }
    }
  }

  num = childlist.getNum();
  long adjustfl = 0;
  for(i=num-1;i>-1; i--){
    WSCbase* child = (WSCbase*)childlist[i];
    long cw = child->getProperty(wsnwidth);
    long ch = child->getProperty(wsnheight);
    if (pwidth < realwidth && cw > _min){
      if ((unsigned long)(realwidth - pwidth) > (unsigned long)(cw - _min)){
        child->setProperty(wsnwidth,_min);
      }else{
        child->setProperty(wsnwidth,(cw - (realwidth - pwidth)));
      }
    }else if (pwidth > realwidth ){
      if (i == num-1 && adjust_lastone != False){
        if (adjustfl == 0){
          child->setProperty(wsnwidth,(cw + (pwidth - realwidth)));
          adjustfl =1;
        }
      }else if (child->cast("WSCvspace") != NULL){
        WSCbool ext = child->getProperty(WSNextension);
        WSCbool vert = child->getProperty(WSNorientation);
        if (ext != 0 && vert == _vertical){
          if (adjustfl == 0){
            child->setProperty(wsnwidth,(cw + (pwidth - realwidth)));
            adjustfl =1;
          }
        }
      }
    }

    if (_alignment == 0){
      //do nothing.
    }else if (_alignment == 1){
      child->setProperty(wsnpos2,_margin);
    }else if (_alignment == 2){
      child->setProperty(wsnpos2,(pheight - ch)/2);
    }else if (_alignment == 3){
      child->setProperty(wsnpos2,(pheight - _margin - ch));
    }else if (_alignment == 4){
      child->setProperty(wsnpos2,_margin);
      child->setProperty(wsnheight,(pheight - _margin*2));
    }
  }
  long pos = 0;
  for(i=0;i<num; i++){
    WSCbase* child = (WSCbase*)childlist[i];
    long cw = child->getProperty(wsnwidth);
    pos += _margin;
    child->setProperty(wsnpos,pos);
    pos += cw;
    pos += _margin;
  }
}
void WSCvertForm::_exec_child_adjust_for_anchors(){
  if (_geometry_changed != False){
    WSClistData children = getChildren();
    long num = children.getNum();
    long i;
    for(i=0; i<num; i++){
      WSCbase* child = (WSCbase*)children[i];
      child->_adjust_for_anchors(_w,0);
    }
  }
}

