// BemIsolDoc.cpp : implementation of the CBemIsolDoc class
//

#include "stdafx.h"
#include "math.h"
#include "BemIsol.h"

#include "geom.h"
#include "BemIsolDoc.h"
#include "isolreg.h"
#include "isolnon.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBemIsolDoc

IMPLEMENT_DYNCREATE(CBemIsolDoc, CDocument)

BEGIN_MESSAGE_MAP(CBemIsolDoc, CDocument)
	//{{AFX_MSG_MAP(CBemIsolDoc)
	ON_COMMAND(ID_ISOL_SAVE, OnIsolSave)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBemIsolDoc construction/destruction

CBemIsolDoc::CBemIsolDoc()
{
	xsi=ysi=fpol=NULL;
}

CBemIsolDoc::~CBemIsolDoc()
{
}

BOOL CBemIsolDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	m_size.cx=1000;m_size.cy=800;
	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CBemIsolDoc serialization

void CBemIsolDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar << name << kx << ky << thick;
		ar.Write (&lfnt,sizeof(LOGFONT));
	}
	else
	{
		ar >> name >> kx >> ky >> thick;
		ar.Read (&lfnt,sizeof(LOGFONT));
	}
	Nodes.Serialize(ar);
	Elems.Serialize(ar);
	Wells.Serialize(ar);
	IntNods.Serialize(ar);
	TriElems.Serialize(ar);
}

/////////////////////////////////////////////////////////////////////////////
// CBemIsolDoc diagnostics

#ifdef _DEBUG
void CBemIsolDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CBemIsolDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CBemIsolDoc commands

BOOL CBemIsolDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	
	decpo=2;
	return TRUE;
}

void CBemIsolDoc::DeleteContents() 
{
	int i=0;
	while (i<Nodes.GetSize())
	{
		delete Nodes.GetAt(i++);
	}	                     
	Nodes.RemoveAll();
	i=0;
	while (i<Elems.GetSize())
	{
		delete Elems.GetAt(i++);
	}	                     
	Elems.RemoveAll();
	i=0;
	while (i<Wells.GetSize())
	{
		delete Wells.GetAt(i++);
	}	                     
	Wells.RemoveAll();
	i=0;
	while (i<IntNods.GetSize())
	{
		delete IntNods.GetAt(i++);
	}	                     
	IntNods.RemoveAll();
	i=0;
	while (i<TriElems.GetSize())
	{
		delete TriElems.GetAt(i++);
	}	                     
	TriElems.RemoveAll();
	i=0;
	while (i<Lines.GetSize())
	{
		delete Lines.GetAt(i++);
	}	                     
	Lines.RemoveAll();

	if (xsi!=NULL) delete xsi;
	if (ysi!=NULL) delete ysi;
	if (fpol!=NULL) delete fpol;
	pol.RemoveAll();
	CDocument::DeleteContents();
}

void CBemIsolDoc::GenerNet(int nx, int ny)
{
 	int i,j;
 	float x,y,dx,dy,ximin,yimin,ximax,yimax,deltx,delty;
 	yimin=ximin=1e+30;ximax=yimax=-1e+30;
	int nuz=Nodes.GetSize();
 	for (i=0;i<nuz;i++)
 	{
 		CNode* bd=GetNode(i);
 		bd->Coord(x,y);
  		if (x<ximin) ximin=x;
  		if (x>ximax) ximax=x;
  		if (y>yimax) yimax=y;
  		if (y<yimin) yimin=y;
 	}
 	dx=(ximax-ximin)/(float)nx;dy=(yimax-yimin)/(float)nx;
 	ximin+=dx;yimin+=dy;
 	ximax-=dx;yimax-=dy;
  	deltx=(ximax-ximin)/(float)nx;delty=(yimax-yimin)/(float)ny;
  	npx=nx+1;npy=ny+1;
	if (xsi!=NULL) delete xsi;
	xsi=new float[npx];
	if (ysi!=NULL) delete ysi;
	ysi=new float[npy];
  	for (i=0;i<npx;i++)
  	{
     	xsi[i]=i*deltx+ximin;
    }	
  	for (j=0;j<npy;j++)
  	{
    	ysi[j]=j*delty+yimin;
 	}
	if (fpol!=NULL) delete fpol;
	fpol=new float[npx*npx];
 	pol.RemoveAll();      
 	j=0;
 	for (i=0;i<npx*npy;i++) pol.Add(j);
	TabWell (deltx,delty,ximin,yimin);
}

void CBemIsolDoc::TabWell(float deltx,float delty,float ximin,float yimin)
{
	int i,j,iz,im,jm;
	float dmin,dx,dy,d,xb,yb;
	for (iz=0;iz<Wells.GetSize();iz++)
	{
		CWell* wl=GetWell(iz);
		dmin=1e+30;
		for (i=0;i<npx;i++)              /* cyklus of columns */
		{
			xb=i*deltx+ximin;
			for (j=0;j<npy;j++)             /* cyklus of rows */
			{
				yb=j*delty+yimin;
				dx=wl->xz-xb;dy=wl->yz-yb;
				d=sqrt (dx*dx+dy*dy);
				if (dmin>d) {dmin=d;im=i;jm=j;}
			}
		}
		wl->izm=im*npx+jm;
	}
}

void CBemIsolDoc::PlotNod (CDC* pDC,int sz,BOOL IsNum)
{
	int i,n;
	CFont hf,*hfp;
	hf.CreateFontIndirect(&lfnt);
	hfp=pDC->SelectObject(&hf);
	for (i=0;i<Nodes.GetSize();i++)
	{
		CNode* nd=GetNode(i);
		if (IsNum) n=i+1;
		else n=-1;
		nd->PlotNode (pDC,n,sz,gcb);
	}
	pDC->SelectObject(hfp);
	hf.DeleteObject();
}

void CBemIsolDoc::PlotIntPt (CDC* pDC,int sz,BOOL IsNum)
{
	int i,n;
	CFont hf,*hfp;
	hf.CreateFontIndirect(&lfnt);
	hfp=pDC->SelectObject(&hf);
	for (i=0;i<IntNods.GetSize();i++)
	{
		CIntPoint* nd=GetIntPt(i);
		if (IsNum) n=i+1;
		else n=-1;
		nd->PlotPt (pDC,n,sz,gcb);
	}
	pDC->SelectObject(hfp);
	hf.DeleteObject();
}

CNode* CBemIsolDoc::GetNode(int i)
{
	return (CNode*)Nodes.GetAt(i);
}

CWell* CBemIsolDoc::GetWell(int i)
{
	return (CWell*)Wells.GetAt(i);
}

CElement* CBemIsolDoc::GetElement(int i)
{
	return (CElement*)Elems.GetAt(i);
}

CIntPoint* CBemIsolDoc::GetIntPt(int i)
{
	return (CIntPoint*)IntNods.GetAt(i);
}

CIntElem* CBemIsolDoc::GetIntElem(int i)
{
	return (CIntElem*)TriElems.GetAt(i);
}

CSize CBemIsolDoc::GetDocSize()
{
	return m_size;
}

void CBemIsolDoc::ScaleNods(CRect rc)
{
	int i;
	float xmin,xmax,ymin,ymax,dx,dxi,dy,dyi,dp1,dp2;
	if (Nodes.GetSize()==0) return;
	CNode* nd=GetNode(0);
	xmin=xmax=nd->xb;ymin=ymax=nd->yb;
	for (i=0;i<Nodes.GetSize();i++)
	{
		nd=GetNode(i);
		if (nd->xb>xmax) xmax=nd->xb;
		if (nd->xb<xmin) xmin=nd->xb;
		if (nd->yb>ymax) ymax=nd->yb;
		if (nd->yb<ymin) ymin=nd->yb;
	}
	dxi=rc.Width()-100;dyi=rc.Height()-100;
	dx=xmax-xmin;dy=ymax-ymin;
	gcb[0]=rc.left+50;gcb[3]=rc.top+50;
	gcb[2]=xmin;gcb[5]=ymax;
	if (fabs(dx)<1e-5 || fabs(dy)<1e-5)
	{
		gcb[1]=100.0f;gcb[4]=-100.0f;
	}
	else
	{
		dp1=fabs(dxi/dx);dp2=fabs(dyi/dy);
		if (dp1<dp2) {gcb[1]=dp1;gcb[4]=-dp1;}
		else {gcb[1]=dp2;gcb[4]=-dp2;}
	}
	m_size.cx=rc.right;m_size.cy=rc.bottom;
}

void CBemIsolDoc::Potenc(CDC &td)
{
 	int i,j,j1,j2,k,ib,ix,iy,imin,imax;
 	double a,b,ra,rb,qq,pvb,sumpr,tx,ty,txy,tt,tp;
 	double xb,yb,pi=3.14159265,
      	x1,x2,y1,y2,pt,dpt,dx,dy,zr,ch;

 	CPoint *rego,ptb;
	fmin=1e+30;fmax=-fmin;
	if (xsi==NULL) return;
    tx=kx*thick;ty=ky*thick;
  	txy=sqrt(tx/ty);tt=sqrt(ty/tx);
	tp= 0.1591549430919/tt;       // 1/(2*pi)
	rprec=precip/(tx*3.1536e10);
	int nel=Elems.GetSize();
	int nwl=Wells.GetSize();
	int ntri=TriElems.GetSize();
	rego=new CPoint[nel];
	for (i=0;i<nel;i++)
	{
		CElement* el=GetElement(i);
		j=el->nod1;
		CNode* nd=GetNode(j);
		nd->TranCoord(gcb);
		rego[i]=nd->Coord();
	}
	CRgn rgo;
	rgo.CreatePolygonRgn(rego,nel,ALTERNATE);
   	ib=-1;
   	for (ix=0;ix<npx;ix++)
   	{                 
   		xb=xsi[ix];
   		for (iy=0;iy<npy;iy++)
   		{
   			yb=ysi[iy]*txy; 
   			ib++;
//   			if (pol[ib]>0) continue;
			ptb=TranCoord(xb,ysi[iy]);
			if (!rgo.PtInRegion(ptb)) continue;
   			td.SetPixel (ptb.x,ptb.y,RGB(255,0,0));
    		pol[ib]=1;
      		pvb=0;
      		for (k=0;k<nel;k++)
      		{
				CElement* el=GetElement(k);
       			pt=el->pot;dpt=el->der;
				j1=el->nod1;j2=el->nod2;
				CNode* nd1=GetNode(j1);CNode* nd2=GetNode(j2);
       			Integ (xb,yb,nd1->xb,nd1->yb*txy,nd2->xb,nd2->yb*txy,a,b,tt);
    			pvb+=dpt*b-pt*a;
      		}
      		if (nwl>0)
      		{
       			for (k=0;k<nwl;k++)
       			{            
       				CWell* wl=GetWell(k);
					dx=xb-wl->xz;dy=yb-wl->yz*txy;
					if (fabs(dx)<1e-8) dx=1e-8;
					if (fabs(dy)<1e-8) dy=1e-8;
       				qq=-wl->yield/tx;
 					rb=dx*dx+dy*dy;
 					ra=1./sqrt(rb);
 					pvb+=qq*log(ra);
				}
       		}
      		if (ntri>0&&fabs(rprec)>1e-8)
      		{
       			sumpr=0.0;
       			for (j=0;j<ntri;j++)
       			{   	
       				CIntElem* vnp=GetIntElem(j);
					zr=0;
					x1=vnp->xp[0];x2=vnp->xp[1];
					y1=vnp->yp[0]*txy;y2=vnp->yp[1]*txy;
					ch=Cell (x1,x2,y1,y2,xb,yb,tt);
					zr+=ch;
					x1=vnp->xp[1];x2=vnp->xp[2];
					y1=vnp->yp[1]*txy;y2=vnp->yp[2]*txy;
					ch=Cell (x1,x2,y1,y2,xb,yb,tt);
					zr+=ch;
					x1=vnp->xp[2];x2=vnp->xp[0];
					y1=vnp->yp[2]*txy;y2=vnp->yp[0]*txy;
					ch=Cell (x1,x2,y1,y2,xb,yb,tt);
					zr+=ch;
					sumpr+=zr*rprec;
       			}
      			pvb-=sumpr;
     		}
      		pvb*=tp;
      		if (fabs(pvb)<1e-37) pvb=0;
      		fpol[ib]=pvb;
     	}
    }
	for (i=0;i<Wells.GetSize();i++)
	{
		CWell* wl=GetWell(i);
		fpol[wl->izm]=wl->drwdown;
	}
	ib=0;
	imin=imax=-1;
	for (i=0;i<npx;i++)
	{
		for (j=0;j<npy;j++)
		{
			if (pol[ib]>0)
			{
				if (fpol[ib]<fmin) {fmin=fpol[ib];imin=ib;}
				if (fpol[ib]>fmax) {fmax=fpol[ib];imax=ib;}
			}
			ib++;
		}
	}
	step=(fmax-fmin)/10.0f;
	rgo.DeleteObject();
	delete rego;
}

CPoint CBemIsolDoc::TranCoord(float x, float y)
{
	CPoint p;
	float dx,dy;
	dx=gcb[1]*(x-gcb[2]);dy=gcb[4]*(y-gcb[5]);
	if (dx>0.0f) dx+=0.5f;
	else dx-=0.5f;
	if (dy>0.0f) dy+=0.5f;
	else dy-=0.5f;
 	p.x=gcb[0]+dx;
 	p.y=gcb[3]+dy;
	return p;
}

void CBemIsolDoc::InterIso(CDC &td)
{
 	int i,j,k,ix,iy,ns,nr,ij,kc[4],ii,nak,kak[4],i1,i2,it,ih,iw,ipr;
 	float xp[4],yp[4],ax[4],ay[4],fp[4],ap[4],w,
       xc[4],yc[4],xpr[4],ypr[4],dp,ap23,ap13,xt[3],yt[3],ft[3],dh,dx,dy,fpmin,fpmax;

 	ns=npx-1;nr=npy-1;
	i=0;
	while (i<Lines.GetSize())
	{
		delete Lines.GetAt(i++);
	}	                     
	Lines.RemoveAll();
 	for (iw=0;iw<Isolin.GetSize();iw++)            /* cyklus izolinii */
 	{     
 		w=Isolin[iw];
		ipr=0;
  		for (ix=0;ix<ns;ix++)                   /* cyklus stlpcov */
  		{
   			ij=ix*npy;
   			xp[0]=xp[3]=xsi[ix];
   			xp[1]=xp[2]=xsi[ix+1];
   			for (iy=0;iy<nr;iy++)                  /* cyklus radov */
   			{
				ipr++;
    			kc[0]=ij+iy;kc[1]=kc[0]+npy;
    			kc[2]=kc[1]+1;kc[3]=kc[0]+1;
    			yp[0]=yp[1]=ysi[iy];yp[2]=yp[3]=ysi[iy+1];
    			ii=0;
    			fpmin=1e+30;fpmax=-fpmin;
    			for (i=0;i<4;i++)
    			{
     				j=kc[i];
     				ii+=pol[j];
     				if (pol[j]>0)
     				{
      					fp[i]=fpol[j];
						for (k=0;k<Wells.GetSize();k++)
						{
							CWell* wl=GetWell(k);
							if (wl->izm==j)
							{
								xp[i]=wl->xz;yp[i]=wl->yz;
								fp[i]=wl->drwdown;
							}
						}
      					if (fp[i]>fpmax) fpmax=fp[i];
      					if (fp[i]<fpmin) fpmin=fp[i];
      				}
     			}
    			if (ii<3) continue;              /* prvok nelezi dnu */
    			if (w<fpmin||w>fpmax) continue;   /* izolinia nepretina prvok */
    			if (ii==4)
    			{
     				bazf (xp,ax);
     				bazf (yp,ay);
     				bazf (fp,ap);
     				for (i=1;i<4;i++) {if (fabs(ap[i])<1e-8) ap[i]=1e-8;}
     				dp=w-ap[0];        /* priesecniky s hranami */
     				ap23=ap[2]+ap[3];if (fabs(ap23)<1e-8) ap23=1e-8;
     				ap13=ap[1]+ap[3];if (fabs(ap13)<1e-8) ap13=1e-8;
     				ypr[0]=0;xpr[0]=dp/ap[1];
     				ypr[1]=(dp-ap[1])/ap23;xpr[1]=1;
     				ypr[2]=1;xpr[2]=(dp-ap[2])/ap13;
     				ypr[3]=dp/ap[2];xpr[3]=0;
     				nak=0;
     				for (i=0;i<4;i++)
     				{
      					if (xpr[i]<0||xpr[i]>1) continue;
      					if (ypr[i]<0||ypr[i]>1) continue;
      					kak[nak++]=i;
     				}
     				if (nak==2)
     				{
      					i=kak[0];
      					xc[0]=bipol(ax,xpr[i],ypr[i]);
      					yc[0]=bipol(ay,xpr[i],ypr[i]);
      					i=kak[1];
      					xc[1]=bipol(ax,xpr[i],ypr[i]);
      					yc[1]=bipol(ay,xpr[i],ypr[i]);
      					CLine* us=AddLine (w,xc[0],yc[0],xc[1],yc[1]);
						us->cok=ipr;
      					us->Plot (td,gcb);
     				}
     				if (nak==4)
     				{
      					for (i=0;i<4;i++)
      					{
       						xc[i]=bipol(ax,xpr[i],ypr[i]);
       						yc[i]=bipol(ay,xpr[i],ypr[i]);
       					}
      					CLine* us1=AddLine (w,xc[0],yc[0],xc[1],yc[1]);
						us1->cok=ipr;
      					CLine* us2=AddLine (w,xc[2],yc[2],xc[3],yc[3]);
						us2->cok=ipr;
      					us1->Plot (td,gcb);
      					us2->Plot (td,gcb);
     				}
    			}
    			else           // trojuholnikovy prvok
    			{
     				it=0;
     				for (i=0;i<4;i++)
     				{
      					j=kc[i];
      					if (pol[j]>0)
      					{
       						xt[it]=xp[i];yt[it]=yp[i];ft[it]=fp[i];
       						it++;
      					}
     				}
     				it=0;
     				for (ih=0;ih<3;ih++)
     				{
      					i1=ih;i2=ih+1;if (i2>2) i2=0;
      					if (ft[i1]==w) ft[i1]+=1e-7;
      					ap23=ft[i2]-ft[i1];if (fabs(ap23)<1e-7) ap23=1e-7;
      					dh=(w-ft[i1])/ap23;
      					dx=xt[i2]-xt[i1];
      					dy=yt[i2]-yt[i1];
      					if (dh>=0&&dh<=1)
      					{
       						xc[it]=xt[i1]+dh*dx;
       						yc[it]=yt[i1]+dh*dy;
       						it++;
      					}
     				}
     				if (it>0)
     				{
     					CLine* us=AddLine (w,xc[0],yc[0],xc[1],yc[1]);
						us->cok=ipr;
      					us->Plot (td,gcb);
     				}
    			}
   			}              // end of rows
  		}               // end of columns 
 	}                // end of isolines cyklus 
}

CLine* CBemIsolDoc::AddLine(float w, float x1, float y1, float x2, float y2)
{
	CLine* ln=new CLine (w,x1,y1,x2,y2);
	Lines.Add(ln);
	return ln;
}

void CBemIsolDoc::PlotElem(CDC *pDC, BOOL IsNum)
{
	int i;
	CPoint p[2];
	CPen *ppr;
	CFont hf,*hfp;
	hf.CreateFontIndirect(&lfnt);
	hfp=pDC->SelectObject(&hf);
	ppr=(CPen*)pDC->SelectStockObject(BLACK_PEN);
	for (i=0;i<Elems.GetSize();i++)
	{
		CElement* el=GetElement(i);
		CNode* n1=GetNode(el->nod1);CNode* n2=GetNode(el->nod2);
		n1->TranCoord(gcb);n2->TranCoord(gcb);
		p[0]=n1->Coord();p[1]=n2->Coord();
		pDC->Polygon(p,2);
		if (IsNum)
		{
			int ix,iy;
			ix=(p[0].x+p[1].x)/2;iy=(p[0].y+p[1].y)/2;
			CString msg;
			msg.Format("E%d",i+1);
			UINT tap=pDC->SetTextAlign(TA_CENTER | TA_BOTTOM);
			pDC->TextOut (ix,iy,msg);
			pDC->SetTextAlign(tap);
		}
		pDC->SelectStockObject(BLACK_PEN);
	}
	pDC->SelectObject(hfp);
	pDC->SelectObject(ppr);
	hf.DeleteObject();
}

void CBemIsolDoc::PlotWells(CDC *pDC, int sz)
{
	int i;
	CFont hf,*hfp;
	hf.CreateFontIndirect(&lfnt);
	hfp=pDC->SelectObject(&hf);
	for (i=0;i<Wells.GetSize();i++)
	{
		CWell* nd=GetWell(i);
		nd->Plot (pDC,gcb,sz);
	}
	pDC->SelectObject(hfp);
	hf.DeleteObject();
}

float CBemIsolDoc::bipol (float *a,float x,float y)
{
 	return (a[0]+a[1]*x+a[2]*y+a[3]*x*y);
}

void CBemIsolDoc::bazf (float *fp,float *ap)
{
 	ap[0]=fp[0];ap[1]=fp[1]-fp[0];ap[2]=fp[3]-fp[0];
 	ap[3]=fp[2]+fp[0]-fp[1]-fp[3];
}

BOOL CBemIsolDoc::InterIsoReg()
{
	CIsolReg isrg;
	float fi;
	isrg.m_max=fmax;isrg.m_min=fmin;isrg.m_step=step;
	if (isrg.DoModal()==IDOK)
	{
		fmax=isrg.m_max;fmin=isrg.m_min;step=isrg.m_step;
		Isolin.RemoveAll();
		for (fi=fmin;fi<fmax+0.5*step;fi+=step) Isolin.Add(fi);
		return TRUE;
	}
	return FALSE;
}

void CBemIsolDoc::PlotLines(CDC *pDC)
{
	int i;
	for (i=0;i<Lines.GetSize();i++)
	{
		CLine* ln=(CLine*)Lines.GetAt(i);
		PlotLine(pDC,i);
	}
}

BOOL CBemIsolDoc::InterIsoNon()
{
	CIsolNon isno;
	isno.pDoc=this;
	isno.m_min.Format("Minimum: %.4f",fmin);
	isno.m_max.Format("Maximum: %.4f",fmax);
	if (isno.DoModal()==IDOK)
	{
		return TRUE;
	}
	return FALSE;
}

void CBemIsolDoc::OnIsolSave() 
{
	char szFile[256];
	UINT  cbString;
	int i;
	char  chReplace;    /* string separator for szFilter */
	char  szFilter[256];
	CString namef;
	CFileDialog fd(FALSE);    
	CFile hf;

    strcpy(szFilter,"Contours (*.CON)|*.iso|All files (*.*)|*.*|");
    cbString=strlen(szFilter);
	chReplace = szFilter[cbString - 1]; /* retrieve wildcard */
    szFile[0]=0;
    
    for (i = 0; szFilter[i] != '\0'; i++) 
	{
    	if (szFilter[i] == chReplace) szFilter[i] = '\0';
	}

/* Set all structure members to zero. */

	fd.m_ofn.lpstrFilter = szFilter;
	fd.m_ofn.nFilterIndex = 1;
	fd.m_ofn.lpstrFile= szFile;
	fd.m_ofn.nMaxFile = sizeof(szFile);
	fd.m_ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT | OFN_ENABLEHOOK | OFN_EXPLORER;


	if (fd.DoModal()==IDOK) 
	{
		namef=fd.GetPathName();
		CString namex;
		namex=fd.GetFileExt();
		if (namex.IsEmpty()) namef+=".iso";
		hf.Open(namef,CFile::typeBinary | CFile::modeWrite | CFile::modeCreate);
		CArchive ar(&hf,CArchive::store);
		ar << fmin << fmax << step;
		Isolin.Serialize(ar);
		Lines.Serialize(ar);
		ar.Close();
		hf.Close();
	}
}

void CBemIsolDoc::OpenIsol()
{
	char szFile[256];
	UINT  cbString;
	int i;
	char  chReplace;    /* string separator for szFilter */
	char  szFilter[256];
	CString namef;
	CFileDialog fd(TRUE);    
	CFile hf;

    strcpy(szFilter,"Contours (*.CON)|*.con|All files (*.*)|*.*|");
    cbString=strlen(szFilter);
	chReplace = szFilter[cbString - 1]; /* retrieve wildcard */
    szFile[0]=0;
    
    for (i = 0; szFilter[i] != '\0'; i++) 
	{
    	if (szFilter[i] == chReplace) szFilter[i] = '\0';
	}

/* Set all structure members to zero. */

	fd.m_ofn.lpstrFilter = szFilter;
	fd.m_ofn.nFilterIndex = 1;
	fd.m_ofn.lpstrFile= szFile;
	fd.m_ofn.nMaxFile = sizeof(szFile);
	fd.m_ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ENABLEHOOK | OFN_EXPLORER;


	if (fd.DoModal()==IDOK) 
	{
		namef=fd.GetPathName();
		hf.Open(namef,CFile::typeBinary | CFile::modeRead);
		CArchive ar(&hf,CArchive::load);
		ar >> fmin >> fmax >> step;
		Isolin.Serialize(ar);
		Lines.Serialize(ar);
		ar.Close();
		hf.Close();
	}
}

void CBemIsolDoc::PlotLine(CDC *pDC, int il)
{
	int ix,iy;
	float dx,dy,alph;
	CPen pbl(PS_SOLID,1,RGB(0,0,255)),*ppr;
	CFont hf,*hfp;
	LOGFONT lfon;
	lfon=lfnt;
	ppr=pDC->SelectObject(&pbl);
	CLine* ln=(CLine*)Lines.GetAt(il);
	pDC->SetTextColor(RGB(0,0,255));
	ln->Plot(*pDC,gcb);
	if (ln->ip)
	{
		dx=ln->xb2-ln->xb1;dy=ln->yb2-ln->yb1;
		alph=atan2(dy,dx)*572.958f;lfon.lfEscapement=alph;
		hf.CreateFontIndirect(&lfon);
		CString msg;
		msg.Format("%.*f",decpo,ln->w);
		hfp=pDC->SelectObject(&hf);
		pDC->SetTextAlign(TA_CENTER | TA_BOTTOM);
		ix=(ln->ix1+ln->ix2)/2;iy=(ln->iy1+ln->iy2)/2;
		pDC->TextOut(ix,iy,msg);
		pDC->SelectObject(hfp);
		hf.DeleteObject();
	}
	pDC->SelectObject(ppr);
	pbl.DeleteObject();
}

int CBemIsolDoc::LabLine(CPoint pt)
{
	int i,dx,dy;
	float dex,dey,dl;  
	CPoint obl[4];        
	for (i=0;i<Lines.GetSize();i++)
	{
  		CLine* lin=(CLine*)Lines.GetAt(i);
   		lin->trancor(gcb);
		CRgn hr;
		dex=(lin->ix2)-(lin->ix1);dey=lin->iy2-lin->iy1;
		dl=sqrt(dex*dex+dey*dey);if (dl<1e-8) dl=1e-8;
		dx=dey*5.0/dl;dy=dex*5.0/dl;
		obl[0].x=lin->ix1+dx;obl[0].y=lin->iy1+dy;
		obl[1].x=lin->ix2+dx;obl[1].y=lin->iy2+dy;
		obl[2].x=lin->ix2-dx;obl[2].y=lin->iy2-dy;
		obl[3].x=lin->ix1-dx;obl[3].y=lin->iy1-dy;
		hr.CreatePolygonRgn (obl,4,ALTERNATE);
		if (hr.PtInRegion(pt)) 
		{
			hr.DeleteObject();
			if (lin->ip==1) lin->ip=0;
			else lin->ip=1;
			return i;
		}
		hr.DeleteObject();
	}                                      
	return -1;
}

void CBemIsolDoc::ChangeFont()
{
	LOGFONT pom;
	memcpy (&pom,&lfnt,sizeof(LOGFONT));
	CFontDialog dlg(&pom, CF_SCREENFONTS|CF_INITTOLOGFONTSTRUCT);
	if (dlg.DoModal() == IDOK)
	{      
		memcpy (&lfnt,&pom,sizeof(LOGFONT));
		SetModifiedFlag();
	}
}

