/* gmpc-guitartabs (GMPC plugin)
 * Copyright (C) 2009 Syed Mushtaq Ahmed <syed1_ahmed@yahoo.co.in>
 * Project homepage: http://gmpc.wikia.com/
 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * This program 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 General Public License for more details.

 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <stdio.h>
#include <string.h>

#include <config.h>

#include <glib.h>
#include <gtk/gtk.h>

#include <libmpd/debug_printf.h>

#include <gmpc/plugin.h>
#include <gmpc/gmpc_easy_download.h>
#include <gmpc/metadata.h>

#define BASE_URL "http://www.ultimate-guitar.com"

gmpcPlugin plugin;
typedef struct Query {
    mpd_Song *song;
    void (*callback)(GList *, gpointer);
    gpointer user_data;
}Query;


static int guitartabs_get_enabled()
{
	return cfg_get_single_value_as_int_with_default(config, "guitartabs", "enable", TRUE);
}
static void guitartabs_set_enabled(int enabled)
{
	cfg_set_single_value_as_int(config, "guitartabs", "enable", enabled);
}

static int guitartabs_fetch_priority(void){
	return cfg_get_single_value_as_int_with_default(config, "guitartabs", "priority", 80);
}
static void guitartabs_fetch_priority_set(int priority){
	cfg_set_single_value_as_int(config, "guitartabs", "priority", priority);
}

static void tab_download_callback(const GEADAsyncHandler *handle, GEADStatus status, gpointer data)
{
	Query *q = (Query *)data;
	if(status == GEAD_PROGRESS) return;
    if(status == GEAD_DONE) 
    {
    	GList *list = NULL;
    	goffset size;
    	const char *data = gmpc_easy_handler_get_data(handle, &size);
    	GError *err = NULL;
    	GMatchInfo *info;
    	GRegex *re = g_regex_new("<pre>(.*)</pre>",G_REGEX_CASELESS|G_REGEX_DOTALL, 0, &err);
        if(!err)
        {
            g_regex_match_full(re,data,strlen(data),0,0,&info,&err);
            if(g_match_info_matches(info))
            {
            	GError *err=NULL;
                gchar *tab = g_match_info_fetch(info,1);
                gchar *tab_utf8   = g_convert(tab,strlen(tab),"utf8","ISO-8859-1",NULL,NULL,&err);
				if(!err)
				{
					MetaData *mtd = meta_data_new();
					mtd->type = META_SONG_GUITAR_TAB;
					mtd->plugin_name = plugin.name;
					mtd->content_type = META_DATA_CONTENT_TEXT;
					mtd->content = tab_utf8;
					list = g_list_append(list, mtd);
					printf("%s\n", mtd->content);

					q->callback(list,q->user_data);
				}
				else
				{
					printf("could not convert \n");
					g_error_free(err);
					err=NULL;
				}
				g_free(tab);
                return;
            }
            else{
                printf("did not match\n");
                /*Nothing Found */
                q->callback(NULL,q->user_data);
            }
        }
        if(err)
        {
            printf("error message: %s\n", err->message);
            g_error_free(err);
            err = NULL;
        }
    	
	}
	if(status == GEAD_FAILED || status == GEAD_CANCELLED)
    	q->callback(NULL,q->user_data);
    
    return;
}
static void query_callback(const GEADAsyncHandler *handle, GEADStatus status, gpointer data)
{
	Query *q = (Query *)data;
	if(status == GEAD_PROGRESS) return;
    if(status == GEAD_DONE) 
    {
    	 goffset size;
    	 const char *data = gmpc_easy_handler_get_data(handle, &size);
    	 GError *err = NULL;
    	 GMatchInfo *info;
	 	GRegex *re = g_regex_new("<a[\\s+]href=\"(/tabs/[\\w-]+/[\\w/.]+)\" class=\"song\">(.+)</a>",G_REGEX_CASELESS, 0, &err);
		 if(!err)
		 {
		 	g_regex_match_full(re,data,strlen(data),0,0,&info,NULL);
			 if (g_match_info_matches(info))
			 {
				gchar *link = g_strdup(g_match_info_fetch(info,1));
				gchar *tab_url = g_strdup_printf("%s%s",BASE_URL,link);
				gmpc_easy_async_downloader(tab_url,tab_download_callback,q);
				g_free(link);
				g_regex_unref (re);
				return;
			}
			else{
                printf("did not match\n");
                /*Nothing Found */
                q->callback(NULL,q->user_data);
            }
		}
		else
		{
			printf("error in regular expression\n");
			g_error_free(err);
			err=NULL;
		}		
		
	}
	if(status == GEAD_FAILED || status == GEAD_CANCELLED)
    	q->callback(NULL,q->user_data);
    
    return;
		 	
}



static void guitartabs_fetch(mpd_Song *song, MetaDataType type, void (*callback)(GList *list, gpointer data), gpointer user_data)
{
	//artist and title
	 if(song->artist != NULL &&song->title != NULL && type == META_SONG_GUITAR_TAB && 
			cfg_get_single_value_as_int_with_default(config, "guitartabs", "enable" , TRUE))
			{
				Query *q = g_malloc0(sizeof(*q));
				GError *err=NULL;
				GRegex *re = g_regex_new( "^The +" , G_REGEX_CASELESS, 0, &err);
				if(!err)
				{
					
					gchar *artist = gmpc_easy_download_uri_escape(song->artist);
					gchar *title = gmpc_easy_download_uri_escape(song->title);
					g_regex_replace(re,artist,strlen(artist),0,"",0,&err);
					q->song = song;
					q->callback = callback;
					q->user_data = user_data;
					
					gchar *query_url = g_strdup_printf("%s/search.php?bn=%s&sn=%s&sort_fld=rate&updown=down&f=tab",BASE_URL,artist,title);
					g_free(artist);
					g_free(title);
					g_regex_unref (re);
					gmpc_easy_async_downloader(query_url,query_callback,q);
					return;
				}
				else
				{
					printf("error in regular expression");
					g_error_free(err);
					err=NULL;
				}
			}
			/*Nothing Found */	
			callback(NULL, user_data);
			return ;
}
				
				
			

static void guitartabs_init()
{
	
}

gmpcMetaDataPlugin gt_meta = {
	.get_priority   = guitartabs_fetch_priority,
	.set_priority   = guitartabs_fetch_priority_set,
	.get_metadata = guitartabs_fetch
};

int plugin_api_version = PLUGIN_API_VERSION;

gmpcPlugin plugin = {
	.name           = "Guitar Tabs fetcher",
	.version        = {PLUGIN_MAJOR_VERSION,PLUGIN_MINOR_VERSION,PLUGIN_MICRO_VERSION},
	.plugin_type    = GMPC_PLUGIN_META_DATA,
    .init           = guitartabs_init,
	.metadata       = &gt_meta,
    .get_enabled    = guitartabs_get_enabled,
	.set_enabled    = guitartabs_set_enabled
};
