using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

public partial class GUIForm : Form
{
    private Counter c1,c2,c3;
    
    public GUIForm()
    {
        InitializeComponent();
    }

    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        if (sender == checkBox1)
            c1.toggle();
        else if (sender == checkBox2)
            c2.toggle();
        else if (sender == checkBox3)
            c3.toggle();
    }



    private void GUIForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        System.Environment.Exit(System.Environment.ExitCode);
    }

    private void GUIForm_Load(object sender, EventArgs e)
    {
        c1 = new Counter(label1);
        Thread thread1 = new Thread(new ThreadStart(c1.count));
        thread1.Name = "Thread 1";
        thread1.Start();

        c2 = new Counter(label2);
        Thread thread2 = new Thread(new ThreadStart(c2.count));
        thread2.Name = "Thread 2";
        thread2.Start();

        c3 = new Counter(label3);
        Thread thread3 = new Thread(new ThreadStart(c3.count));
        thread3.Name = "Thread 3";
        thread3.Start();
    }
}

class Counter
{
    private bool suspended;
    private Label output;
    private string threadName;
    private int currentCount=0;

    public Counter(Label l)
    {
        output = l;
    }

    private delegate void DisplayDelegate(int count);

    private void DisplayCount(int count)
    {
        output.Text=threadName+ ": " + count;
    }

    private void displayCount(int c)
    {
        output.Text = threadName + "  " + c;
    }

    public void count()
    {
        threadName = Thread.CurrentThread.Name;

        while (true)
        {
            Thread.Sleep(300);

            lock(this)
            {
                if (suspended)
                {
                    Monitor.Wait(this);
                }
            }
            currentCount++;

            output.Invoke(new DisplayDelegate(DisplayCount),new object[] {currentCount});
        }
    }


    public void toggle()
    {
        suspended = !suspended;

        output.BackColor = suspended ? Color.Red : Color.LightCyan;

        lock (this)
        {
            if (!suspended)
                Monitor.Pulse(this);
        }
    }
}