#!/usr/bin/perl
use XML::Parser;
use DBI;

$mythtv_database	= "mythconverg";
$mythtv_hostname	= "localhost";
$mythtv_user		= "mythtv";
$mythtv_password	= "mythtv";
$mythtv_playlist_host = "po";
$file = "/av/music/iTunes/iTunes Music Library.xml";

sub trim {
	$_ = $_[0];
	s/^\s+//o;
	s/\s+$//o;
	return $_;
}

sub start_element {
	my ($self, $element) = @_;
	
	push(@current_xml_elements, $element);
}

sub end_element {
	my ($self, $element) = @_;
	
	if($element ne pop(@current_xml_elements)) {
		print "Unexpected name ".($element)." for popped element\n";
	}
	
	if($element eq 'key') {
		push(@current_plist_elements, trim($tag_data));
	} elsif($element eq 'integer' || $element eq 'string' ||
	        $element eq 'dict' || $element eq 'date' ||
	        $element eq 'true' || $element eq 'false' ||
	        $element eq 'array' || $element eq 'data') {
	    
	    if($current_xml_elements[$#current_xml_elements] ne "array") {
			$finished_plist_element = pop(@current_plist_elements);
		} else {
			$finished_plist_element = $current_plist_elements[$#current_plist_elements];
		}
		
		plist_element($finished_plist_element, $element, trim($tag_data));
	}
	
	$tag_data = '';
}

sub characters {
	my ($self, $data) = @_;
	
	$tag_data .= $data;
}

sub plist_element {
	my ($element_name, $element_type, $element_data) = @_;
	
	if($current_plist_elements[0] eq 'Tracks') {
		if($element_name eq 'Name') {
			$name = $element_data;
		} elsif($element_name eq 'Artist') {
			$artist = $element_data;
		} elsif($element_name eq 'Album') {
			$album = $element_data;
		} elsif(($element_name eq 'Disabled' || $element_name eq 'Has Video') && $element_type eq 'true') {
			$disabled = 1;
		} elsif($element_type eq 'dict') {
			if($name && $artist && !$disabled) {
				if(!$dbh) {
					$dbh = DBI->connect("DBI:mysql:database=".$mythtv_database.";host=".$mythtv_hostname, $mythtv_user, $mythtv_password);
					$dbh->do("LOCK TABLES musicplaylist WRITE, musicmetadata READ");
					$get_id = $dbh->prepare("SELECT intid FROM musicmetadata WHERE
					                         title = ? AND artist = ? ORDER BY album = ? DESC");
					$dbh->do("DELETE FROM musicplaylist WHERE playlistid > 2");
					$mythtv_playlist_host_quoted = $dbh->quote($mythtv_playlist_host);
				}
				
				$get_id->execute($name, $artist, $album);
				if(($id) = $get_id->fetchrow_array()) {
					$track_map[$element_name] = $id;
				} else {
					print "Could not map $artist - $name ($album)\n";
				}
				$get_id->finish();
			}
			$name = $artist = $album = $disabled = undef;
		}
	} elsif($current_plist_elements[0] eq 'Playlists') {
		if($element_name eq 'Name') {
			$name = $element_data;
		} elsif($element_name eq 'Track ID') {
			if($track_map[$element_data]) {
				$tracks .= ",".$track_map[$element_data];
			}
		} elsif($element_name eq 'Playlists' && $element_type eq 'dict') {
			if($tracks) {
				$values .= ",(NULL, ".($dbh->quote($name)).", ".$mythtv_playlist_host_quoted.", ".($dbh->quote(substr($tracks, 1))).")";
			}
			$name = $tracks = $undef;
		}
	} elsif($element_name eq 'Playlists' && $element_type eq 'array') {
			$dbh->do("INSERT INTO musicplaylist VALUES ".substr($values, 1));
			$dbh->do("UNLOCK TABLES");
	}
}

my $parser = new XML::Parser(Handlers => {Start	=> \&start_element,
                                          End	=> \&end_element,
                                          Char	=> \&characters});
$parser->parsefile($file);
