# include  <iostream>  
# include  <algorithm>  
# include  <graphics.h> 		 
# include  <conio.h>  
# include  <unordered_map>  
# include  <Windows.h>  
# include  "layout/LayoutSystem.h"  
# define  DEFAULT_PANELS_LAYOUT_PADDING  0.03  
# define  DEFAULT_PANELS_LAYOUT_CELL_SIZE  0.01  
using  namespace  boxing:: layout; 
int  SCRW =  640 ; 
int  SCRH =  480 ; 
int  main ( ) 
{ 
    HWND hConsole =  GetConsoleWindow ( ) ; 
	initgraph ( SCRW,  SCRH) ; 	
    
    SetWindowPos ( hConsole,  HWND_TOP,  0 ,  0 ,  0 ,  0 ,  SWP_NOSIZE |  SWP_NOMOVE |  SWP_SHOWWINDOW) ; 
    auto  getX =  [ ] ( float  x1) -> int  { return  ( int ) ( ( x1 +  1.0 )  /  2.0  *  SCRW) ;  } ; 
    auto  getY =  [ ] ( float  y1) -> int  { return  ( int ) ( abs ( y1 -  1.0 )  /  2.0  *  SCRH) ;  } ; 
    auto  getW =  [ ] ( float  w) -> int  { return   w /  2.0  *  SCRW;  } ; 
    auto  getH =  [ ] ( float  h) -> int  { return   h /  2.0  *  SCRH;  } ; 
    auto  drawRectText =  [ & ] ( float  x, float  y,  LPCTSTR str, float  w, float  h,  COLORREF color)  { 
        int  new_x =  getX ( x) ; 
        int  new_y =  getY ( y) ; 
        int  new_w =  getW ( w) ; 
        int  new_h =  getH ( h) ; 
        setfillcolor (  color) ; 
        fillrectangle (  new_x-  new_w/ 2 ,  new_y-  new_h/ 2 ,  new_x +  new_w /  2 ,  new_y +  new_h /  2  ) ; 
        int  textW =  textwidth ( str) ; 
        int  textH =  textheight ( str) ; 
        setfillcolor ( RGB ( 255 , 255 , 255 ) ) ; 
        outtextxy ( new_x -  textW /  2.0 ,  new_y -  textH /  2.0 , str ) ; 
    } ; 
    auto  drawRectCharText =  [ & ] ( float  x,  float  y,  char *  str,  float  w,  float  h,  COLORREF color)  { 
        int  num =  MultiByteToWideChar ( 0 ,  0 ,  str,  - 1 ,  NULL ,  0 ) ; 
        wchar_t *  wide =  new  wchar_t [ num] ; 
        MultiByteToWideChar ( 0 ,  0 ,  str,  - 1 ,  wide,  num) ; 
        drawRectText ( x,  y,  wide,  w,  h,  color) ; 
        free ( wide) ; 
    } ; 
    auto  drawRectInt =  [ & ] ( float  x,  float  y,  int  text,  float  w,  float  h,  COLORREF color)  { 
        char  str[ 50 ]  =  {  0  } ; 
        sprintf ( str,  "%d" ,  text) ; 
        drawRectCharText ( x,  y,  str,  w,  h,  color) ; 
    } ; 
    auto  drawRectFloat =  [ & ] ( float  x,  float  y,  float  text,  float  w,  float  h,  COLORREF color)  { 
        char  str[ 50 ]  =  {  0  } ; 
        sprintf ( str,  "%f" ,  text) ; 
        drawRectCharText ( x,  y,  str,  w,  h,  color) ; 
    } ; 
    auto  drawLine =  [ & ] ( float  start_x,  float  start_y,  float  end_x,  float  end_y,  COLORREF color)  { 
        setlinecolor ( color) ; 
        line ( getX ( start_x) ,  getY ( start_y) ,  getX ( end_x) ,  getY ( end_y) ) ; 
    } ; 
    srand ( time ( NULL ) ) ; 
    bool  loop =  false ; 
    for  ( int  count =  100 ;  count > 0 ;  count-- )  { 
        cleardevice ( ) ; 
        float  aspect =  1.0  /  0.618 ;  
        int  col =  min ( count,  ( int ) std:: ceil ( sqrt ( count *  aspect) ) ) ; 
        int  row =  std:: ceil ( ( float ) count /  col) ; 
        std:: unordered_map< int , float >  widthInCol; 
        std:: unordered_map< int , float >  heightInRow; 
        int  rowMin =  row /  2  -  ( count -  1 )  /  col; 
        int  rowMax =  row /  2  -  ( ( int ) 0 )  /  col; 
        int  colMax =  ( col -  1 )  %  col -  col /  2 ; 
        int  colMin =  ( ( int ) 0 )  %  col -  col /  2 ; 
        float  col_centre =  ( colMax +  colMin)  /  2.0 ; 
        float  row_centre =  ( rowMax +  rowMin)  /  2.0 ; 
        drawLine ( - 1 , 0 , 1 , 0 ,  RGB ( 0  , 255 ,  0 ) ) ; 
        drawLine ( 0 ,  1 ,  0 ,  - 1 ,  RGB ( 0 ,  255 ,  0 ) ) ; 
        char  str[ 100 ]  =  {  0  } ; 
        sprintf ( str,  "r:%d,c:%d" ,  row, col) ; 
        drawRectCharText ( - 0.9 , 0.95 ,  str,  0.2 ,  0.1 ,  RGB ( 255 ,  250 ,  0 ) ) ; 
        printf ( " count: %d,colMax: %d,colMin:%d,rowMax:%d ,rowMin:%d, tt:%f,row_centre:%f\n" ,  count,  colMax,  colMin,  rowMax,  rowMin,  col_centre,  row_centre) ; 
        
        LayoutSystem:: Ptr layoutSystem =  LayoutSystem :: NEW ( PAGE_LAYOUT_PLANE,  DEFAULT_PANELS_LAYOUT_CENTRE,  DEFAULT_PANEL_POSITION) ; 
        for  ( int  index =  0 ;  index <  count;  index++ )  { 
         
            float  randW =  max ( 0.1 , rand ( )  /  double ( RAND_MAX) / 5.0 ) ; 
            float  randH =  max ( 0.1 ,  rand ( )  /  double ( RAND_MAX)  /  5.0 ) ; 
            layoutSystem-> addLayoutElement ( index,  randW,  randH) ; 
     
            
        } 
        layoutSystem-> startCompositor ( false ) ; 
        auto  layout_results =  layoutSystem-> getLayoutResults ( ) ; 
        for  ( auto  [ k,  v]  :  layout_results)  { 
            int  color =  ( float ) k /  count *  255 ; 
            
            auto  element =  layoutSystem-> getLayoutElement ( k) ; 
            drawRectInt ( v-> position. x,  v-> position. y ,  k,  element-> mWidth,  element-> mHeight,  RGB ( 255 ,  color,  0 ) ) ; 
        } 
        
        
        
        
        
        
        Sleep ( 1000 ) ; 
        if  ( ! loop) 
            break ; 
    } 
	_getch ( ) ; 				
	closegraph ( ) ; 			
	return  0 ; 
}