using System;
using System.Collections.Generic;
using System.Text;

using System.Windows.Forms;
using System.Drawing;


namespace Chart
{
    /// <summary>
    /// Logarithm coordinator
    /// </summary>
    public class LogarithmCoordinator : SimpleCoordinator
    {

        #region Fields
        private bool logX = false;
        private bool logY = false;
        #endregion

        #region Constructors
        public LogarithmCoordinator(ChartPerformer performer)
            : base(5, 5, performer)
        {

        }

        #endregion

        #region ICoordPainter Members


        public override void DrawCoord(Graphics g, double[,] dSize, int[] size)
        {
            calculateScale(dSize);
            if (logX)
            {
                drawCoordLog(g, size, dSize, 0);
            }
            else
            {
                DrawCoord(g, size, dSize, 0);
            }
            if (logY)
            {
                drawCoordLog(g, size, dSize, 1);
            }
            else
            {
                DrawCoord(g, size, dSize, 1);
            }

        }

        public override void DrawCoord(Graphics g, int[,] insets, double[,] dSize, int[] size)
        {
            calculateScale(dSize);
            Pen pen = new Pen(Color.Black);
            g.DrawRectangle(pen, insets[0, 0] - 1, insets[0, 1] - 1, size[0] + 2, size[1] + 2);
            if (logX)
            {
                drawTextXLog(g, insets, dSize, size);
            }
            else
            {
                drawTextX(g, insets, dSize, size);
            }
            if (logY)
            {
                drawTextYLog(g, insets, dSize, size);
            }
            else
            {
                drawTextY(g, insets, dSize, size);
            }
        }

        #endregion

        #region Specific Members


        public bool LogX
        {
            set
            {
                logX = value;
            }
        }

        public bool LogY
        {
            set
            {
                logY = value;
            }
        }

        protected void drawCoordLog(Graphics g, int[] size, double[,] dSize, int i)
        {
            Pen pen = new Pen(Color.Black);
            int min = (int)Math.Floor(dSize[0, i]);
            int max = (int)Math.Ceiling(dSize[1, i]);
            for (int j = min; j <= max; j++)
            {
                for (int k = 0; k < 10; k++)
                {
                    double c = j + Math.Log10(k);
                    if ((c < dSize[0, i]) | (c > dSize[1, i]))
                    {
                        continue;
                    }
                    if (i == 0)
                    {
                        performer.Transform(c, 0.0, p);
                        g.DrawLine(pen, p[0], 0, p[0], size[1]);
                    }
                    else
                    {
                        performer.Transform(0, c, p);
                        g.DrawLine(pen, 0, p[1], size[0], p[1]);
                    }
                }
            }
        }

        protected void drawTextXLog(Graphics g, int[,] insets, double[,] dSize, int[] size)
        {
            Font font = new Font("Times", 13);
            Font fontPow = new Font("Times", 6);
            Brush brush = new SolidBrush(Color.Black);
            int h = font.Height + insets[0, 1] + size[1];
            Pen pen = new Pen(Color.Black);
            int min = (int)Math.Floor(dSize[0, 0]);
            int max = (int)Math.Ceiling(dSize[1, 0]);
            for (int j = min; j <= max; j++)
            {
                string ss = "";
                for (int k = 0; k < j; k++)
                {
                    ss = ss + "0";
                }
                string sp = "";
                for (int k = 0; k > j + 1; k--)
                {
                    sp = sp + "0";
                }
                if (j < 0)
                {
                    sp = "0," + sp;
                }
                for (int k = 0; k < 10; k++)
                {
                    double c = j + Math.Log10(k);
                    if ((c < dSize[0, 0]) | (c > dSize[1, 0]))
                    {
                        continue;
                    }
                    performer.Transform(c, 0.0, p);
                    string s = k + "";
                    int w = (int)g.MeasureString(s, font).Width;
                    int x = p[0] + insets[0, 0] - w / 2;
                    g.DrawString(sp + k + ss, font, brush, x, h);
                    /*if ((k == 0) & (j != 0))
					{
                        g.DrawString(sp + k + ss, fontPow, brush, x + w, h - font.Height + fontPow.Height);
                    }*/
                                }
            }
        }

        protected void drawTextYLog(Graphics g, int[,] insets, double[,] dSize, int[] size)
        {
            Font font = new Font("Times", 13);
            Font fontPow = new Font("Times", 6);
            Brush brush = new SolidBrush(Color.Black);
            int h = font.Height + insets[0, 1] + size[1];
            Pen pen = new Pen(Color.Black);
            int min = (int)Math.Floor(dSize[0, 1]);
            int max = (int)Math.Ceiling(dSize[1, 1]);
            for (int j = min; j <= max; j++)
            {
                string ss = "";
                for (int k = 0; k < j; k++)
                {
                    ss = ss + "0";
                }
                string sp = "";
                for (int k = 0; k > j; k--)
                {
                    sp = sp + "0";
                }
                if (sp.Length > 0)
                {
                    sp = "0," + sp;
                }
                for (int k = 0; k < 9; k++)
                {
                    double c = j + Math.Log10(k);
                    if ((c < dSize[0, 1]) | (c > dSize[1, 1]))
                    {
                        continue;
                    }
                    performer.Transform(0.0, c, p);
                    string s = k + "";
                    int w = (int)g.MeasureString("13", font).Width;
                    int y = p[1] + insets[0, 1];
                    g.DrawString(s, font, brush, insets[0, 0] - (int)(double)(1.2 * w), y);
                    if ((k == 0) & (j != 0))
                    {
                        w = (int)g.MeasureString("7", font).Width;
                        g.DrawString(sp + k + ss, fontPow, brush, insets[0, 0] - (int)(double)(1.2 * w), y - font.Height + fontPow.Height);
                    }
                }
            }
        }


        #endregion
    }
}
