/*

MATT WIN GUI API TEST PROGRAM...

Author: Matthew W. Coan
Date: Augst 4, 2018

*/

#include "stdafx.h"
#include "matt_win.h"
#include <windows.h>
#include <cmath>

using namespace std;
using namespace matt_win;

#define IDC_MAIN_BUTTON 101
#define IDC_MAIN_EDIT 102
#define IDC_MAIN_CANVAS 103
#define IDC_TEXT_LABEL 104
#define IDC_MAIN_LISTBOX 105
#define IDC_MAIN_COMBOBOX 106
#define IDC_MAIN_TABCONTROL 107
#define IDC_MAIN_LABEL1 108
#define IDC_MAIN_LABEL2 109
#define IDC_MAIN_LABEL3 110
#define IDC_MAIN_IPADDRESS 111
#define IDC_MAIN_IMAGE 112

class MyApplication;

MyApplication * app = 0;

class MyCanvas : public Canvas {
public:
	MyCanvas(HWND hWnd) 
		: Canvas(hWnd, IDC_MAIN_CANVAS, 50, 100, 100, 50)
	{ 
	}
   int f(double x) {
      double A0 = height / 2;
      double A1 = 20;
      double w1 = 20;
      double l1 = 2;
      double A2 = 30;
      double w2 = 30;
      double l2 = 3;
      double A3 = 40;
      double w3 = 40;
      double l3 = 4;
      double y = A0 + A1 * sin(x * w1 - l1) + A2 * sin(x * w2 - l2) + A3 * sin(x * w3 - l3);
      return height - y;
   }
	void draw() {
		fill_rect(0,0,width,height,RGB(0,0,0));
		for(int xx = 0; xx < width; xx+=5) {
		   draw_line(xx,f(xx),xx+5,f(xx+5),RGB(0,255,0));
		}
		//draw_rect(0,0,width,height,RGB(0,0,255));
      set_bg(RGB(0,0,0));
      set_fg(RGB(0,255,0));
      set_font("Times New Roman", 15, 0);
      string text = "Matt Win...";
      int text_width = 15 * text.size();
      set_fg(RGB(255,255,255));
      draw_text((width/2)-(text_width/2),height/2,text);
	}
};

class MyApplication : public Application {
   Text * edit;
   Button * button;
   Frame * frame;
   Canvas * canvas;
   Label * text_label;
   ListBox * list_box;
   ComboBox * combo_box;
   TabControl * tab;
   Label * label1;
   Label * label2;
   Label * label3;
   IPAddress * ip;
   Image * image;

public:
   MyApplication(HINSTANCE hInst, int nShowCmd)
   { 
      app = this;
      frame = new Frame("Matt Win", hInst, nShowCmd, "Matt Win...");
   }

   void update() {
      image->update();
   }

   ~MyApplication() {
      if(edit) delete edit;
      if(button) delete button;
      if(canvas) delete canvas;
      if(text_label) delete text_label;
      if(list_box) delete list_box;
      if(combo_box) delete combo_box;
      if(tab) delete tab;
      if(label1) delete label1;
      if(label2) delete label2;
      if(label3) delete label3;
      if(ip) delete ip;
      if(image) delete image;
      delete frame;
   }

   void on_create(HWND hWnd) {
      int pad = 10;
      edit = new Text(hWnd, "Matt Win...", IDC_MAIN_EDIT, 15+50, 100, 100, 50-15);
      button = new Button(hWnd, "Click Me", IDC_MAIN_BUTTON, 50, 250, 200, 50);
      canvas = new MyCanvas(hWnd);
      text_label = new Label(hWnd, "Text:", IDC_TEXT_LABEL, 50, 100, 100, 50);
      list_box = new ListBox(hWnd, IDC_MAIN_LISTBOX, 50, 100, 100, 200);
      list_box->add("List Item 1");
      list_box->add("List Item 2");
      list_box->add("List Item 3");
      combo_box = new ComboBox(hWnd, IDC_MAIN_COMBOBOX, 0, 0, 100, 100);
      combo_box->add("Item 1");
      combo_box->add("Item 2");
      combo_box->add("Item 3");
      combo_box->set_selection(0);
      tab = new TabControl(hWnd, IDC_MAIN_TABCONTROL, 15+50, 100, 100, 50-15);
      tab->add(0, "First");
      tab->add(1, "Second");
      tab->add(2, "Third");
      tab->set_current_index(1);
      label1 = new Label(hWnd, "First", IDC_MAIN_LABEL1, 0,0,0,0);
      label2 = new Label(hWnd, "Second", IDC_MAIN_LABEL2, 0,0,0,0);
      label3 = new Label(hWnd, "Third", IDC_MAIN_LABEL3, 0,0,0,0);
      label1->hide();
      label2->show();
      label3->hide();
      ip = new IPAddress(hWnd, IDC_MAIN_IPADDRESS, 0,0,0,0);
      image = new Image(hWnd, "image.bmp", IDC_MAIN_IMAGE, 0,0,100,56);
      image->hide();
   }

   void resize(int w, int h, HWND hWnd) {
      int pad = 10;
      int label_height = 20;
      int label_width = 50;
      if(edit) { 
         edit->resize(w/2-pad,h/2-pad-pad+pad/2-label_height-100);
         edit->move(pad,pad+label_height+100);
      }
      if(button) { 
         button->resize(((w-pad-pad)/2)-pad+pad,h/2-pad-pad/2);
         button->move(pad, (h/2+pad-pad/2));
      }
      if(tab) { 
         tab->resize(((w-pad-pad)/2)-pad,h/2-pad-pad+pad/2);
         tab->move(((w-pad-pad)/2)+pad+pad, (h/2+pad-pad/2));
      }
      if(label1) { 
         label1->resize(50,20);
         label1->move(((w-pad-pad)/2)+pad+pad+25, (h/2+pad-pad/2)+100);
      }
      if(label2) { 
         label2->resize(50,20);
         label2->move(((w-pad-pad)/2)+pad+pad+25, (h/2+pad-pad/2)+100);
      }
      if(label3) { 
         label3->resize(50,20);
         label3->move(((w-pad-pad)/2)+pad+pad+25, (h/2+pad-pad/2)+100);
      }
      if(canvas) { 
         canvas->resize(w/2-pad-pad,h/2-pad-pad+pad/2);
         canvas->move(w/2+pad,pad);
      }
      if(text_label) { 
         text_label->resize(label_width,label_height);
         text_label->move(pad,pad);
      }
      if(list_box) {
         list_box->resize(w/2-pad,50);
         list_box->move(pad,pad+label_height);
      }
      if(combo_box) {
         combo_box->resize(w/2-pad,100);
         combo_box->move(pad,pad+label_height+50);
      }
      if(ip) {
         ip->resize(100,20);
         ip->move(((w-pad-pad)/2)+pad+pad+25, (h/2+pad-pad/2)+140);
      }
      if(image) {
         image->resize(100,56);
         image->move(((w-pad-pad)/2)+pad+pad+25, (h/2+pad-pad/2)+120);
      }
   }

   void on_command(WPARAM wParam, LPARAM lParam, HWND hWnd) {
      switch(LOWORD(wParam)) {
      case IDC_MAIN_BUTTON: {
         if(edit) {
            string text = edit->get_text();
            MessageBox(hWnd, 
            text.c_str(), 
            "Information", 
            MB_OK);
         }
      }
      break;
/*
      case IDC_MAIN_LISTBOX: {
         if(HIWORD(wParam) == LBN_SELCHANGE) {
            string selection = list_box->get_selection();
            MessageBox(hWnd,
            selection.c_str(),
            "Change Selection",
            MB_OK);
         }
      }
      break;
      case IDC_MAIN_COMBOBOX: {
         if(HIWORD(wParam) == CBN_SELCHANGE) {
            string selection = combo_box->get_selection();
            MessageBox(hWnd,
            selection.c_str(),
            "Change Selection",
            MB_OK);
         }
      }
      break;
*/
      }
   }

   void on_notify(WPARAM wParam, LPARAM lParam, HWND hWnd) {
      switch(LOWORD(wParam)) {
      case IDC_MAIN_TABCONTROL: {
         if(((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
            int index = tab->get_current_index();
            switch(index) {
            case 0:
               label1->show();
               label2->hide();
               label3->hide();
               ip->hide();
               image->show();
            break;

            case 1:
               label1->hide();
               label2->show();
               label3->hide();
               ip->show();
               image->hide();
            break;

            case 2:
               label1->hide();
               label2->hide();
               label3->show();
               ip->hide();
               image->hide();
            break;
            }
         }
      }
      break;
      }
   }

   void on_quit() {
      if(edit) delete edit;
      edit = 0;
      if(button) delete button;
      button = 0;
      if(canvas) delete canvas;
      canvas = 0;
      if(text_label) delete text_label;
      text_label = 0;
      if(list_box) delete list_box;
      list_box = 0;
      if(combo_box) delete combo_box;
      combo_box = 0;
      if(label1) delete label1;
      label1 = 0;
      if(label2) delete label2;
      label2 = 0;
      if(label3) delete label3;
      label3 = 0;
      if(tab) delete tab;
      tab = 0;
      if(ip) delete ip;
      ip = 0;
      if(image) delete image;
      image = 0;
      PostQuitMessage(0);
   }

   void paint(HWND hWnd) {
      if(canvas) canvas->paint(hWnd);
   }
};

LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd)
{
   try {
      MyApplication myApp(hInst, nShowCmd);
      myApp.run();
   }
   catch(...) {
      MessageBox(NULL, 
      "Software Exception...",
      "Software Exception...", 
      MB_OK);
   }
	return 0;
}

LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	switch(msg)
	{
		case WM_CREATE:
		{
         if(app) {
            app->on_create(hWnd);
		   }
		}
		break;

		case WM_COMMAND:
		{
         if(app) {
            app->on_command(wParam,lParam,hWnd);
		   }
		}
		break;

      case WM_NOTIFY:
      {
         if(app) {
            app->on_notify(wParam,lParam,hWnd);
         }
      }
      break;

		case WM_DESTROY:
		{
          if(app) {
             app->on_quit();
          }
			 return 0;
		}

		case WM_SIZE:
		{
			int w = LOWORD(lParam);
			int h = HIWORD(lParam);
			if(app) {
		      app->resize(w, h, hWnd);
            app->paint(hWnd);
		   }
		}
		break;

		case WM_PAINT:
		{
		   if(app) {
            DefWindowProc(hWnd,msg,wParam,lParam);
		      app->paint(hWnd);
            return 0;
		   }
		}
		break;

		case WM_LBUTTONDOWN:
		{
		   if(app) {
            int xPos = LOWORD(lParam);
            int yPos = HIWORD(lParam);
		      app->paint(hWnd);
 		   }
		}
      break;

		case WM_RBUTTONDOWN:
		{
		   if(app) {
            int xPos = LOWORD(lParam);
            int yPos = HIWORD(lParam);
		      app->paint(hWnd);
 		   }
		}
		break;
	}

   return DefWindowProc(hWnd,msg,wParam,lParam);
}
