<?php
/**
 * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
 *
 * BOKEH is free software; you can redistribute it and/or modify
 * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
 * the Free Software Foundation.
 *
 * There are special exceptions to the terms and conditions of the AGPL as it
 * is applied to this software (see README file).
 *
 * BOKEH is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
 *
 * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
 * along with BOKEH; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 */


class Class_WebService_Lastfm  extends Class_WebService_Abstract {
  protected static $_instance;
  protected $xml;
  protected $req;
  protected $id_afi;
  protected $ix;
  protected $player;

  public static function getInstance() {
    if (null !== static::$_instance)
      return static::$_instance;
    return new self();
  }


  public static function setInstance($instance) {
    static::$_instance = $instance;
  }


  public function __construct() {
    $this->id_afi = "76d470da0d3d5cb08a7025aae2c8686a";
    $this->xml = new Class_Xml();
    $this->req = 'http://ws.audioscrobbler.com/2.0/?api_key=' . $this->id_afi;
    $this->ix = new Class_Indexation();
    $this->player = '<embed id="lfmPlayer" height="221" width="300" align="middle" swliveconnect="true" name="lfmPlayer" allowfullscreen="true" allowscriptaccess="always" flashvars="lang=fr&lfmMode=playlist&FOD=true&resname=@TITRE@&restype=track&artist=@AUTEUR@&albumArt=&autostart=true" bgcolor="#fff" wmode="transparent" quality="high" menu="true" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://cdn.last.fm/webclient/s12n/s/5/lfmPlayer.swf" type="application/x-shockwave-flash"/>';
  }


  public function requete($req) {
    $url = $this->req . $req;

    $this->xml->open_url($url);
    return $this->test_erreur();
  }


  /** Compare deux expression et rend true si tous les mots correspondent */
  public function compare_expression($texte1, $texte2) {
    $mots_vides = ';THE;';

    $texte1 = convertFromUtf8($texte1);
    $texte2 = convertFromUtf8($texte2);
    // Decouper par mots
    $chaine = trim($this->ix->alphaMaj($texte1));
    $mot1 = explode(' ', $chaine);
    $chaine = trim($this->ix->alphaMaj($texte2));
    $mot2 = explode(' ', $chaine);

    // Comparer
    for($i=0;$i<count($mot1); $i++) {
      if (!trim($mot1[$i])) continue;
      if (strPos($mots_vides,";".$mot1[$i].";") !== false) continue;
      if (!in_array($mot1[$i],$mot2)) return false;

    }
    return true;
  }


  public function getAlbum($titre, $auteur) {
    $titre = implode(' ', $this->ix->getMots($this->ix->codeAlphaTitre($titre)));

    $req = $this->getRequete('album.search', 'album', $titre);
    if ($this->requete($req)==false)
      return false;

    $nodes = $this->xml->index['ALBUM'];
    if(!$nodes)
      return false;

    foreach($nodes as $node) {
      $album = $this->xml->get_child_value($node, "NAME");
      $artist = $this->xml->get_child_value($node, "ARTIST");
      if($this->compare_expression($titre, $album)
         and $this->compare_expression($auteur, $artist))
        break;

      $album = $artist = '';
    }

    if (!$album) {
      foreach($nodes as $node) {
        $album = $this->xml->get_child_value($node, "NAME");
        if (strtoupper($titre) == strtoupper($album))
          break;

        $album = $artist = '';
      }
    }

    if (!$album)
      return false;

    $notice["auteur"] = $artist;
    $notice["url"] = $this->xml->get_child_value($node, "URL");
    $node_image = $this->xml->get_child_node($node, "IMAGE");

    if ($this->xml->get_attribut($node_image,"SIZE") == "small")
      $notice["vignette"] = $this->xml->get_value($node_image);
    $node_image += 4;
    if($this->xml->get_attribut($node_image,"SIZE") == "large")
      $notice["image"] = $this->xml->get_value($node_image);
    return $notice;
  }


  public function getMorceaux($titre, $auteur) {
    $album=$this->getAlbum($titre,$auteur);
    if(!$album) return false;

    $data = $this->httpGet($album['url']);
    $dom = new Zend_Dom_Query($data);
    $elements = $dom->queryXpath('//td[@class="chartlist-name"]//span/a');

    if (!$elements->count())
      return ['nb_resultats' => 0];

    $piste=0;
    foreach($elements as $element) {
      $piste++;
      $album["morceaux"][1][$piste] = ['titre' => $element->textContent];
    }

    $album['nb_resultats'] = $piste;
    return $album;
  }



  protected function _getArtistBaseUrl($auteur) {
    $req = $this->getRequete('artist.search', 'artist', $auteur);

    if($this->requete($req)==false)
      return '';

    if (!$nodes = $this->xml->index["ARTIST"])
      return '';

    foreach($nodes as $node) {
      $artist = $this->xml->get_child_value($node, "NAME");
      if (strtoupper($artist) == strtoupper($auteur))
        break;
      $artist = '';
    }

    if (!$artist) {
      foreach($nodes as $node) {
        $artist = $this->xml->get_child_value($node, "NAME");
        if ($this->compare_expression($auteur,$artist) == true)
          break;
        $artist = '';
      }
    }

    if (!$artist)
      return '';

    $url = $this->xml->get_child_value($node, "URL");
    if (substr($url,0,4) != 'http')
      $url = 'http://' . $url;
    return str_replace(' ', '+', $url);
  }


  public function getPhotos($auteur) {
    if (!$artist_url = $this->_getArtistBaseUrl($auteur))
      return [];

    $data = $this->httpGet($artist_url . '/+images');

    $dom = new Zend_Dom_Query($data);
    $elements = $dom->queryXpath('//ul[@class="image-list"]/li/a/img');

    $photos = [];
    foreach($elements as $element) {
      if (!$element)
        continue;

      $url = $element->getAttribute('src');

      $photos []= ['thumb' => $url,
                   'full' => str_replace('avatar170s',  '770x0', $url)];
    }

    return $photos;
  }


  public function getDiscographie($auteur) {
    if (!$artist_url = $this->_getArtistBaseUrl($auteur))
      return [];

    $data = $this->httpGet($artist_url . '/+albums');

    $dom = new Zend_Dom_Query($data);
    $elements = $dom->queryXpath('//section[@id = "artist-albums-section"]/ol/li');
    $albums = [];

    foreach ($elements as $element) {
      $dom = $dom->setDocumentHtml($element->ownerDocument->saveHtml($element));

      $titles = $dom->query('li/a/p[@class="album-grid-item-main-text"]');
      if (!count($titles))
        continue;

      $album = [];
      foreach ($titles as $title) {
        if (isset($title)) {
          $album['titre'] = utf8_decode($title->textContent);
        }
      }

      $covers = $dom->query('a/img[@class="album-grid-album-art"]');

      foreach ($covers as $cover) {
        if (isset($cover) && isset($cover->attributes)) {
          $album['vignette'] = $cover->attributes->getNamedItem('src')->value;
        }
      }

      $albums[] = $album;
    }

    return $albums;
  }


  private function getRequete($operation, $argTitre, $titre) {
    if(!trim($titre)) return "";
    $titre=$this->ix->Alphamaj($titre);
    $titre=str_replace(" ","+",$titre);
    $titre=str_replace("+++","+",$titre);
    $titre=str_replace("++","+",$titre);
    $req="&method=".$operation."&".$argTitre."=".$titre;
    return $req;
  }


  public function test_erreur() {
    if (!$item = $this->xml->getNode("OPENSEARCH:TOTALRESULTS"))
       return false;

    $value = $this->xml->get_value($item);
    return $value > 0;
  }
}

?>