using System;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using System.IO;
using System.Web;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Xml;
using System.Windows.Forms;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Text.RegularExpressions;
namespace WindowsFormsApp1
{
    /// 
    /// 여러 기능들이 추가될 예정.
    /// Excel_to_DataGridView
    /// 
    class Skill_Grid
    {
        /// 
        /// * Row헤더에 체크박스를 넣는 기능*
        /// 사용불가. 복사해서 가져가고 사양에 맞춰 수정할 것.
        /// 
        /// 
        /// 
        /// 체크박스를 넣을 컬럼 위치
        public void Add_Row_CheckBox(object sender, DataGridViewCellPaintingEventArgs e, int colCount)
        {
            if (e.ColumnIndex == colCount && e.RowIndex == -1)
            {
                string ori_name = ((DataGridView)sender).Name;
                ((DataGridView)sender).Name = "Add_chkBox";
                e.PaintBackground(e.ClipBounds, false);
                Point pt = e.CellBounds.Location;
                int nChkBoxWidth = 15;
                int nChkBoxHeight = 15;
                int offsetX = (e.CellBounds.Width - nChkBoxWidth) / 2;
                int offsetY = (e.CellBounds.Height - nChkBoxHeight) / 2;
                pt.X += offsetX;
                pt.Y += offsetY;
                CheckBox cb = new CheckBox();
                cb.Size = new Size(nChkBoxWidth, nChkBoxHeight);
                cb.Location = pt;
                cb.CheckedChanged += new EventHandler(datagridview_checkBox_Click);
                ((DataGridView)sender).Controls.Add(cb);
                e.Handled = true;
            }
        }
        private void datagridview_checkBox_Click(object sender, EventArgs e)
        {
            foreach(DataGridViewRow r in ((DataGridView)sender).Rows)
            {
                r.Cells["chkbox"].Value = ((CheckBox)sender).Checked;
            }
        }
        /// 
        /// 엑셀에서 복사한 데이터를 DataGirdView에 붙여넣어주는 코드 (단, KeyDown에 넣어야함!!!!)
        /// 사전에 if ((e.Shift && e.KeyCode == Keys.Insert) || (e.Control && e.KeyCode == Keys.V))안에 들어가야함.
        /// 
        /// KeyDown의 object "sender"
        /// KeyDown의 KeyEventArgs "e"
        public void Excel_to_DataGridView(object sender, KeyEventArgs e)
        {
            //if user clicked Shift+Ins or Ctrl+V (paste from clipboard)
            if ((e.Shift && e.KeyCode == Keys.Insert) || (e.Control && e.KeyCode == Keys.V))
            {
                char[] rowSplitter = { '\r', '\n' };
                char[] columnSplitter = { '\t' };
                //get the text from clipboard
                IDataObject dataInClipboard = Clipboard.GetDataObject();
                string stringInClipboard = (string)dataInClipboard.GetData(DataFormats.Text);
                //split it into lines
                string[] rowsInClipboard = stringInClipboard.Split(rowSplitter, StringSplitOptions.RemoveEmptyEntries);
                //get the row and column of selected cell in dataGridView1
                int r = ((DataGridView)sender).SelectedCells[0].RowIndex;
                int c = ((DataGridView)sender).SelectedCells[0].ColumnIndex;
                //add rows into dataGridView1 to fit clipboard lines
                if (((DataGridView)sender).Rows.Count < (r + rowsInClipboard.Length))
                {
                    ((DataGridView)sender).Rows.Add(r + rowsInClipboard.Length - ((DataGridView)sender).Rows.Count);
                }
                // loop through the lines, split them into cells and place the values in the corresponding cell.
                for (int iRow = 0; iRow < rowsInClipboard.Length; iRow++)
                {
                    //split row into cell values
                    string[] valuesInRow = rowsInClipboard[iRow].Split(columnSplitter);
                    //cycle through cell values
                    for (int iCol = 0; iCol < valuesInRow.Length; iCol++)
                    {
                        //assign cell value, only if it within columns of the dataGridView1
                        if (((DataGridView)sender).ColumnCount - 1 >= c + iCol)
                        {
                            ((DataGridView)sender).Rows[r + iRow].Cells[c + iCol].Value = valuesInRow[iCol];
                        }
                    }
                }
            }
        }
        /// 
        /// DataGirdView의 활성화된 셀값을 삭제하는 코드 (단, KeyDown에 넣어야함!!!!)
        /// 사전에 if(e.KeyCode == Keys.Delete)안에 들어가야함.
        /// 
        /// KeyDown의 object "sender"
        /// KeyDown의 KeyEventArgs "e"
        public void DataGrid_to_Delete(object sender, KeyEventArgs e)
        {
            int rowIndex = ((DataGridView)sender).CurrentCell.RowIndex;
            int columnIndex = ((DataGridView)sender).CurrentCell.ColumnIndex;
            ((DataGridView)sender).Rows[rowIndex].Cells[columnIndex].Value = "";
        }
        /// 
        /// 그리드 앞 머리말에 넘버를 표시
        /// 
        /// 
        /// 
        public void Print_Grid_Num(Object sender, DataGridViewRowPostPaintEventArgs e)
        {
            // RowPostPaint 이벤트 핸들러
            // 행헤더 열영역에 행번호를 위해 장방형으로 처리
            Rectangle rect = new Rectangle(e.RowBounds.Location.X,
                                           e.RowBounds.Location.Y,
                                           ((DataGridView)sender).RowHeadersWidth - 4,
                                           e.RowBounds.Height);
            // 위에서 생성된 장방형내에 행번호를 보여주고 폰트색상 및 배경을 설정
            TextRenderer.DrawText(e.Graphics,
                                  (e.RowIndex + 1).ToString(),
                                  ((DataGridView)sender).RowHeadersDefaultCellStyle.Font,
                                  rect,
                                  ((DataGridView)sender).RowHeadersDefaultCellStyle.ForeColor,
                                  TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }
        /// 
        /// Grid에서 복사시 클립보드 글자깨짐방지
        /// 현재 효과없음
        /// 
        /// 
        /// 
        public void clipboard_not_crack(object sender, KeyEventArgs e)
        {
            Clipboard.SetDataObject(((DataGridView)sender).GetClipboardContent().GetText());
        }
        /// 
        /// 엑셀 내보내기
        /// 
        /// 사용할 데이터 그리드뷰
        public void ExportToExcel(DataGridView datagridview)
        {
            Excel.Application excelApplication;
            Excel._Workbook workbook;
            Excel._Worksheet worksheet;
            excelApplication = new Excel.Application();
            if (excelApplication == null) {
                MessageBox.Show("엑셀이 설치되지 않았습니다");
                return;
            }
            excelApplication.Visible = false;
            workbook = excelApplication.Workbooks.Add(Missing.Value);
            worksheet = workbook.ActiveSheet as Excel._Worksheet;
            object[,] headerValueArray = new object[1, datagridview.ColumnCount];
            int gap = 0;    // 숨김처리된 컬럼 격차 줄이기 위한 변수
            // 헤더 출력
            for (int a = 0; a < datagridview.Columns.Count; a++)
            {
                if (datagridview.Columns[a].Visible == false) { gap++; continue; }
                
                headerValueArray[0, a - gap] = datagridview.Columns[a].HeaderText;
            }
            Excel.Range startHeaderCell = worksheet.Cells[1, 1];
            Excel.Range endHeaderCell = worksheet.Cells[1, datagridview.ColumnCount - gap];
            worksheet.get_Range(
                startHeaderCell as object, endHeaderCell as object).Font.Bold = true;
            worksheet.get_Range(
                startHeaderCell as object, endHeaderCell as object).VerticalAlignment=Excel.XlVAlign.xlVAlignCenter;
            worksheet.get_Range(
                startHeaderCell as object, endHeaderCell as object).Value2 = headerValueArray;
            object[,] cellValueArray = new object[datagridview.RowCount, datagridview.ColumnCount];
            gap = 0;
            // 내용 출력
            for(int a = 0; a < datagridview.RowCount; a++)
            {
                for(int b = 0; b < datagridview.ColumnCount; b++)
                {
                    if (datagridview.Columns[b].Visible == false) { gap++; continue; }
                    if (datagridview.Rows[a].Cells[b].ValueType.Name == "String") {
                        cellValueArray[a, b-gap] = "'" + datagridview.Rows[a].Cells[b].Value.ToString();
                    }
                    else {
                        cellValueArray[a, b] = datagridview.Rows[a].Cells[b].Value;
                    }
                }
            }
            Excel.Range startCell = worksheet.Cells[2, 1];
            Excel.Range endCell = worksheet.Cells[datagridview.RowCount + 1, datagridview.ColumnCount-gap];
            worksheet.get_Range(startCell as object, endCell as object).Value2 = cellValueArray;
            excelApplication.Visible = true;
            excelApplication.UserControl = true;
        }
    }
    /// 
    /// 텍스트 관련 함수.
    /// 
    class String_Text
    {
        /// 
        /// 텍스트박스 숫자만 입력받는 함수. KeyPress함수에 적용
        /// 
        /// 
        /// 
        public void Only_Int(object sender, KeyPressEventArgs e)
        {
            if(!(char.IsDigit(e.KeyChar) || e.KeyChar == Convert.ToChar(Keys.Back)))
            {
                e.Handled = true;
            }
        }
        /// 
        /// TextChanged이벤트 - 천단위 콤마찍어주기
        /// 
        /// object sender
        /// EventArgs
        public void Int_Comma(object sender, EventArgs e)
        {
            if (((TextBox)sender).Text != "") {
                string text;
                text = ((TextBox)sender).Text.Replace(",", "");
                ((TextBox)sender).Text = String.Format("{0:#,###}", Convert.ToInt32(text));
                ((TextBox)sender).SelectionStart = ((TextBox)sender).TextLength;
                ((TextBox)sender).SelectionLength = 0;
            }
        }
        /// 
        /// 문자열 내에 한글이 들어가는지 체크
        /// 
        /// 대상 문자열
        /// 한글 포함시 true
        public bool isContainHangul(string value)
        {
            char[] charArr = value.ToCharArray();
            foreach(char c in charArr)
            {
                if (char.GetUnicodeCategory(c) == System.Globalization.UnicodeCategory.OtherLetter)
                    return true;
            }
            return false;
        }
        /// 
        /// 대상 문자열안에 찾고 싶은 문자 찾기
        /// 
        /// 대상 문자열
        /// 찾고 싶은 문자
        /// 있을 경우 True반환
        public bool CheckString(string value, string chkString)
        {
            int index = value.IndexOf(chkString);
            if (index < 0) 
                return false;
            return true;
        }
        public int Char_count(string value, char chkString)
        {
            string[] res = value.Split(chkString);
            int count = res.Length;
            return count - 1;
        }
        /// 
        /// 문자와 문자사이의 값 가져오기
        /// 
        /// 대상 문자열
        /// 시작 문자열
        /// 마지막 문자열
        /// 문자 사이값
        public string GetMiddelString(string str, string begin, string end)
        {
            if (string.IsNullOrEmpty(str))
            {
                return null;
            }
            string result = null;
            if (str.IndexOf(begin) > -1)
            {
                str = str.Substring(str.IndexOf(begin) + begin.Length);
                if (str.IndexOf(end) > -1) result = str.Substring(0, str.IndexOf(end));
                else result = str;
            }
            return result;
        }
    }
    public class API
    {
        /// 
        /// https://blog.aladin.co.kr/openapi 참고
        /// 
        /// 
        /// 
        /// 
        /// 
        public string Aladin(string Query, string QueryType, string[] Param)
        {
            string result = string.Empty;
            // 쿼리 생성
            string key = "ttbgloriabook1512001";
            string site = "http://www.aladin.co.kr/ttb/api/ItemSearch.aspx";
            string query = string.Format("{0}?query={1}&TTBKey={2}&output=xml&querytype={3}&MaxResults={4}",
                site, Query, key, QueryType, 30.ToString());
            // 쿼리를 입력인자로 WebRequest 개채 생성
            WebRequest request = WebRequest.Create(query);
            // WebRequest개체의 헤더에 인증키 포함시키기.
            // request.Headers.Add("Authorization", header);
            // WebResponse개체를 통해 서비스 요청.
            WebResponse response = request.GetResponse();
            // 결과문자열 확인
            Stream stream = response.GetResponseStream();
            StreamReader reader = new StreamReader(stream, Encoding.UTF8);
            String xml = reader.ReadToEnd();
            stream.Close();
            // xml형식을 json형식으로 변환
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            var json = JsonConvert.SerializeXmlNode(doc);
            // json형식 분석을 위해 JavaScriptSerializer 개체 생성
            JavaScriptSerializer js = new JavaScriptSerializer();
            // 런타임에 개체를 확인하여 사용할수 있는 dynamic을 이용해 역직렬화
            dynamic dob = js.Deserialize(json);
            // "object"내에 있는것을 얻어오기 위해 다시 dynamic변수에 참조
            dynamic docs = "";
            try
            {
                docs = dob["object"]["item"];
            }
            catch
            {
                return "";
            }
            int length = 0;
            int ID_length = Param.Length;
            // 검색 결과가 1개 이하일 경우, 오류가 발생하여 try/catch문 사용.
            try
            {
                // docs는 요소 컬렉션으로 object로 변환.
                object[] buf = docs;
                length = buf.Length;
            }
            catch
            {
                object buf = docs;
                length = 1;
            }
            for (int a = 0; a < length; a++)
            {
                List tmp_data = new List();
                for (int b = 0; b < ID_length; b++)
                {
                    if (length == 1)
                    {
                        tmp_data.Add(docs[Param[b]]);
                    }
                    else
                    {
                        tmp_data.Add(docs[a][Param[b]]);
                    }
                    result += tmp_data[b] + "|";
                }
                result += "\n";
            }
            return result;
        }
        public string Naver(string[] Query, string[] QueryType, string[] Param)
        {
            string result = string.Empty;
            string json = string.Empty;
            // url 생성
            string url = "https://openapi.naver.com/v1/search/book_adv?";
            for (int a = 0; a < Query.Length; a++)
            {
                url += string.Format("{0}={1}&", QueryType[a], Query[a]);
            }
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Headers.Add("X-Naver-Client-Id", "wYr0JczCBoDopq1NKTyQ");   // 클라이언트 아이디
            request.Headers.Add("X-Naver-Client-Secret", "QHzeXadtO7");         // 클라이언트 시크릿
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string status = response.StatusCode.ToString();
            if (status == "OK")
            {
                Stream stream = response.GetResponseStream();
                StreamReader reader = new StreamReader(stream, Encoding.UTF8);
                json = reader.ReadToEnd();
            }
            else
            {
                MessageBox.Show(status, "Error");
                return "Error";
            }
            // json형식 분석을 위해 JavaScriptSerializer 개체 생성
            JavaScriptSerializer js = new JavaScriptSerializer();
            // 런타임에 개체를 확인하여 사용할수 있는 dynamic을 이용해 역직렬화
            dynamic dob = js.Deserialize(json);
            // "object"내에 있는것을 얻어오기 위해 다시 dynamic변수에 참조
            dynamic docs = "";
            try
            {
                // docs = dob["object"]["item"];
                docs = dob["items"];
            }
            catch
            {
                return "";
            }
            int length = 0;
            int ID_length = Param.Length;
            // 검색 결과가 1개 이하일 경우, 오류가 발생하여 try/catch문 사용.
            try
            {
                // docs는 요소 컬렉션으로 object로 변환.
                object[] buf = docs;
                length = buf.Length;
            }
            catch
            {
                object buf = docs;
                length = 1;
            }
            for (int a = 0; a < length; a++)
            {
                List tmp_data = new List();
                for (int b = 0; b < ID_length; b++)
                {
                    tmp_data.Add(docs[a][Param[b]]);
                    result += tmp_data[b] + "|";
                }
                result += "\n\t";
            }
            return result;
        }
        public string Daum(string Query, string Type, string[] Param)
        {
            string result = string.Empty;
            // url생성
            string url = "https://dapi.kakao.com/v3/search/book";
            string query = string.Format("{0}?query={1}&target={2}&", url, Query, Type);
            WebRequest request = WebRequest.Create(query);
            string rKey = "e3935565b731a2a6f32880c90d76403a";
            string header = "KakaoAK " + rKey;
            request.Headers.Add("Authorization", header);
            WebResponse response = request.GetResponse();
            Stream stream = response.GetResponseStream();
            StreamReader reader = new StreamReader(stream, Encoding.UTF8);
            string json = reader.ReadToEnd();
            stream.Close();
            JavaScriptSerializer js = new JavaScriptSerializer();
            dynamic dob = js.Deserialize(json);
            dynamic docs = dob["documents"];
            object[] buf = docs;
            int length = buf.Length;
            int ID_length = Param.Length;
            for (int a = 0; a < length; a++)
            {
                List