/***************************************************************************
    Copyright          : (C) 2002 by Neoworks Limited. All rights reserved
    URL                : http://www.neoworks.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.                                   *
 *                                                                         *
 ***************************************************************************/

/*
 * PlaylistBrowser.java
 *
 * Created on 23 April 2002, 16:44
 */

package com.neoworks.jukex.client.tui;

import com.neoworks.jukex.*;
import com.neoworks.jukex.tracksource.*;
import com.neoworks.jukex.query.*;
import com.neoworks.shout.*;
import com.neoworks.util.Escaper;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import java.util.*;
import java.net.URL;

import org.apache.log4j.*;

/**
 * Command line client. This is now quite out of date and needs to be brought into
 * line with the servlet based client.
 *
 * @author Nick Vincent (<a href="mailto:nick@neoworks.com">nick@neoworks.com</a>)
 * @author Nigel Atkinson (<a href="mailto:nigel@neoworks.com">nigel@neoworks.com</a>)
 */
public class PlaylistBrowser
{
	private static final Category log = Category.getInstance(PlaylistBrowser.class.getName());
	private static final boolean logDebugEnabled = log.isDebugEnabled();
	private static final boolean logInfoEnabled = log.isInfoEnabled();
	
	private static BufferedReader br = null;
	private static TrackStore ts = null;
	private static String configFile = null;
	private static Shouter sh = null;
	
	/**
	 * Public constructor
	 */
	public PlaylistBrowser()
	{
	}
	
	/**
	 * Entry point
	 *
	 * @param args the command line arguments
	 */
	public static void main(String[] args)
	{
		// initialise logging
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		//System.out.println( "Got classloader: " + loader.getClass().getName() );
		URL loggingPropertiesURL = loader.getResource( "logging.properties" );
		if (loggingPropertiesURL == null)
		{
                        Properties loggingProps = new Properties();
                        loggingProps.put("log4j.rootCategory","WARN, A1");
                        loggingProps.put("log4j.appender.A1","org.apache.log4j.FileAppender");
                        loggingProps.put("log4j.appender.A1.File","System.out");
                        loggingProps.put("log4j.appender.A1.layout","org.apache.log4j.PatternLayout");

                        // Print the date in ISO 8601 format
                        loggingProps.put("log4j.appender.A1.layout.ConversionPattern","%d [%t] %-5p %c - %m%n");
			//System.out.println("Configuring logging without properties file");
                        PropertyConfigurator.configure(loggingProps);
		} else {
			//System.out.println( "Got URL: " + loggingPropertiesURL );
			PropertyConfigurator.configure( loggingPropertiesURL );
		}
						
		if (args.length < 1)
		{
			System.out.println("Where's the feckin config then?");
			System.exit(0);
		} else {
			configFile = args[0];
		}
		br = new BufferedReader( new InputStreamReader( System.in ) );
		String query = null;
		
		System.out.println("JukeX Playlist Browser 0.1");
		while (true)
		{
			System.out.println("0 - List all playlists");
			System.out.println("1 - Show a playlist");
			System.out.println("2 - Add tracks to a playlist");
			System.out.println("3 - Clear a playlist");
			System.out.println("4 - Create a new playlist\n");
			System.out.println("p - Play");
			System.out.println("\" - Pause");
			System.out.println("s - Stop");
			System.out.println("f - Skip forward\n");
			System.out.println("q - Quit");
			query = getInput();

			if ( query.startsWith( "q" ))
			{
				quit();
			} else if (query.startsWith("0")) {
				listPlaylists();
			} else if (query.startsWith("1")) {
				System.out.println("Name: ");
				query = getInput();
				getPlaylist(query);
			} else if (query.startsWith("2")) {
				System.out.println("Name: ");
				String name = getInput();
				System.out.println("Query: ");
				query = getInput();
				addTracksToPlaylist(name, query);
			} else if (query.startsWith("3")) {
				System.out.println("Name: ");
				query = getInput();
				clearPlaylist(query);
			} else if (query.startsWith("p")) {
				if (sh == null)
				{
					System.out.println("Name: ");
					query = getInput();
				}
				/*System.out.println("Server name: ");
				String serverName = getInput();
				System.out.println("Server port: ");
				String serverPort = getInput();
				int portNo = Integer.parseInt(serverPort);
				System.out.println("Server password: ");
				String serverPassword = getInput();*/
				sendPlaylistToServer(query/*, serverName, portNo, serverPassword*/);
			} else if (query.startsWith("s")) {
				stopPlaying();
			} else if (query.startsWith("f")) {
				skipTrack();
			} else if (query.startsWith("\"")) {
				pauseTrack();
			} else if (query.startsWith("4")) {
				System.out.println("Name: ");
				query = getInput();
				createPlaylist(query);
			}
		}
	}

	private static void listPlaylists()
	{
		if (ts == null)
			ts = TrackStoreFactory.getTrackStore();
		Collection c = ts.getAllPlaylists();
		Iterator i = c.iterator();
		Playlist p = null;
		while (i.hasNext())
		{
			p = (Playlist)i.next();
			System.out.println(p.getName());
		}
	}

	private static void skipTrack()
	{
		sh.skip();
	}

	private static void pauseTrack()
	{
		sh.pause();
	}

	private static void stopPlaying()
	{
		sh.cpStop();
		sh = null;
	}

	private static void sendPlaylistToServer(String playlist/*, String serverName, int serverPort, String serverPassword*/)
	{
		if (sh == null)
		{
			if (ts == null)
				ts = TrackStoreFactory.getTrackStore();

			TrackSource p = (TrackSource)ts.getPlaylist( playlist );
			Stream s = new Stream();
			try {
				s.loadConfig(configFile);
				/*s.setServerName(serverName);
				s.setPort(serverPort);
				s.setPassword(serverPassword);*/
				sh = ShouterFactory.getShouter();
				sh.setStream(s);
				sh.setTrackSource(p);
				sh.play();
			} catch (Exception e) {
				log.warn(e);
			}
		} else {
			sh.play();
		}
	}

	private static void quit()
	{
		System.out.println("Bye then.");
		System.exit( 0 );
	}

	private static void clearPlaylist(String name)
	{
		if (ts == null)
			ts = TrackStoreFactory.getTrackStore();

		Playlist p = ts.getPlaylist( name );
		if ( p == null )
		{
			System.out.println( "Cannot find a playlist named <" + name + ">" );
		} else {
			p.clear();
		}
	}

	private static void getPlaylist(String name)
	{
		if (ts == null)
			ts = TrackStoreFactory.getTrackStore();

		Playlist p = ts.getPlaylist( name );
		if ( p == null )
		{
			System.out.println( "Cannot find a playlist named <" + name + ">" );
		} else {
			System.out.println("Track listing:");
			System.out.println(p);
		}
	}

	private static void addTracksToPlaylist(String name, String query)
	{
		if (ts == null)
			ts = TrackStoreFactory.getTrackStore();
		Playlist p = ts.getPlaylist(name);
		if (p == null)
		{
			System.out.println("Cannot find a playlist named <" + name + ">");
		} else {
			try
			{
				Query q = ((JukeXParser)JukeXParser.createParser( Escaper.SQLEscape(query) )).parse();
				List tracks = q.getTracks();

				Iterator i = tracks.iterator();

				while ( i.hasNext() )
				{
					Track currtrack = (Track) i.next();
					p.add( currtrack );
				}

				System.out.println( p );
			}
			catch ( Exception e )
			{
				System.err.println( e.getMessage() );
				e.printStackTrace( System.err );
			}
		}
	}

	private static void createPlaylist(String name)
	{
		if (ts == null)
			ts = TrackStoreFactory.getTrackStore();

		Playlist p = ts.getPlaylist( name );
		if ( p == null )
		{
			p = ts.createPlaylist( name );
			System.out.println( "Created a playlist named <" + name + ">" );
		} else {
			System.out.println("A playlist named <" + name + "> already exists"); 
		}
	}

	private static String getInput()
	{
		String query = "";
		try {
			query = br.readLine();
		} catch ( Exception e ) {
		}
		return query;
	}
}
