using dotnetCHARTING;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Configuration;
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Text;
using System.Text.Encodings.Web;

namespace dotnetCHARTING.NET10
{
    public static class DNC
    {
        public static IConfiguration Configuration;
        public static IWebHostEnvironment HostingEnvironment;
        public static IHttpContextAccessor HttpContextAccessor;
        public class ChartBuilder : IHtmlContent
        {
            public void WriteTo(TextWriter writer, HtmlEncoder encoder)
            {
                if (!string.IsNullOrEmpty(cTitle))
                    chartObj.Title = cTitle;
                if (!string.IsNullOrEmpty(_fileName))
                    chartObj.FileName = _fileName;               
                if (sc != null && sc.Count > 0)
                {
                    chartObj.SeriesCollection.Add(sc);
                }
                string strDiv = "";
                if (string.IsNullOrEmpty(this.chartObj.ID))
                    this.chartObj.ID = "chart_" + DateTime.Now.Ticks;
                if (chartObj.JS.Enabled)
                {                   
                    string hcCode = chartObj.GetChartJS();
                    if (!string.IsNullOrEmpty(hcCode))
                    {                    
                        var builder3 = new TagBuilder("script");
                        builder3.MergeAttribute("type", "text/javascript");
                        builder3.InnerHtml.AppendHtml(hcCode);
                        builder3.RenderEndTag();                       
                        var div = new TagBuilder("div");
                        div.MergeAttribute("id", $"container_{chartObj.ID}{chartObj.JS.ControlID}");
                        div.RenderEndTag();
                        writer.Write(chartObj.JS.ScriptReference);
                        builder3.WriteTo(writer, HtmlEncoder.Default);
                        div.WriteTo(writer, HtmlEncoder.Default);
                    }
                    else
                    {
                        var innerHtml = new HtmlContentBuilder();
                        innerHtml.Append(chartObj.ErrorMessage);
                        innerHtml.WriteTo(writer, HtmlEncoder.Default);
                    }
                }
                else if (!chartObj.UseFile)
                {
                    System.IO.MemoryStream chartStream = chartObj.GetChartStream();
                    if (chartStream != null)
                    {
                        var base64 = Convert.ToBase64String(chartStream.ToArray());
                        var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
                        strDiv = ByteArrayToString(chartStream.ToArray());
                        var builder = new TagBuilder("img");
                        // Add attributes
                        builder.MergeAttribute("src", $"{imgSrc}");
                        builder.MergeAttribute("alt", "chart");
                        builder.WriteTo(writer, HtmlEncoder.Default);
                    }
                    else
                    {
                        var innerHtml = new HtmlContentBuilder();
                        innerHtml.Append(chartObj.ErrorMessage);
                        innerHtml.WriteTo(writer, HtmlEncoder.Default);
                    }
                }               
                else
                {
                    string imageURL = chartObj.FileManager.SaveImage();
                    if (!string.IsNullOrEmpty(imageURL))
                    {
                        if (chartObj.ImageFormat == dotnetCHARTING.ImageFormat.Pdf)
                        {
                            var builder1 = new TagBuilder("script");
                            builder1.MergeAttribute("type", "text/javascript");
                            string embed = "rdnc_WriteEmbed.js";
                            builder1.MergeAttribute("src", $"{chartObj.TempDirectory}/{embed}");
                            builder1.RenderEndTag();
                            builder1.WriteTo(writer, HtmlEncoder.Default);
                            var builder3 = new TagBuilder("script");
                            builder3.MergeAttribute("type", "text/javascript");
                            string str3 = $"dnc_WriteEmbed('<embed type=\"application/pdf\" Src=\"{imageURL}\" Width=\"600px\" Height=\"400px\"/>');";
                            builder3.InnerHtml.AppendHtml(str3);
                            builder3.RenderEndTag();
                            var div = new TagBuilder("div");
                            div.MergeAttribute("id", $"container_{chartObj.ID}");
                            div.RenderEndTag();
                            builder3.WriteTo(writer, HtmlEncoder.Default);
                            div.WriteTo(writer, HtmlEncoder.Default);
                        }
                        else if(chartObj.ImageFormat == dotnetCHARTING.ImageFormat.Svg)
                        {
                            var builder1 = new TagBuilder("iframe");
                            builder1.MergeAttribute("Width", chartObj.Width.ToString()+"px");
                            builder1.MergeAttribute("Height", chartObj.Height.ToString() + "px");                            
                            builder1.MergeAttribute("src", imageURL);
                            builder1.RenderEndTag();                          
                            var div = new TagBuilder("div");
                            div.MergeAttribute("id", $"container_{chartObj.ID}");
                            div.MergeAttribute("style", "border - width:0px;");
                            div.RenderEndTag();
                            builder1.WriteTo(writer, HtmlEncoder.Default);
                            div.WriteTo(writer, HtmlEncoder.Default);
                        }
                        else
                        {
                            var builder = new TagBuilder("img");
                            builder.MergeAttribute("src", imageURL);
                            builder.MergeAttribute("alt", "chart");
                            if (!string.IsNullOrEmpty(chartObj.ImageMapName) && !string.IsNullOrEmpty(chartObj.ImageMapText))
                            {
                                builder.MergeAttribute("usemap", chartObj.ImageMapName);
                                builder.WriteTo(writer, HtmlEncoder.Default);
                                var builder2 = new TagBuilder("span");
                                builder2.InnerHtml.AppendHtml(chartObj.ImageMapText);
                                builder2.WriteTo(writer, HtmlEncoder.Default);
                            }
                            else
                                builder.WriteTo(writer, HtmlEncoder.Default);
                        }
                    }
                    else
                    {
                        strDiv = chartObj.ErrorMessage;
                        var innerHtml = new HtmlContentBuilder();
                        innerHtml.Append(strDiv);
                        innerHtml.WriteTo(writer, HtmlEncoder.Default);
                    }
                }
            }
            public static string ByteArrayToString(byte[] ba)
            {
                StringBuilder hex = new StringBuilder(ba.Length * 2);
                foreach (byte b in ba)
                    hex.AppendFormat("{0:x2}", b);
                return hex.ToString();
            }
            IHtmlHelper myhelper;
            dotnetCHARTING.Chart chartObj = null;
            string cTitle = "";
            DataEngine de = new DataEngine();
            SeriesCollection sc = null;
            string _fileName = "";
            public ChartBuilder(IHtmlHelper helper, HttpContext httpContext)
            {
                myhelper = helper;
               // chartObj = new dotnetCHARTING.Chart(DNC.HttpContextAccessor, DNC.HostingEnvironment.WebRootPath);
                chartObj = new dotnetCHARTING.Chart(httpContext, DNC.HostingEnvironment.WebRootPath);
                //chartObj = new dotnetCHARTING.Chart(null, DNC.HostingEnvironment.WebRootPath);
            }
            //public ChartBuilder(IHtmlHelper helper, HttpContext httpContext)
            //{
            //    myhelper = helper;
            //    chartObj = new dotnetCHARTING.Chart(httpContext, DNC.HostingEnvironment.WebRootPath);
            //}
            public ChartBuilder ObjectChart(Object objectChart)
            {
                chartObj.ObjectChart = objectChart;
                return this;
            }
            public ChartBuilder Zoomer(bool enabled)
            {
                chartObj.Zoomer.Enabled = enabled;
                return this;
            }
            public ChartBuilder ID(string chartId)
            {
                chartObj.ID = chartId;
                return this;
            }
            public ChartBuilder ShadingEffectMode(ShadingEffectMode shadingEffectMode)
            {
                chartObj.ShadingEffectMode = shadingEffectMode;
                return this;
            }
            public ChartBuilder ShadingEffect(bool shadingEffect)
            {
                chartObj.ShadingEffect = shadingEffect;
                return this;
            }
            public ChartBuilder AlternateText(string alternateText)
            {
                chartObj.AlternateText = alternateText;
                return this;
            }
            public ChartBuilder ControlID(string controlID)
            {
                chartObj.JS.ControlID = controlID;
                return this;
            }
            public ChartBuilder Annotation(Annotation annotation)
            {
                chartObj.Annotations.Add(annotation);
                return this;
            }
            public ChartBuilder Annotations(AnnotationCollection annotations)
            {
                chartObj.Annotations.Add(annotations);
                return this;
            }
            public ChartBuilder AutoNameLabels(bool autoNameLabels)
            {
                chartObj.AutoNameLabels = autoNameLabels;
                return this;
            }
            public ChartBuilder Axes(Axis axis)
            {
                chartObj.AxisCollection.Add(axis);
                return this;
            }
            public ChartBuilder Background(Background background)
            {
                chartObj.Background = background;
                return this;
            }
            public ChartBuilder BubbleCenterStack(bool bubbleCenterStack)
            {
                chartObj.BubbleCenterStack = bubbleCenterStack;
                return this;
            }
            public ChartBuilder BubbleStackShadeAsOne(bool bubbleStackShadeAsOne)
            {
                chartObj.BubbleStackShadeAsOne = bubbleStackShadeAsOne;
                return this;
            }
            public ChartBuilder Box(Annotation box)
            {
                chartObj.Box = box;
                return this;
            }
            public ChartBuilder CacheDuration(int cacheDuration)
            {
                chartObj.CacheDuration = cacheDuration;
                return this;
            }
            public ChartBuilder CalculateEmptyElement(bool calculateEmptyElement)
            {
                chartObj.CalculateEmptyElement = calculateEmptyElement;
                return this;
            }          
            public ChartBuilder ChartArea(ChartArea chartArea)
            {
                chartObj.ChartArea = chartArea;              
                return this;
            }
            public ChartBuilder ChartArea(ChartArea chartArea, bool clearBackground)
            {
                chartObj.ChartArea = chartArea;
                if (clearBackground)
                    chartObj.ChartArea.ClearColors();
                return this;
            }
            public ChartBuilder ChartAreaLayoutMode(ChartAreaLayoutMode chartAreaLayoutMode)
            {
                chartObj.ChartAreaLayout.Mode = chartAreaLayoutMode;
                return this;
            }
            public ChartBuilder ChartAreaSpacing(int chartAreaSpacing)
            {
                chartObj.ChartAreaSpacing = chartAreaSpacing;
                return this;
            }
            public ChartBuilder CleanupMinimumAge(int cleanupMinimumAge)
            {
                chartObj.CleanupMinimumAge = cleanupMinimumAge;
                return this;
            }
            public ChartBuilder CleanupPeriod(int cleanupPeriod)
            {
                chartObj.CleanupPeriod = cleanupPeriod;
                return this;
            }
            public ChartBuilder ClipGauges(bool clipGauges)
            {
                chartObj.ClipGauges = clipGauges;
                return this;
            }
            public ChartBuilder DatabaseCultureName(string databaseCultureName)
            {
                chartObj.DatabaseCultureName = databaseCultureName;
                return this;
            }
            public ChartBuilder DataGridCustomAttributes(string dataGridCustomAttributes)
            {
                chartObj.DataGridCustomAttributes = dataGridCustomAttributes;
                return this;
            }
            public ChartBuilder DataGridFormatString(string dataGridFormatString)
            {
                chartObj.DataGridFormatString = dataGridFormatString;
                return this;
            }
            public ChartBuilder DataGridSeriesHeader(string dataGridSeriesHeader)
            {
                chartObj.DataGridSeriesHeader = dataGridSeriesHeader;
                return this;
            }
            public ChartBuilder DataGridTranspose(bool dataGridTranspose)
            {
                chartObj.DataGridTranspose = dataGridTranspose;
                return this;
            }
            public ChartBuilder DateGroupingCalculation(Calculation dateGroupingCalculation)
            {
                chartObj.DateGroupingCalculation = dateGroupingCalculation;
                return this;
            }
            public ChartBuilder DateGroupingSort(bool dateGroupingSort)
            {
                chartObj.DateGroupingSort = dateGroupingSort;
                return this;
            }
            public ChartBuilder Debug(bool debug)
            {
                chartObj.Debug = debug;
                return this;
            }
            public ChartBuilder DefaultAxis(Axis defaultAxis)
            {
                chartObj.DefaultAxis = defaultAxis;
                return this;
            }
            public ChartBuilder DefaultBox(Box defaultBox)
            {
                //chartObj.DefaultBox. = defaultBox;
                return this;
            }
            public ChartBuilder DefaultChartArea(Box defaultBox)
            {
                //chartObj.DefaultChartArea = defaultBox;
                return this;
            }
            public ChartBuilder DefaultCultureName(string defaultCultureName)
            {
                chartObj.DefaultCultureName = defaultCultureName;
                return this;
            }
            public ChartBuilder DefaultElement(Element defaultElement)
            {
                chartObj.DefaultElement = defaultElement;
                return this;
            }
            public ChartBuilder DefaultFormatString(string defaultFormatString)
            {
                chartObj.DefaultFormatString = defaultFormatString;
                return this;
            }
            public ChartBuilder DefaultSeries(Series defaultSeries)
            {
                chartObj.DefaultSeries = defaultSeries;
                return this;
            }
            public ChartBuilder DefaultShadow(Shadow defaultShadow)
            {
                chartObj.DefaultShadow = defaultShadow;
                return this;
            }
            public ChartBuilder Use3D(bool use3D)
            {
                chartObj.Use3D = use3D;
                return this;
            }
            public ChartBuilder Depth(int depth)
            {
                chartObj.Depth = depth;
                return this;
            }
            public ChartBuilder DisableBrowserCache(bool disableBrowserCache)
            {
                chartObj.DisableBrowserCache = disableBrowserCache;
                return this;
            }
            public ChartBuilder DonutHoleSize(double donutHoleSize)
            {
                chartObj.DonutHoleSize = donutHoleSize;
                return this;
            }
            public ChartBuilder DrillDownChain(string drillDownChain)
            {
                chartObj.DrillDownChain = drillDownChain;
                return this;
            }
            public ChartBuilder DrillDownIntoSeries(bool drillDownIntoSeries)
            {
                chartObj.DrillDownIntoSeries = drillDownIntoSeries;
                return this;
            }
            public ChartBuilder EmptyElementText(string emptyElementText)
            {
                chartObj.EmptyElementText = emptyElementText;
                return this;
            }
            public ChartBuilder ExplodedSliceAmount(double explodedSliceAmount)
            {
                chartObj.ExplodedSliceAmount = explodedSliceAmount;
                return this;
            }
            public ChartBuilder ExtraChartArea(ChartArea extraChartArea)
            {
                chartObj.ExtraChartAreas.Add(extraChartArea);
                return this;
            }
            public ChartBuilder ExtraLegendBoxe(LegendBox extraLegendBox)
            {
                chartObj.ExtraLegendBoxes.Add(extraLegendBox);
                return this;
            }
            public ChartBuilder FileManager(FileManager fileManager)
            {
                chartObj.FileManager = fileManager;
                return this;
            }
            public ChartBuilder FileQuality(long fileQuality)
            {
                chartObj.FileQuality = fileQuality;
                return this;
            }
            public ChartBuilder FunnelNozzlePercentage(int funnelNozzlePercentage)
            {
                chartObj.FunnelNozzlePercentage = funnelNozzlePercentage;
                return this;
            }
            public ChartBuilder FunnelNozzleWidthPercentage(int funnelNozzleWidthPercentage)
            {
                chartObj.FunnelNozzleWidthPercentage = funnelNozzleWidthPercentage;
                return this;
            }
            public ChartBuilder FunnelSpacingPercentage(int funnelSpacingPercentage)
            {
                chartObj.FunnelSpacingPercentage = funnelSpacingPercentage;
                return this;
            }
            public ChartBuilder GanttCompleteHatchStyle(HatchStyle ganttCompleteHatchStyle)
            {
                chartObj.GanttCompleteHatchStyle = ganttCompleteHatchStyle;
                return this;
            }
            public ChartBuilder HatchStylePalette(HatchStyle[] hatchStylePalette)
            {
                chartObj.HatchStylePalette = hatchStylePalette;
                return this;
            }
            public ChartBuilder HatchStylePaletteName(HatchStylePalette hatchStylePaletteName)
            {
                chartObj.HatchStylePaletteName = hatchStylePaletteName;
                return this;
            }
            public ChartBuilder Hotspot(Hotspot hotspot)
            {
                chartObj.Hotspot = hotspot;
                return this;
            }
            public ChartBuilder ImageFormat(ImageFormat imageFormat)
            {
                chartObj.ImageFormat = imageFormat;
                return this;
            }
            public ChartBuilder JsEnabled(bool jsEnabled)
            {
                chartObj.JS.Enabled = jsEnabled;
                return this;
            }
            public ChartBuilder JS(JsOptions jsOptions)
            {
                chartObj.JS = jsOptions;
                return this;
            }
            public ChartBuilder LegendBox(LegendBox legendBox)
            {
                chartObj.ChartArea.LegendBox = chartObj.LegendBox = legendBox;
                //if (legendBox.ExtraEntries.Count > 0)
                //    chartObj.ExtraLegendEntries.Add(legendBox.ExtraEntries);
                return this;
            }
            public ChartBuilder Mapping(Mapping.Mapping mapping)
            {
                chartObj.Mapping = mapping;
                return this;
            }
            public ChartBuilder Margin(string margin)
            {
                chartObj.Margin = margin;
                return this;
            }
            public ChartBuilder MarginTop(int marginTop)
            {
                chartObj.MarginTop = marginTop;
                return this;
            }
            public ChartBuilder MarginBottom(int marginBottom)
            {
                chartObj.MarginBottom = marginBottom;
                return this;
            }
            public ChartBuilder MaximumBubbleSize(int maximumBubbleSize)
            {
                chartObj.MaximumBubbleSize = maximumBubbleSize;
                return this;
            }
            public ChartBuilder MaximumBubbleSizeValue(int maximumBubbleSizeValue)
            {
                chartObj.MaximumBubbleSizeValue = maximumBubbleSizeValue;
                return this;
            }
            public ChartBuilder Navigator(NavigatorOptions navigatorOptions)
            {
                chartObj.Navigator = navigatorOptions;
                return this;
            }
            public ChartBuilder NavigatorEnabled(bool enabled)
            {
                chartObj.Navigator.Enabled = enabled;
                return this;
            }
            public ChartBuilder NoDataLabel(Label noDataLabel)
            {
                chartObj.NoDataLabel = noDataLabel;
                return this;
            }
            public ChartBuilder ShowDateInTitle(bool showDateInTitle)
            {
                chartObj.ShowDateInTitle = showDateInTitle;
                return this;
            }
            public ChartBuilder SmallChartMode(bool smallChartMode)
            {
                chartObj.SmallChartMode = smallChartMode;
                return this;
            }
            public ChartBuilder SmartForecast(TimeIntervalAdvanced smartForecast)
            {
                chartObj.SmartForecast = smartForecast;
                return this;
            }
            public ChartBuilder SmartPalette(SmartPalette smartPalette)
            {
                chartObj.SmartPalette = smartPalette;
                return this;
            }
            public ChartBuilder SmartPaletteAutoSync(bool smartPaletteAutoSync)
            {
                chartObj.SmartPaletteAutoSync = smartPaletteAutoSync;
                return this;
            }
            public ChartBuilder TitleBox(Box titleBox)
            {
                chartObj.ChartArea.TitleBox = chartObj.TitleBox = titleBox;
                return this;
            }
            public ChartBuilder ToolTip(string toolTip)
            {
                chartObj.ToolTip = toolTip;
                return this;
            }
            public ChartBuilder Transpose(bool transpose)
            {
                chartObj.Transpose = transpose;
                return this;
            }
            public ChartBuilder UseFile(bool useFile)
            {
                chartObj.UseFile = useFile;
                return this;
            }
            public ChartBuilder UseSession(bool useSession)
            {
                chartObj.UseSession = useSession;
                return this;
            }
            public ChartBuilder View3D(View3D view3D)
            {
                chartObj.View3D = view3D;
                return this;
            }
            public ChartBuilder ZAxis(Axis zAxis)
            {
                chartObj.ZAxis = zAxis;
                return this;
            }
            public ChartBuilder PieLabelMode(PieLabelMode pieLabelMode)
            {
                chartObj.PieLabelMode = pieLabelMode;
                return this;
            }
            public ChartBuilder RadarLabelMode(RadarLabelMode radarLabelMode)
            {
                chartObj.RadarLabelMode = radarLabelMode;
                return this;
            }
            public ChartBuilder FileName(string fileName)
            {
                _fileName = fileName;
                return this;
            }
            public ChartBuilder TempDirectory(string tempDirectory)
            {
                chartObj.TempDirectory = tempDirectory;
                return this;
            }
            public ChartBuilder Size(string size)
            {
                chartObj.Size = size;
                return this;
            }
            public ChartBuilder DateGrouping(TimeInterval timeInterval)
            {
                chartObj.DateGrouping = timeInterval;
                return this;
            }
            public ChartBuilder YAxis(Axis yAxis)
            {
                chartObj.ChartArea.YAxis = chartObj.YAxis = yAxis;
                return this;
            }
            public ChartBuilder XAxis(Axis xAxis)
            {
                chartObj.ChartArea.XAxis = chartObj.XAxis = xAxis;
                return this;
            }
            public ChartBuilder OverlapFooter(bool overlapFooter)
            {
                chartObj.OverlapFooter = overlapFooter;
                return this;
            }
            public ChartBuilder PaletteName(Palette palette)
            {
                chartObj.PaletteName = palette;
                return this;
            }
            public ChartBuilder Palette(Color[] colorArray)
            {
                chartObj.Palette = colorArray;
                return this;
            }
            public ChartBuilder Title(string title)
            {
                cTitle = title;
                return this;
            }
            public ChartBuilder ChartType(dotnetCHARTING.ChartType type)
            {
                chartObj.Type = type;
                return this;
            }
            public ChartBuilder DataEngine(DataEngine dataEngine)
            {
                de = dataEngine;
                return this;
            }
            public ChartBuilder ConnectionString(string connectionString)
            {
                chartObj.DefaultSeries.ConnectionString = connectionString;
                return this;
            }
            public ChartBuilder SeriesCollection(SeriesCollection seriesCollection)
            {
                //if(sc==null)
                //    sc = new dotnetCHARTING.SeriesCollection();
                sc = seriesCollection;
                return this;
            }
            public ChartBuilder SeriesCollection(Series series)
            {
                if (sc == null)
                    sc = new dotnetCHARTING.SeriesCollection();
                sc.Add(series);
                return this;
            }
        }
        public static SeriesCollection generateRandomData(int numberOfSeries, int numberOfElements)
        {
            return generateRandomData(dotnetCHARTING.ChartType.Combo, numberOfSeries, numberOfElements);
        }
        public static SeriesCollection generateRandomData(ChartType st)
        {
            return generateRandomData(st, 4, 4);
        }
        public static SeriesCollection generateRandomData()
        {
            return generateRandomData(dotnetCHARTING.ChartType.Combo, 4, 4);
        }
        public static SeriesCollection generateRandomData(ChartType st, int numberOfSeries, int numberOfElements)
        {
            return generateRandomData(st, numberOfSeries, numberOfElements, DateTime.MinValue);
        }
        public static SeriesCollection generateRandomData(ChartType st, int numberOfSeries, int numberOfElements, DateTime startDate)
        {
            var SC = new dotnetCHARTING.SeriesCollection();
            if (st == dotnetCHARTING.ChartType.Surface)
            {
                int size = numberOfSeries;
                double[][] zVals = new double[size][];
                double[] xVals = new double[size];
                double[] yVals = new double[size];
                // Series s = new Series();
                for (int i = 0; i < size; i++)
                {
                    zVals[i] = new double[size];
                    for (int j = 0; j < size; j++)
                    {
                        double x = (double)(-2 + i * .16);
                        double y = (double)(-2 + j * .16);
                        xVals[i] = x;
                        yVals[j] = y;
                        zVals[i][j] = Math.Sin(x * 3.2) + Math.Cos(y * 2) + Math.Sin(x * 1.2) + Math.Sin(y * 1.2);
                    }
                }
                Series s = Series.FromSurfaceData("", xVals, yVals, zVals);
                SC.Add(s);
            }
            else
            {
                Random myR = new Random();
                for (int a = 1; a < numberOfSeries + 1; a++)
                {
                    var s = new dotnetCHARTING.Series();
                    s.Name = "Series " + a;
                    for (int b = 1; b < numberOfElements + 1; b++)
                    {
                        var e = new dotnetCHARTING.Element();
                        if (startDate != DateTime.MinValue)
                            e.XDateTime = startDate = startDate.AddDays(1);
                        e.Name = "E " + b;
                        if (st == dotnetCHARTING.ChartType.Gauges)
                            e.YValue = 10 + myR.Next(40);
                        else
                            e.YValue = myR.Next(5, 50);
                        if (st == dotnetCHARTING.ChartType.Bubble || st == dotnetCHARTING.ChartType.Radar
                            || st == dotnetCHARTING.ChartType.Pie || st == ChartType.Scatter)
                        {
                            e.XValue = myR.Next(50);
                            if (st == dotnetCHARTING.ChartType.Bubble)
                                e.BubbleSize = myR.Next(50);
                        }
                        s.Elements.Add(e);
                    }
                    SC.Add(s);
                }
            }
            return SC;
        }
        public static SeriesCollection generateRandomData(ChartType st, DateTime startDate, int numberOfElements)
        {
            SeriesCollection SC = new SeriesCollection();
            Random myR = new Random();
            if (ChartType.Financial == st)
            {
                for (int i = 0; i < 1; i++)
                {
                    Series s = new Series();
                    s.Name = "X Company";
                    double startPrice = 50;
                    DateTime startDT = startDate;
                    for (int b = 0; b < numberOfElements; b++)
                    {
                        Element e = new Element();
                        e.XDateTime = startDT;
                        startDT = startDT.AddDays(1);
                        if (myR.Next(10) > 5)
                            startPrice += myR.Next(5);
                        else
                            startPrice -= myR.Next(3);
                        e.Close = startPrice;
                        e.Volume = myR.Next(100);
                        if (myR.Next(10) > 5)
                            e.Open = startPrice + myR.Next(6);
                        else
                            e.Open = startPrice - myR.Next(6);
                        if (e.Open > e.Close)
                        {
                            e.High = e.Open + myR.Next(6);
                            e.Low = e.Close - myR.Next(6);
                        }
                        else
                        {
                            e.High = e.Close + myR.Next(6);
                            e.Low = e.Open - myR.Next(6);
                        }
                        s.Elements.Add(e);
                    }
                    SC.Add(s);
                }
            }
            else
            {
                DateTime dt = startDate;
                Series s = new Series("Series 1");
                for (int b = 1; b < numberOfElements; b++)
                {
                    Element e = new Element();
                    e.XDateTime = dt = dt.AddDays(1);
                    e.YValue = myR.Next(50);
                    s.Elements.Add(e);
                }
                SC.Add(s);
            }
            return (SC);
        }
        public static string MapPath(string original)
        {
            // Determine whiether Absolute Path, Relative Web, Absolute Web address, or UNC
            string result = original;
            if (original.IndexOf(@":\") != -1 || original.IndexOf(@":/") != -1)
            {
                // Absolute Path
                result = original;
            }
            else if (original.StartsWith(@"\\") || original.StartsWith(@"//"))
            {
                // UNC
                result = original;
            }
            else
            {
                //result = Path.Combine(HostingEnvironment.WebRootPath, original);
                if (original.StartsWith(Path.AltDirectorySeparatorChar.ToString()) || original.StartsWith(Path.DirectorySeparatorChar.ToString()))
                    result = HostingEnvironment.WebRootPath + original;
                else
                    result = HostingEnvironment.WebRootPath + Path.DirectorySeparatorChar.ToString() + original;
                result = result.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
            }
            return result;
        }        
        public static DataProviderType ProviderType = DataProviderType.Sqlite;
        public static string ConnectionString()
        {
            string providerTypeString = Configuration.GetConnectionString("DataProvider");
            if (!string.IsNullOrEmpty(providerTypeString))
                ProviderType = (DataProviderType)Enum.Parse(typeof(DataProviderType), providerTypeString);
            string connString = "";
            string path = "";
            try
            {
                var conn = Configuration.GetConnectionString("ConnectionString");
                switch (ProviderType)
                {
                    case DataProviderType.MySql:
                        connString = conn;
                        break;
                    case DataProviderType.MsSql:
                        connString = conn;
                        break;
                    case DataProviderType.Oracle:
                        connString = conn;
                        break;
                    case DataProviderType.Sqlite:
                        connString = conn;
                        path = MapPath(conn);
                        connString = "Data Source=" + path + ";";
                        break;
                    case DataProviderType.OleDb:
                        path = MapPath(conn);
                        if(conn.EndsWith(".mdb"))
                            connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + ";";
                        else
                            connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";";
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return connString;
        }
        public static ChartBuilder Chart(this IHtmlHelper helper, HttpContext httpContext)
        {
            return new ChartBuilder(helper, httpContext);
        }
    }
}
