/*
2D VERTEX MODEL OF DROSOPHILA VENTRAL FURROW FORMATION
MULTILAYERED SIMULATION - LATERAL EDGES NOW HAVE MORE THAN ONE POINT ALONG WHICH THEY CAN MOVE
BY OLEG POLYAKOV | PRINCETON UNIVERSITY | 2008 - 2013

This model was developed to study the process of ventral furrow formation in Drosophila Melanogaster.

In this model we consider the consider the midplane cross section of theemrbyo at the onset of gasrtulation. 
This corresponds to a geometry of 80 cells connected in a ring. 
The volumes of the yolk, the cellularvolumes, as well as the apical, basal, and lateral sides of all the cellshave an "elastic" energy equation of the form K*(X - Xo)^2. 

The input energy comes entirely from apical constriction.
It is a Gaussian distribution centered on the ventral surface with a width of sigma.

This also has additional graphic component taken from DaniWeb at:
https://www.daniweb.com/software-development/cpp/code/216430/add-a-little-graphics-to-your-console
*/


#include <iostream>
#include <fstream>
#include <Windows.h>

using namespace std;

#define Red  RGB (255,0,0)
#define Lime RGB (206,255,0)
#define Blue RGB (0,0,255)
#define Green RGB (0,255,0)
#define Black RGB (0,0,0)
static HWND    hConWnd;
int     BCX_Line (HWND,int,int,int,int,int=0,HDC=0);
int     BCX_Circle (HWND,int,int,int,int=0,int=0,HDC=0);
HWND    GetConsoleWndHandle (void);

#include "Embryo_class.h"

int main() {
	
	
	Embryo X(80, 3);
	X.set_kangle(0.0);
	X.set_kv(5000.0); X.set_ky(1.0);
	X.set_kl(100.0, 0);X.set_kl(100.0, 1);
	X.set_ka(5.0, 0);//X.set_ka(5.0, 1);

	X.set_ka_con(5000.0, 3.0, 0);
	X.set_a0_con(7.0, 12.0, 0);
	X.set_la(1.0, 4.0, 0);
	X.set_lo(6.0, 10.0, 0.75);
	X.create_output_file("dataout.m");

	hConWnd = GetConsoleWndHandle();
	int count = 0;
	while(X.Evolve(10000) && count++ < 500){
		X.output();
		X.draw();
	}

	X.output();
	cout << "Simulation finished!!" << endl;
	cin.get();
	
	return 0;
}

int BCX_Line (HWND Wnd,int x1,int y1,int x2,int y2,int Pen,HDC DrawHDC)
{
  int a,b=0;
  HPEN hOPen;
  // penstyle, width, color
  HPEN hNPen = CreatePen(PS_SOLID, 2, Pen);
  if (!DrawHDC) DrawHDC = GetDC(Wnd), b = 1;
  hOPen = (HPEN)SelectObject(DrawHDC, hNPen);
  // starting point of line
  MoveToEx(DrawHDC, x1, y1, NULL);
  // ending point of line
  a = LineTo(DrawHDC, x2, y2);
  DeleteObject(SelectObject(DrawHDC, hOPen));
  if (b) ReleaseDC(Wnd, DrawHDC);
  return a;
}
// converts circle(centerX,centerY,radius,pen) to WinApi function
// ellipse inside box with upper left and lower right coordinates
int BCX_Circle(HWND Wnd,int X,int Y,int R,int Pen,int Fill,HDC DrawHDC)
{
  int a, b = 0;
  if (!DrawHDC) DrawHDC = GetDC(Wnd), b = 1;
  // penstyle, width, color
  HPEN   hNPen = CreatePen(PS_SOLID, 2, Pen);
  HPEN   hOPen = (HPEN)SelectObject(DrawHDC, hNPen);
  HBRUSH hOldBrush;
  HBRUSH hNewBrush;
  // if true will fill circle with pencolor
  if (Fill)
  {
    hNewBrush = CreateSolidBrush(Pen);
    hOldBrush = (HBRUSH)SelectObject(DrawHDC, hNewBrush);
  }
  else
  {
    hNewBrush = (HBRUSH)GetStockObject(NULL_BRUSH);
    hOldBrush = (HBRUSH)SelectObject(DrawHDC, hNewBrush);
  }
  a = Ellipse(DrawHDC, X-R, Y+R, X+R, Y-R);
  DeleteObject(SelectObject(DrawHDC, hOPen));
  DeleteObject(SelectObject(DrawHDC, hOldBrush));
  if (b) ReleaseDC(Wnd, DrawHDC);
  return a;
}
// the hoop ...
HWND GetConsoleWndHandle(void)
{
  HWND hConWnd;
  OSVERSIONINFO os;
  char szTempTitle[64], szClassName[128], szOriginalTitle[1024];
  os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  GetVersionEx( &os );
  // may not work on WIN9x
  if ( os.dwPlatformId == VER_PLATFORM_WIN32s ) return 0;
  GetConsoleTitle( szOriginalTitle, sizeof( szOriginalTitle ) );
  sprintf( szTempTitle,"%u - %u", GetTickCount(), GetCurrentProcessId() );
  SetConsoleTitle( szTempTitle );
  Sleep( 40 );
  // handle for NT
  hConWnd = FindWindow( NULL, szTempTitle );
  SetConsoleTitle( szOriginalTitle );
  // may not work on WIN9x
  if ( os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
  {
    hConWnd = GetWindow( hConWnd, GW_CHILD );
    if ( hConWnd == NULL )  return 0;
    GetClassName( hConWnd, szClassName, sizeof ( szClassName ) );
    while ( strcmp( szClassName, "ttyGrab" ) != 0 )
    {
      hConWnd = GetNextWindow( hConWnd, GW_HWNDNEXT );
      if ( hConWnd == NULL )  return 0;
      GetClassName( hConWnd, szClassName, sizeof( szClassName ) );
    }
  }
  return hConWnd;
}
