' =======
' GetInfo
' =======
' Version 1.0.0.7 - July 5th 2018
' Copyright © Steve MacGuire 2011-2018
' http://samsoft.org.uk/iTunes/GetInfo.vbs
' Please visit http://samsoft.org.uk/iTunes/scripts.asp for updates

' =======
' Licence
' =======
' 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 3 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.

' Please visit http://www.gnu.org/licenses/gpl-3.0-standalone.html to view the GNU GPLv3 licence.

' ===========
' Description
' ===========
' Reads & displays miscellaneous track information from iTunes.
' Modify to read any other data of interest that cannot be read in the iTunes interface.

' =========
' ChangeLog 
' =========
' Version 1.0.0.1 - Initial version
' Version 1.0.0.2 - Minor updates
' Version 1.0.0.3 - Display PersistentID
' Version 1.0.0.4 - Include Gapless property
' Version 1.0.0.5 - Minor updates
' Version 1.0.0.6 - Handle internet streams
' Version 1.0.0.7 - Tweak to suppress errors checking artwork in lost files & add TV show details


' ==========
' To-do List
' ==========
' Add things to do

Option Explicit
Dim A,AC,AD,AE,Count,F,FSO,I,iTunes,NL,P,R,T,tab,Title,Tracks

nl=vbCrLf
tab=Chr(9)
Title="Get Info"
Set iTunes=CreateObject("iTunes.Application")
Set FSO=CreateObject("Scripting.FileSystemObject")
Set Tracks=iTunes.SelectedTracks
If Tracks is Nothing Then Set Tracks=iTunes.BrowserWindow.SelectedTracks
If Tracks is Nothing Then Set Tracks=iTunes.BrowserWindow.SelectedPlaylist.Tracks
If Tracks is Nothing Then
  Count=0
Else 
  Count=Tracks.Count
End If
If Count=0 Then
  MsgBox "Please select some tracks before calling this script",vbExclamation,Title
Else
  I=1
' List properties here as required
' Refer to iTunes COM SDK to see what can be accessed via script commands
  Do
    T="Viewing" & tab & tab & I & " of " & Count & nl & nl
    With Tracks(I)
      T=T & "Track" & tab & tab & .TrackNumber
      If .TrackCount>0 And .TrackCount>=.TrackNumber Then T=T & " of " & .TrackCount & nl Else T=T & nl
      T=T & "Name" & tab & tab & .Name & nl
      T=T & "Artist" & tab & tab & .Artist & nl
      On Error Resume Next
      T=T & "Album Artist" & tab & .AlbumArtist & nl
      On Error Goto 0
      T=T & "Album" & tab & tab & .Album & nl & nl
      If (.Show & "")<>"" Then
      T=T & "Show" & tab & tab & .Show & nl
      T=T & "Season" & tab & tab & .SeasonNumber & nl
      T=T & "Episode" & tab & tab & .EpisodeNumber & nl
      T=T & "EpisodeID" & tab & tab & .EpisodeID & nl & nl
      End If      
      T=T & "Bitrate" & tab & tab & .Bitrate & nl
      T=T & "Grouping" & tab & tab & .Grouping & nl
      'T=T & "Work" & tab & tab & .Work & nl
      T=T & "Kind As String" & tab & .KindAsString & nl
      T=T & "Plays" & tab & tab & .PlayedCount & nl
      On Error Resume Next
      If .Size>0 Then T=T & "Skips" & tab & tab & .SkippedCount & nl
      On Error Goto 0
      T=T & "Last Played" & tab & FormatDate(.PlayedDate) & nl
      On Error Resume Next
      If .Size>0 Then T=T & "Last Skipped" & tab & FormatDate(.SkippedDate) & nl
      On Error Goto 0
      T=T & "Rating" & tab & tab & Int(.Rating/20) & " stars" & nl
      On Error Resume Next
      If .Size>0 Then T=T & "Remember Position" & tab & .RememberBookmark & nl
      If .Size>0 Then T=T & "Part Of Gapless" & tab & .PartOfGaplessAlbum & nl
      On Error Goto 0
      T=T & "Start" & tab & tab & FormatTime(.Start) & nl
      T=T & "Finish" & tab & tab & FormatTime(.Finish) & nl
      T=T & "Time" & tab & tab & .Time & nl
      On Error Resume Next
      If .Size>0 Then T=T & "Bookmark Time" & tab & FormatTime(.BookmarkTime) & nl
      If .Size>0 Then T=T & "Kind/Video Kind" & tab & .Kind & "/" & .VideoKind & nl
      If .Size>0 Then T=T & "Comments/Lyrics" & tab & (.Comment<>"") & "/" & (.Lyrics<>"") & nl      
      T=T & "Size" & tab & tab & FormatNumber(.Size,0,-2,-2,-2) & " bytes" & nl
      On Error Goto 0
      T=T & "Source" & tab & tab & Source(iTunes.BrowserWindow.SelectedPlaylist.Source.Kind) & nl
      T=T & "PersistentID" & tab & PersistentID(Tracks(I)) & nl
      T=T & "Artwork" & tab & tab
      On Error Resume Next
      If .Artwork.Count=0 Then
        T=T & "None"
      Else  
        AD=0
        AE=0
        For AC=1 To .Artwork.Count
          If .Artwork.Item(AC).IsDownloadedArtwork Then AD=AD+1 Else AE=AE+1
        Next
        If AD>0 Then T=T & AD & " downloaded"
        If AD>0 And AE>0 Then T=T & ", "
        If AE>0 Then T=T & AE & " embedded"        
      End If
      On Error Goto 0
      T=T & nl & nl
      P=""
      On Error Resume Next
      If .Size>0 Then P=.Location Else P=""
      On Error Goto 0
      If P=""  Then
        If .Size>0 Then P="<Unknown>" Else P="<iCloud/Stream>"
      Else
        A=FSO.GetAbsolutePathName(P)
        If A<>P Then T=T & "Abs. Path" & Wrap(A,37,"\",2) & nl
      End If
      T=T & "Path" & tab & tab & Wrap(P,37,"\",2) & nl
      If Count>1 Then T=T & nl & nl & "Yes : Last   -   No : Next   -   Cancel : Exit            "  
    End With
    If Count>1 Then
      R=MsgBox(T,vbQuestion+vbYesNoCancel,Title)
    Else
      R=MsgBox(T,vbQuestion+vbOKCancel,Title)
    End If
    If R=vbYes And I>1 Then I=I-1
    If R=vbNo And I<Count Then I=I+1
  Loop Until R=vbCancel Or R=vbOK
End If


' Format date as text
' Modified 2011-10-06
Function FormatDate(D)
  If D=0 Then
    FormatDate="Never"
  Else
    FormatDate=D
  End If
End Function


' Format time to hh:mm:ss.xxx 
' Modified 2014-02-19
Function FormatTime(T)
  Dim H,M,S,F
  If T<0 Then T=T+86400                 ' Watch for timer running over midnight
  F=T-Int(T)
  T=Int(T)
  S=Right("0" & (T Mod 60),2)
  M=Right("0" & ((T\60) Mod 60),2)    ' \ = Div operator for integer division
  H=T\3600
  If H>0 Then
    FormatTime=H & ":" & M & ":" & S
  Else
    FormatTime=M & ":" & S
    If Left(FormatTime,1)="0" Then FormatTime=Mid(FormatTime,2)
  End If
  If F>0 Then FormatTime=FormatTime & Mid(FormatNumber(F,3),2)
End Function


' Create a string representing the 64 bit persistent ID of an iTunes object
' Modified 2012-08-24
Function PersistentID(T)
  PersistentID=Right("0000000" & Hex(iTunes.ITObjectPersistentIDHigh(T)),8) & "-" & Right("0000000" & Hex(iTunes.ITObjectPersistentIDLow(T)),8)
End Function


' Return the persistent object representing the track, with exceptions for apps/games, streams & ringtones
' Keeps hold of an object that might vanish from a smart playlist as it is updated
' Modified 2012-10-17
Function PersistentObject(T)
  Dim K
  K=T.KindAsString
  If Instr(K," app") Or Instr("Internet audio stream/iPod game/Ringtone",K) Then  ' Ringtones seem to be invisible to scripts!
    Set PersistentObject=T
  Else
    Set PersistentObject=iTunes.LibraryPlaylist.Tracks.ItemByPersistentID(iTunes.ITObjectPersistentIDHigh(T),iTunes.ITObjectPersistentIDLow(T))
  End If  
End Function


' Return source kind as string
' Modified 2012-11-02
Function Source(K)
  Dim A
  A=Array("<Unknown>","Library","iPod","Audio CD","MP3 CD","Device","Radio Tuner","Shared Library")
  Source=A(K)
End Function


' Wrap & tab long strings, break string S after at least B characters on next character C adding T tabs to each new line
' Modified 2012-12-18
Function Wrap(S,B,C,T)
  Dim P
  P=Instr(B,S,C)
  If P Then Wrap=Left(S,P) & nl & String(T,tab) & Wrap(Mid(S,P+1),B,C,T) Else Wrap=S
End Function