using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Blurum
{
/// <summary>
///
/// </summary>
[Serializable]
public partial class BlurumCatalogue : UserControl
{
private readonly Timer _timer;
/// <summary>
///
/// </summary>
public event ProductAddedHandler ProductAdded;
/// <summary>
///
/// </summary>
/// <param name="catalogue"></param>
/// <param name="p"></param>
public delegate void ProductAddedHandler(BlurumCatalogue catalogue,Product p);
/// <summary>
///
/// </summary>
public event ProductAddedToWishListHandler ProductAddedToWishList;
/// <summary>
///
/// </summary>
/// <param name="catalogue"></param>
/// <param name="p"></param>
public delegate void ProductAddedToWishListHandler(BlurumCatalogue catalogue, Product p);
/// <summary>
///
/// </summary>
public event ProductInWishListAvailableHandler ProductInWishListAvailable;
/// <summary>
///
/// </summary>
/// <param name="catalogue"></param>
/// <param name="p"></param>
public delegate void ProductInWishListAvailableHandler(BlurumCatalogue catalogue, Product p);
readonly private WebBrowser _web = new WebBrowser();
/// <summary>
/// WishList con i prodotti caricati in memoria.
/// </summary>
public List<Product> LoadedProducts = new List<Product>();
/// <summary>
/// WishList con i prodotti.
/// </summary>
public List<Product> WishList = new List<Product>();
private const string Link = @"https://www.blurum.it/Web/PointBox.aspx";
/// <summary>
/// Controlla se il webbrowser interno sta ancora caricando oppure no.
/// </summary>
public bool IsLoading { get {return _web.ReadyState!=WebBrowserReadyState.Complete; } }
/// <summary>
/// Ritorna true se il timer della wishlist è attivo, false altrimenti.
/// </summary>
public bool IsCheckingWishList { get; set; }
/// <summary>
/// Costruttore principale della classe.
/// </summary>
public BlurumCatalogue()
{
InitializeComponent();
_web.ScriptErrorsSuppressed = true;
_web.Visible = false;
treeCatalogo.AfterSelect += AfterSelect;
treeCatalogo.BeforeExpand += BeforeExpand;
_timer = new Timer {Interval = 5000};
_timer.Tick += CheckWishListTick;
}
/// <summary>
/// Metodo principale che carica le categorie principali.
/// </summary>
public void LoadMainCategories()
{
//IsLoading = true;
treeCatalogo.Nodes.Clear();
_web.Navigate(Link);
while (_web.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
var elements = _web.Document.GetElementsByTagName("li");
foreach (HtmlElement elem in elements)
{
foreach (HtmlElement el2 in elem.GetElementsByTagName("a"))
{
if (el2.GetAttribute("href").Contains("catalog"))
{
TreeNode radice = new TreeNode(elem.GetElementsByTagName("img")[0].GetAttribute("alt"));
radice.ToolTipText = el2.GetAttribute("href");
radice.Tag = el2.GetAttribute("href");
radice.Nodes.Add("cacca");
treeCatalogo.Nodes.Add(radice);
}
}
}
//IsLoading = false;
}
/// <summary>
/// Setta l'intervallo del timer interno.
/// </summary>
/// <param name="ms">Tempo in millisecondi per l'intervallo del timer (consiglio di moltiplicare il numero di prodotti nella wishlist per 5)</param>
public void SetTimerIntervalForWishListCheck(int ms)
{
_timer.Interval = ms;
}
/// <summary>
/// Fa partire il timer interno per controllare se i prodotti nella wishlist sono disponibili.
/// </summary>
public void BeginCheckingWishList()
{
_timer.Start();
IsCheckingWishList = true;
}
/// <summary>
/// Ferma il timer interno che controlla se i prodotti nella wishlist sono disponibili.
/// </summary>
public void StopCheckingWishList()
{
_timer.Stop();
IsCheckingWishList = false;
}
private void BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
TreeNode nodo = e.Node;
if (nodo.Nodes.Count == 1 && nodo.Nodes[0].Text == @"cacca")
nodo.Nodes.RemoveAt(0);
if (nodo.Nodes.Count == 0)
{
switch (nodo.Level)
{
case 0:
//IsLoading = true;
_web.Navigate(nodo.ToolTipText);
while (_web.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
var elements = _web.Document.GetElementsByTagName("ul");
foreach (HtmlElement element in elements)
{
if (element.GetAttribute("className") == "listCompVertical catalogSectors")
{
var elem2 = element.GetElementsByTagName("li");
foreach (HtmlElement el in elem2)
{
Application.DoEvents();
TreeNode newNodo = new TreeNode(el.GetElementsByTagName("a")[0].InnerHtml.Replace(" ", ""));
newNodo.ToolTipText = el.GetElementsByTagName("a")[0].GetAttribute("href");
newNodo.Tag = el.GetElementsByTagName("a")[0].GetAttribute("href");
//MessageBox.Show(newNodo.ToolTipText);
newNodo.Nodes.Add("cacca");
nodo.Nodes.Add(newNodo);
}
}
}
//IsLoading = false;
break;
case 1: //sottocategoria
//IsLoading = true;
_web.Navigate(nodo.ToolTipText);
while (_web.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
var elem = _web.Document.GetElementById("lev-2-0");
foreach (HtmlElement listElement in elem.GetElementsByTagName("li"))
{
Application.DoEvents();
TreeNode newNodo = new TreeNode(listElement.GetElementsByTagName("a")[0].InnerHtml.Replace(" ", ""));
newNodo.ToolTipText = listElement.GetElementsByTagName("a")[0].GetAttribute("href").Replace("&page=1", "");
newNodo.Tag = listElement.GetElementsByTagName("a")[0].GetAttribute("href").Replace("&page=1", "");
newNodo.Nodes.Add("cacca");
//MessageBox.Show(newNodo.ToolTipText);
nodo.Nodes.Add(newNodo);
}
//IsLoading = false;
break;
case 2:
string notFound = "La ricerca non ha prodotto risultati";
int i = 1;
while (true)
{
//IsLoading = true;
_web.Navigate(nodo.ToolTipText + "&page=" + i);
while (_web.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
if (_web.DocumentText.Contains(notFound)) break;
var elementi = _web.Document.GetElementsByTagName("ul");
foreach (HtmlElement element in elementi)
{
if (element.GetAttribute("className") == "compListHorizontal productSampler")
{
var elem2 = element.GetElementsByTagName("li");
foreach (HtmlElement el in elem2)
{
Application.DoEvents();
TreeNode newNodo = new TreeNode(el.GetElementsByTagName("a")[0].InnerHtml.Replace(" ", "")
+ " - " + el.GetElementsByTagName("p")[0].InnerText);
newNodo.ToolTipText = el.GetElementsByTagName("a")[0].GetAttribute("href");
newNodo.Tag = el.GetElementsByTagName("a")[0].GetAttribute("href");
//MessageBox.Show(newNodo.ToolTipText);
nodo.Nodes.Add(newNodo);
}
}
}
i++;
//IsLoading = false;
}
break;
}
}
}
private void AfterSelect(object sender, TreeViewEventArgs e)
{
TreeNode nodo = e.Node;
if (nodo.Level == 3 && LoadedProducts.Where(p => p.Link == nodo.ToolTipText).ToList().Count == 0)
{
Product p = new Product();
p.Name = nodo.Text.Substring(0, nodo.Text.LastIndexOf('-') - 1);
p.Value = nodo.Text.Substring(nodo.Text.LastIndexOf('-') + 1);
p.Link = nodo.ToolTipText;
//IsLoading = true;
_web.Navigate(nodo.ToolTipText);
while (_web.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
var x = _web.Document.GetElementsByTagName("span");
foreach (HtmlElement el in x)
{
if (el.Id == "availabilityValue")
{
//p.IsAvailable = el.InnerText != "in riassortimento";
p.IsAvailable = !_web.DocumentText.Contains("in riassortimento");
}
}
x = _web.Document.GetElementsByTagName("div");
foreach (HtmlElement el in x)
{
if (el.GetAttribute("className") == "description")
{
p.Description = el.InnerText;
}
}
//IsLoading = false;
nodo.ContextMenuStrip = contextMenu;
LoadedProducts.Add(p);
if (ProductAdded != null)
ProductAdded(this, p);
}
}
private void load(object sender, EventArgs e)
{
LoadMainCategories();
}
private void AddToWishListClick(object sender, EventArgs e)
{
if (LoadedProducts != null)
{
Product x = LoadedProducts.Where(p => p.Link == treeCatalogo.SelectedNode.ToolTipText).ToList()[0];
WishList.Add(x);
if (ProductAddedToWishList != null)
ProductAddedToWishList(this, x);
}
}
private void CheckWishListTick(object sender, EventArgs e)
{
for (int i = 0; i < WishList.Count; i++)
{
if (!IsLoading)
{
//IsLoading = true;
_web.Navigate(WishList[i].Link);
while (_web.ReadyState != WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
var x = _web.Document.GetElementsByTagName("span");
foreach (HtmlElement el in x)
{
if (el.Id == "availabilityValue")
{
WishList[i].IsAvailable = !_web.DocumentText.Contains("in riassortimento");
}
}
if (WishList[i].IsAvailable && ProductInWishListAvailable != null) ProductInWishListAvailable(this, WishList[i]);
}
}
}
}
/// <summary>
/// Classe che rappresenta un prodotto di blurum.
/// </summary>
public class Product
{
private string _valore;
private string _nome;
private bool _isAvailable;
private string _description;
private string _link;
/// <summary>
/// Costruttore per un prodotto generico.
/// </summary>
/// <param name="nome">Nome del prodotto.</param>
/// <param name="isAvailable">Disponibilità del prodotto (true o false).</param>
/// <param name="description">Descrizione del prodotto.</param>
/// <param name="valore">Valore (in punti) del prodotto.</param>
/// <param name="link">Link al sito di blurum del prodotto.</param>
public Product(string nome, bool isAvailable, string description, string valore, string link)
{
_nome = nome;
_isAvailable = isAvailable;
_description = description;
_valore = valore;
_link = link;
}
/// <summary>
/// Costruttore di default.
/// </summary>
public Product()
{
}
/// <summary>
/// Valore del prodotto in punti.
/// </summary>
public string Value
{
get { return _valore; }
set { _valore = value; }
}
/// <summary>
/// Nome del prodotto.
/// </summary>
public string Name
{
get { return _nome; }
set { _nome = value; }
}
/// <summary>
/// Indica se un prodotto è disponibile o no.
/// </summary>
public bool IsAvailable
{
get { return _isAvailable; }
set { _isAvailable = value; }
}
/// <summary>
/// Descrizione del prodotto.
/// </summary>
public string Description
{
get { return _description; }
set { _description = value; }
}
/// <summary>
/// Link al sito di blurum del prodotto.
/// </summary>
public string Link
{
get { return _link; }
set { _link = value; }
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Name + "\n" + "Value: " + Value + "\nIs Available :" + _isAvailable.ToString() + "\nDescription: " + Description;
}
}
}