using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;

namespace GrowingDisks {

    public class Disk {
        const int MAXRADIUS = 100, MINRADIUS = 10, 
                  MAXFULLGROWNAGE = 5000, MINFULLGROWNAGE = 1000,
                  TICKINTERVAL = 50;
        private int radius;
        private int maxRadius;
        private Point center;
        private int age, ageWhenFullGrown;
        private Brush brush;
        private Timer timer;
        private Form parent;
        static Random rnd = new Random();

        public void ageBy(int span) {
            age += span;
            radius = (int)(MINRADIUS + 
                           age/(float)ageWhenFullGrown * (maxRadius-MINRADIUS));
        }
        public static Disk randomDisk(Point center, Form parent) {
            Disk result = new Disk();
            result.radius = MINRADIUS;
            result.maxRadius = result.radius + rnd.Next(MAXRADIUS - result.radius + 1);
            result.age = 0;
            result.ageWhenFullGrown = 
                MINFULLGROWNAGE + rnd.Next(MAXFULLGROWNAGE-MINFULLGROWNAGE+1);
            result.center = center;
            Color randomColor = ColorTranslator.FromWin32(rnd.Next(0xFFFFFF));
            result.brush = new SolidBrush(randomColor);
            result.parent = parent;
            result.timer = new Timer();
            result.timer.Interval = TICKINTERVAL;
            result.timer.Tick += result.onTimer;
            result.timer.Start();
            result.draw(parent.CreateGraphics());
            return result;
        }
        public void draw(Graphics g) {
            Rectangle rect = new Rectangle(center.X-radius,center.Y-radius,
                                        2*radius, 2*radius);
            g.FillEllipse(brush, rect);
            g.DrawEllipse(new Pen(Color.Black), rect);
        }
        public void onTimer(Object source, EventArgs e) {
            if (age < ageWhenFullGrown) ageBy(TICKINTERVAL);
            else {
                timer.Stop();
                timer = null;
            }
            draw(parent.CreateGraphics());
        }
    }

    partial class GrowingDisksForm: Form {
       
        LinkedList<Disk> disks = new LinkedList<Disk>();

        partial void onPaint(Graphics g) {
            if (disks.Count == 0) g.DrawString(
                "Click anywhere. Each mouse click will produce a growing disk.", 
                Font, Brushes.Red, 10, 10);
            else foreach (Disk d in disks) d.draw(g);
       }

        partial void onClick(MouseEventArgs me) {
            Disk newDisk = Disk.randomDisk(me.Location, this);
            disks.AddLast(newDisk);
            Refresh();
        }

   }

}