=begin
== sp.rb
Subtitle processor Ruby Interface

=end

=begin
==SP module
General SubtitleProcessor functions.
=end

module SPInterfaceC
  # Time mode constants
  # Time
  SP_TIMEMODE_TIME = 1
  # Frames
  SP_TIMEMODE_FRAMES = 2
end

module SPInterface
  include SPInterfaceC
end


=begin
==Player module
Interface functions for communication with the Player and Player window.  
=end
module SPPlayerInterfaceC
  # Player state
  # To  determine the player state, use these constants.
  # No file loaded
  PLAYER_STATE_NO_FILE=0
  # Paused playback
  PLAYER_STATE_PAUSED=1
  # Currently playing
  PLAYER_STATE_PLAYING=2
  # Stopped playback
  PLAYER_STATE_STOPPED=3

  # Player Mode
  # Normal multimedia file (AVI, mkv etc.)
  PLAYER_MODE_NORMAL=0
  # DVD disc
  PLAYER_MODE_DVD=1
  # Capture from signal source
  PLAYER_MODE_CAPTURE=1  
end

module SPPlayerInterface
  include SPPlayerInterfaceC
end


=begin
==User Interface module
Functions to enable user interactions with the script.
=end
module SPUIInterfaceC
  # Dialog result
  # Result of message box dialog
  # OK button
  ID_OK = 1
  # Cancel button
  ID_CANCEL = 2
  # Abort button
  ID_ABORT = 3
  # Retry button
  ID_RETRY = 4
  # Ignore button
  ID_IGNORE = 5
  # Yes button
  ID_YES = 6
  # No button
  ID_NO = 7
  
  # Buttons
  # What buttons shall appear in message box
  # OK button
  MB_OK = 0
  #OK and Cancel buttons
  MB_OKCANCEL = 1
  # Abort, Retry and Ignore buttons
  MB_ABORTRETRYIGNORE = 2
  # Yes, No and Cancel buttons
  MB_YESNOCANCEL = 3
  # Yes and No buttons
  MB_YESNO = 4
  # Retry and Cancel buttons
  MB_RETRYCANCEL = 5
  
  # Message box type
  # Custom type
  DLG_MT_CUSTOM = 0
  # Information (i) icon
  DLG_MT_INFORMATION = 1
  # Warning (!) icon
  DLG_MT_WARNING = 2
  # Error (x) icon
  DLG_MT_ERROR = 3
  # Confirmation (?) icon
  DLG_MT_CONFIRMATION = 4
  
end
module SPUIInterface
  include SPUIInterfaceC
end


=begin
==Subtitles module
Module used to manipulate subtitles collections in SP. 
=end
module SPSubsInterfaceC

  # Subtitles number
  # First subtitles
  SUBS_FIRST = 1
  # Second subtitles
  SUBS_SECOND = 2
end

module SPSubsInterface
  include SPSubsInterfaceC

  # Property  number
  # Use this to specify which property should be manipulated by a particular 
  # getter or setter function - what_prop parameter. Always use the constants, 
  # the actual numbers may change in future versions of SP.
  SUBS_STRING_TITLE=1
  SUBS_STRING_AUTHOR=2
  SUBS_STRING_TRANSLATED_BY=3
  SUBS_STRING_EDITED_BY=4
  SUBS_STRING_TIMED_BY=5
  SUBS_STRING_CHECKED_BY=6
  SUBS_STRING_SYNCH_POINT=7
  SUBS_STRING_UPDATE_AUTHOR=8
  SUBS_STRING_UPDATE_DETAILS=9
  SUBS_STRING_DEFAULT_STYLE_OVERRIDE=10

  SUBS_FLOAT_FPS = 101
  SUBS_FLOAT_TIMER_SPEED = 102
  SUBS_FLOAT_TIMER_SHIFT = 103
  
  SUBS_INT_CHARSET = 201
  SUBS_INT_PLAYRES_X = 202
  SUBS_INT_PLAYRES_Y = 203
  SUBS_INT_PLAYRES_BPP = 204
  SUBS_INT_WORDWRAP = 205
  SUBS_INT_COLLISIONS = 206
  
  SUBS_BOOL_CHANGED = 301  
end


=begin
==Subtitle module
Module used to manipulate single subtitles in the subtitles collections.
=end
module SPSubInterfaceC
  # Property  number
  # Use this to specify which property should be manipulated by a particular getter 
  # or setter function - what_prop parameter. Always use the constants, the actual 
  # numbers may change in future versions of SP.
  
  # Integer
  SUB_SF = 1
  SUB_EF = 2
  SUB_REF = 3                    #get only
  SUB_NSF = 4                    #get only
  SUB_DURATION_F = 5             #get only
  SUB_MARGIN_L = 13
  SUB_MARGIN_R = 14
  SUB_MARGIN_V = 15
  SUB_MARGIN_V2 = 16
  SUB_TEXT_CHAR_COUNT = 21       #get only
  SUB_LINE_COUNT = 22
  
  # Floating point
  SUB_ST = 6
  SUB_ET = 7
  SUB_RET = 8                    #get only
  SUB_NST = 9                    #get only
  SUB_DURATION_T = 10            #get only
  
  # String
  SUB_STYLE = 11
  SUB_PAINT_STYLE = 12           #get only
  SUB_CHARACTER_NAME = 17
  SUB_EFFECT = 18
  SUB_TEXT_DELIMITER = 19
  SUB_TEXT = 20
  
  # Line properties
  SUB_LINE_TEXT = 23
  SUB_LINE_STYLE = 24
  SUB_LINE_POS_X = 25
  SUB_LINE_POS_Y = 26  
end
module SPSubInterface
  include SPSubInterfaceC
end


=begin
==Styles module
Module used to manipulate style collections.
=end
module SPStylesInterfaceC
  # Styles number
  # To specify which styles collection shall be manipulated, use these constants:
  STYLES_MAIN = 0  
end
module SPStylesInterface
  include SPStylesInterfaceC
end



=begin
==Style module
Module for manipulating single styles in the styles collection.
=end
module SPStyleInterfaceC
  # Border style
  # Possible values for Border style property:
  STYLE_P_BST_DEFAULT = -1
  STYLE_P_BST_OUTLINE = 1
  STYLE_P_BST_BOX = 3

  # Subtitle position
  # Possible value for position of subtitles
  STYLE_P_SUBPOS_DEFAULT = -1
  STYLE_P_SUBPOS_BOTTOM = 0
  STYLE_P_SUBPOS_CENTER = 1
  STYLE_P_SUBPOS_TOP = 2

  # Subtitle text align
  STYLE_P_SUBALIGN_DEFAULT = -1
  STYLE_P_SUBALIGN_LEFT = 1
  STYLE_P_SUBALIGN_CENTER = 2
  STYLE_P_SUBALIGN_RIGHT = 3  
  
end
module SPStyleInterface
  include SPStyleInterfaceC
  
  # Property  number
  # Use this to specify which property should be manipulated by a particular 
  # getter or setter function - what_prop parameter. Always use the constants, 
  # the actual numbers may change in future versions of SP.
  # Boolean
  STYLE_RESOLVE = 1
  STYLE_LOCAL = 2
  STYLE_EMBEDABLE = 3
  STYLE_FONT_B = 4
  STYLE_FONT_I = 5
  STYLE_FONT_U = 6
  STYLE_FONT_S = 7
  # Text
  STYLE_NAME = 11
  STYLE_FONT_NAME = 12
  # Floating point
  STYLE_ASS_ANGLE = 31
  # Integer
  STYLE_FONT_SIZE = 41
  STYLE_FONT_CHARSET = 42
  STYLE_COLOR1 = 43
  STYLE_COLOR2 = 44
  STYLE_COLOR3 = 45
  STYLE_COLORS = 46
  STYLE_BORDER_STYLE = 47
  STYLE_OUTLINE_W = 48
  STYLE_SHADOW_W = 49
  STYLE_SUB_POSITION = 50
  STYLE_ALIGN = 51
  STYLE_MARGIN_L = 52
  STYLE_MARGIN_R = 53
  STYLE_MARGIN_V = 54
  STYLE_MARGIN_V2 = 55
  STYLE_ASS_SCALE_X = 56
  STYLE_ASS_SCALE_Y = 57
  STYLE_ASS_SPACING = 58
  STYLE_COLOR1_ALPHA = 59
  STYLE_COLOR2_ALPHA = 60
  STYLE_COLOR3_ALPHA = 61
  STYLE_COLORS_ALPHA = 62
  STYLE_INDEX = 63            #get only
end


module SPEditorInterface
  
end

## ======================================================================== SubtitleLine
=begin
==SubtitleLine
Class representing single line of subtitle with properties
=end
class SubtitleLine
  def initialize(subs, sub, line)
    @subs_no = subs
    @sub_no = sub
    @line_no = line
  end
  
  def get_property(what_prop)
    prop_value = SPSubInterface.get_subtitle_line_prop(@subs_no, @sub_no, @line_no, what_prop)
    raise "Reference to invalid subtitles (#{@subs_no}), subtitle (#{@sub_no}), line (#{@line_no}) or property(#{what_prop})" if prop_value.nil?
    prop_value
  end
  
  def set_property(what_prop, prop_val)
    ret_value = SPSubInterface.set_subtitle_line_prop(@subs_no, @sub_no, @line_no, what_prop, prop_val)
    raise "Reference to invalid subtitles (#{@subs_no}), subtitle (#{@sub_no}), line (#{@line_no}) or property(#{what_prop})" unless ret_val
    prop_val
  end
  
  ## Properties -----------------------------------------------------------------
  def text
    get_property(SUB_LINE_TEXT)
  end
  
  def text= (value)
    set_property(SUB_LINE_TEXT, value)
    value
  end
  
  def style
    get_property(SUB_LINE_STYLE)
  end
  
  def style= (value)
    set_property(SUB_LINE_STYLE, value)
    value
  end
  
  def pos_x
    get_property(SUB_LINE_POS_X)
  end
  
  def pos_x= (value)
    set_property(SUB_LINE_POS_X, value)
    value
  end
  
  def pos_y
    get_property(SUB_LINE_POS_Y)
  end
  
  def pos_y= (value)
    set_property(SUB_LINE_POS_Y, value)
    value
  end
end

#Helper class
class LineGetter
  
  def initialize(subs, sub)
    @subs_no = subs
    @sub_no = sub
  end
  
  def [](i)
    line_count = SPSubInterface.get_subtitle_int_prop(@subs_no, @sub_no, SUB_LINE_COUNT)
    return nil if (line_count.nil? or (i < 0) or (i >= line_count))
    
    SubtitleLine.new(@subs_no, @sub_no, i)
  end
end

## ======================================================================== Subtitle
=begin
==Subtitle
Class that represents single subtitle in Ruby. Internally it holds reference to
Subtitles collection and also a subtitle number. It's methods only call SPSubInterface 
methods, passing the internal references.
=end
class Subtitle
  include SPSubInterface  
  # Constructor
  def initialize(subs, sub)
    @subs_no = subs
    @sub_no = sub
    @line_getter = LineGetter.new(@subs_no, @sub_no)
  end
  
  attr_reader :subs_no
  attr_reader :sub_no
  
  # Getter
  def get_property(what_prop)
    prop_value = nil
    case what_prop
      when
          SUB_SF,
          SUB_EF,
          SUB_REF,
          SUB_NSF,
          SUB_DURATION_F,
          SUB_MARGIN_L ,
          SUB_MARGIN_R,
          SUB_MARGIN_V,
          SUB_MARGIN_V2,
          SUB_TEXT_CHAR_COUNT,
          SUB_LINE_COUNT 
        prop_value = SPSubInterface.get_subtitle_int_prop(@subs_no, @sub_no, what_prop)
      when  
          SUB_ST,
          SUB_ET,
          SUB_RET,
          SUB_NST,
          SUB_DURATION_T
        prop_value = SPSubInterface.get_subtitle_float_prop(@subs_no, @sub_no, what_prop)
      when  
          SUB_STYLE, 
          SUB_PAINT_STYLE, 
          SUB_CHARACTER_NAME, 
          SUB_EFFECT, 
          SUB_TEXT_DELIMITER, 
          SUB_TEXT
        prop_value = SPSubInterface.get_subtitle_string_prop(@subs_no, @sub_no, what_prop)
      else
        raise ArgumentError, "Invalid property ID (#{what_prop})"
    end
    raise ArgumentError, "Reference to invalid subtitles (#{@subs_no}) or subtitle (@sub_no)" if prop_value.nil?
    prop_value  
  end
  
  # Setter
  def set_property(what_prop, prop_val)
    ret_val = false
    case what_prop
      when
          SUB_SF,
          SUB_EF,
          SUB_REF,
          SUB_NSF,
          SUB_DURATION_F,
          SUB_MARGIN_L ,
          SUB_MARGIN_R,
          SUB_MARGIN_V,
          SUB_MARGIN_V2,
          SUB_TEXT_CHAR_COUNT,
          SUB_LINE_COUNT 
        ret_val = SPSubInterface.set_subtitle_int_prop(@subs_no, @sub_no, what_prop, prop_val)
      when  
          SUB_ST,
          SUB_ET,
          SUB_RET,
          SUB_NST,
          SUB_DURATION_T
        ret_val = SPSubInterface.set_subtitle_float_prop(@subs_no, @sub_no, what_prop, prop_val)
      when  
          SUB_STYLE, 
          SUB_CHARACTER_NAME, 
          SUB_EFFECT, 
          SUB_TEXT_DELIMITER, 
          SUB_TEXT
        ret_val = SPSubInterface.set_subtitle_string_prop(@subs_no, @sub_no, what_prop, prop_val)
      else
        raise ArgumentError, "Invalid property ID (#{what_prop})"
    end
    raise ArgumentError, "Reference to invalid subtitles (#{@subs_no}) or subtitle (@sub_no)" unless ret_val
    ret_val  
  end
  
  ## Properties -----------------------------------------------------------------
  def sf
    get_property(SUB_SF)
  end
  
  def sf= (value)
    set_property(SUB_SF, value)
    value
  end
  
  def ef
    get_property(SUB_EF)
  end
  
  def ef= (value)
    set_property(SUB_EF, value)
    value
  end

  def ref
    get_property(SUB_REF)
  end
  
  def nsf
    get_property(SUB_NSF)
  end

  def duration_f
    get_property(SUB_DURATION_F)
  end
  
  def margin_l
    get_property(SUB_MARGIN_L)
  end
  
  def margin_l= (value)
    set_property(SUB_MARGIN_L, value)
    value
  end

  def margin_r
    get_property(SUB_MARGIN_R)
  end
  
  def margin_r= (value)
    set_property(SUB_MARGIN_R, value)
    value
  end

  def margin_v
    get_property(SUB_MARGIN_V)
  end
  
  def margin_v= (value)
    set_property(SUB_MARGIN_V, value)
    value
  end

  def margin_v2
    get_property(SUB_MARGIN_V2)
  end
  
  def margin_v2= (value)
    set_property(SUB_MARGIN_V2, value)
    value
  end

  def text_char_count
    get_property(SUB_TEXT_CHAR_COUNT)
  end
  
  def line_count
    get_property(SUB_LINE_COUNT)
  end
  
  def line_count= (value)
    set_property(SUB_LINE_COUNT, value)
    value
  end

  def st
    get_property(SUB_ST)
  end
  
  def st= (value)
    set_property(SUB_ST, value)
    value
  end

  def et
    get_property(SUB_ET)
  end
  
  def et= (value)
    set_property(SUB_ET, value)
    value
  end

  def ret
    get_property(SUB_RET)
  end

  def nst
    get_property(SUB_NST)
  end

  def duration_t
    get_property(SUB_DURATION_T)
  end
  
  def style
    get_property(SUB_STYLE)
  end
  
  def style= (value)
    set_property(SUB_STYLE, value)
    value
  end

  def paint_style
    get_property(SUB_PAINT_STYLE)
  end
  
  def effect
    get_property(SUB_EFFECT)
  end
  
  def effect= (value)
    set_property(SUB_EFFECT, value)
    value
  end
  
  def text_delimiter
    get_property(SUB_TEXT_DELIMITER)
  end
  
  def text_delimiter= (value)
    set_property(SUB_TEXT_DELIMITER, value)
    value
  end

  def text
    get_property(SUB_TEXT)
  end
  
  def text= (value)
    set_property(SUB_TEXT, value)
    value
  end
  
  def lines
    @line_getter
  end
  
  ## Methods -----------------------------------------------------------------
  def recalc_fps
    SPSubInterface.recalc_fps(@subs_no, @sub_no)
  end

  def shift_f(delta)
    SPSubInterface.shift_f(@subs_no, @sub_no, delta)
  end
  
  def shift_t(delta)
    SPSubInterface.shift_t(@subs_no, @sub_no, delta)
  end
  
  def clear
    SPSubInterface.clear(@subs_no, @sub_no)
  end
  
  def text_remove_line(line_no)
    SPSubInterface.text_remove_line(@subs_no, @sub_no, line_no)
  end
  
  def check_sub_length(max_length)
    SPSubInterface.check_sub_length(@subs_no, @sub_no, max_length)
  end
  
  def swap_content(subtitle)
    SPSubInterface.swap_content(@subs_no, @sub_no, subtitle.subs_no, subtitle.sub_no)
  end
  
end


## ======================================================================== Subtitles
##Class for getting subtitle by index
class SubtitleGetter

  def initialize(subs)
    @subs_no = subs
  end
  
  def [](i)
    subs_count = SPSubsInterface.get_subtitles_count(@subs_no)
    return nil if (subs_count.nil? or (i < 0) or (i >= subs_count))
    
    Subtitle.new(@subs_no, i)
  end
  
end


## ----------------------------------------------------------------------- Subtitles
=begin
==Subtitles
Class that represents subtitles collection.
=end
class Subtitles
  include SPSubsInterface, SPInterface
  
  def initialize(subs)
    @subs_no = subs
    @subs_getter = SubtitleGetter.new(@subs_no)
  end
  
  # Getter
  def get_property(what_prop)
    prop_value = nil
    case what_prop
      when
          SUBS_STRING_TITLE,
          SUBS_STRING_AUTHOR,
          SUBS_STRING_TRANSLATED_BY,
          SUBS_STRING_EDITED_BY,
          SUBS_STRING_TIMED_BY,
          SUBS_STRING_CHECKED_BY,
          SUBS_STRING_SYNCH_POINT,
          SUBS_STRING_UPDATE_AUTHOR,
          SUBS_STRING_UPDATE_DETAILS,
          SUBS_STRING_DEFAULT_STYLE_OVERRIDE
        prop_value = SPSubsInterface.get_subtitles_string_prop(@subs_no, what_prop)  
      when
          SUBS_FLOAT_FPS,
          SUBS_FLOAT_TIMER_SPEED,
          SUBS_FLOAT_TIMER_SHIFT
        prop_value = SPSubsInterface.get_subtitles_float_prop(@subs_no, what_prop)  
      when  
          SUBS_INT_CHARSET,
          SUBS_INT_PLAYRES_X,
          SUBS_INT_PLAYRES_Y,
          SUBS_INT_PLAYRES_BPP,
          SUBS_INT_WORDWRAP,
          SUBS_INT_COLLISIONS,
        prop_value = SPSubsInterface.get_subtitles_int_prop(@subs_no, what_prop)
      when    
          SUBS_BOOL_CHANGED
        prop_value = SPSubsInterface.get_subtitles_bool_prop(@subs_no, what_prop)  
      else
        raise ArgumentError, "Invalid property ID (#{what_prop})"
    end
    raise ArgumentError, "Reference to invalid subtitles (#{@subs_no})" if prop_value.nil?
    prop_value  
  end
  
  # Setter
  def set_property(what_prop, prop_val)
    ret_val = false
    case what_prop
      when
          SUBS_STRING_TITLE,
          SUBS_STRING_AUTHOR,
          SUBS_STRING_TRANSLATED_BY,
          SUBS_STRING_EDITED_BY,
          SUBS_STRING_TIMED_BY,
          SUBS_STRING_CHECKED_BY,
          SUBS_STRING_SYNCH_POINT,
          SUBS_STRING_UPDATE_AUTHOR,
          SUBS_STRING_UPDATE_DETAILS,
          SUBS_STRING_DEFAULT_STYLE_OVERRIDE
        ret_val = SPSubsInterface.set_subtitles_string_prop(@subs_no, what_prop, prop_val)  
      when
          SUBS_FLOAT_FPS,
          SUBS_FLOAT_TIMER_SPEED,
          SUBS_FLOAT_TIMER_SHIFT
        ret_val = SPSubsInterface.set_subtitles_float_prop(@subs_no, what_prop, prop_val)  
      when  
          SUBS_INT_CHARSET,
          SUBS_INT_PLAYRES_X,
          SUBS_INT_PLAYRES_Y,
          SUBS_INT_PLAYRES_BPP,
          SUBS_INT_WORDWRAP,
          SUBS_INT_COLLISIONS,
        ret_val = SPSubsInterface.set_subtitles_int_prop(@subs_no, what_prop, prop_val)
      when    
          SUBS_BOOL_CHANGED
        ret_val = SPSubsInterface.set_subtitles_bool_prop(@subs_no, what_prop, prop_val)  
      else
        raise ArgumentError, "Invalid property ID (#{what_prop})"
    end
    raise ArgumentError, "Reference to invalid subtitles (#{@subs_no})" unless ret_val
    prop_val  
  end
  
  ## Properties -----------------------------------------------------------------
  
  # Number of subtitles in this collection
  def count
    cnt = SPSubsInterface.get_subtitles_count(@subs_no)
    return 0 if cnt.nil?
    return 0 if cnt < 0
    cnt
  end
  
  # Main mode of timestamps
  def time_mode
    tm_mode = SPSubsInterface.get_subtitles_time_mode(@subs_no)
    if tm_mode == SP_TIMEMODE_FRAMES
      SP_TIMEMODE_FRAMES
    else
      SP_TIMEMODE_TIME
    end
  end
  
  def time_mode= (value)
    SPSubsInterface.set_subtitles_time_mode(@subs_no, value)
    value
  end
  
  def title
    get_property(SUBS_STRING_TITLE)
  end
  
  def title= (value)
    set_property(SUBS_STRING_TITLE, value)
    value
  end
  
  def author
    get_property(SUBS_STRING_AUTHOR)
  end
  
  def author= (value)
    set_property(SUBS_STRING_AUTHOR, value)
    value
  end
  
  def translated_by
    get_property(SUBS_STRING_TRANSLATED_BY)
  end
  
  def translated_by= (value)
    set_property(SUBS_STRING_TRANSLATED_BY, value)
    value
  end
  
  def edited_by
    get_property(SUBS_STRING_EDITED_BY)
  end
  
  def edited_by= (value)
    set_property(SUBS_STRING_EDITED_BY, value)
    value
  end
  
  def timed_by
    get_property(SUBS_STRING_TIMED_BY)
  end
  
  def timed_by= (value)
    set_property(SUBS_STRING_TIMED_BY, value)
    value
  end
  
  def checked_by
    get_property(SUBS_STRING_CHECKED_BY)
  end
  
  def checked_by= (value)
    set_property(SUBS_STRING_CHECKED_BY, value)
    value
  end
  
  def synch_point
    get_property(SUBS_STRING_SYNCH_POINT)
  end
  
  def synch_point= (value)
    set_property(SUBS_STRING_SYNCH_POINT, value)
    value
  end
  
  def update_author
    get_property(SUBS_STRING_UPDATE_AUTHOR)
  end
  
  def update_author= (value)
    set_property(SUBS_STRING_UPDATE_AUTHOR, value)
    value
  end
  
  def update_details
    get_property(SUBS_STRING_UPDATE_DETAILS)
  end
  
  def update_details= (value)
    set_property(SUBS_STRING_UPDATE_DETAILS, value)
    value
  end
  
  def default_style_override
    get_property(SUBS_STRING_DEFAULT_STYLE_OVERRIDE)
  end
  
  def default_style_override= (value)
    set_property(SUBS_STRING_DEFAULT_STYLE_OVERRIDE, value)
    value
  end
  
  def fps
    get_property(SUBS_FLOAT_FPS)
  end
  
  def fps= (value)
    set_property(SUBS_FLOAT_FPS, value)
    value
  end
  
  def timer_speed
    get_property(SUBS_FLOAT_TIMER_SPEED)
  end
  
  def timer_speed= (value)
    set_property(SUBS_FLOAT_TIMER_SPEED, value)
    value
  end
  
  def timer_shift
    get_property(SUBS_FLOAT_TIMER_SHIFT)
  end
  
  def timer_shift= (value)
    set_property(SUBS_FLOAT_TIMER_SHIFT, value)
    value
  end
  
  def charset
    get_property(SUBS_INT_CHARSET)
  end
  
  def charset= (value)
    set_property(SUBS_INT_CHARSET, value)
    value
  end
  
  def playres_x
    get_property(SUBS_INT_PLAYRES_X)
  end
  
  def playres_x= (value)
    set_property(SUBS_INT_PLAYRES_X, value)
    value
  end
  
  def playres_y
    get_property(SUBS_INT_PLAYRES_Y)
  end
  
  def playres_y= (value)
    set_property(SUBS_INT_PLAYRES_Y, value)
    value
  end
  
  def playres_bpp
    get_property(SUBS_INT_PLAYRES_BPP)
  end
  
  def playres_bpp= (value)
    set_property(SUBS_INT_PLAYRES_BPP, value)
    value
  end
  
  def wordwrap
    get_property(SUBS_INT_WORDWRAP)
  end
  
  def wordwrap= (value)
    set_property(SUBS_INT_WORDWRAP, value)
    value
  end
  
  def collisions
    get_property(SUBS_INT_COLLISIONS)
  end
  
  def collisions= (value)
    set_property(SUBS_INT_COLLISIONS, value)
    value
  end

  def changed?
    get_property(SUBS_BOOL_CHANGED)
  end
  
  def changed= (value)
    set_property(SUBS_BOOL_CHANGED, value)
    value
  end
  
  def subs
    @subs_getter
  end
  
  ## Methods -----------------------------------------------------------------
  def add_subtitle
    SPSubsInterface.add_subtitle(@subs_no)
  end

  def delete_subtitle(sub_no)
    SPSubsInterface.delete_subtitle(@subs_no, sub_no)
  end
  
  def insert_subtitle(where)
    SPSubsInterface.insert_subtitle(@subs_no, where)
  end
  
  def insert_subtitle
    SPSubsInterface.insert_subtitle(@subs_no)
  end
  
  def disable_index_updates
    SPSubsInterface.disable_index_updates(@subs_no)
  end
  
  def enable_index_updates
    SPSubsInterface.enable_index_updates(@subs_no)
  end
  
  def enable_index_updates_immediate
    SPSubsInterface.enable_index_updates_immediate(@subs_no)
  end
  
  def sort_subtitles(increasing)
    SPSubsInterface.sort_subtitles(@subs_no, increasing)
  end
  
  def get_indices(frame_no)
    SPSubsInterface.get_indices(@subs_no, frame_no)
  end
  
  def get_unsynced_cnt
    SPSubsInterface.get_unsynced_cnt(@subs_no)
  end
  
  def get_unsynced(unsynced_index)
    SPSubsInterface.get_unsynced(@subs_no, unsynced_index)
  end
  
  def get_next_unsynced(index)
    SPSubsInterface.get_next_unsynced(@subs_no, index)
  end
  
end


## ----------------------------------------------------------------------- SPFont
=begin
==SPFont
Helper class for grouping style's font properties. Requires parent style reference
when creating instance
=end
class SPFont
  include SPStyleInterface

  # Create with reference to parent style
  def initialize(style)
    @style = style
  end
  
  # Bold
  def b?
    @style.get_property(STYLE_FONT_B)
  end
  
  def b= (value)
    @style.set_property(STYLE_FONT_B, value)
    value
  end
  
  #Italic
  def i?
    @style.get_property(STYLE_FONT_I)
  end
  
  def i= (value)
    @style.set_property(STYLE_FONT_I, value)
    value
  end

  #Underline 
  def u?
    @style.get_property(STYLE_FONT_U)
  end
  
  def u= (value)
    @style.set_property(STYLE_FONT_U, value)
    value
  end
   
  #Strike Out
  def s?
    @style.get_property(STYLE_FONT_S)
  end
  
  def s= (value)
    @style.set_property(STYLE_FONT_S, value)
    value
  end
  
  #Font name
  def name
    @style.get_property(STYLE_FONT_NAME)
  end
  
  def name= (value)
    @style.set_property(STYLE_FONT_NAME, value)
    value
  end
  
  #Size in pixels
  def size
    @style.get_property(STYLE_FONT_SIZE)
  end
  
  def size= (value)
    @style.set_property(STYLE_FONT_SIZE, value)
    value
  end
  
  #Windows charset
  def charset
    @style.get_property(STYLE_FONT_CHARSET)
  end
  
  def charset= (value)
    @style.set_property(STYLE_FONT_CHARSET, value)
    value
  end
end

## ----------------------------------------------------------------------- Style
=begin
==Style
Class that represents single style in Ruby. Internally it holds reference (index) to
SP style.
=end
class Style
  include SPStyleInterface, SPInterface
  
  # Initialize the style
  # styles: number of styles collection
  # style: index or name of style in the collection
  def initialize(styles, style)
    @styles = styles
    @style = style
    @font = SPFont.new(self)
  end
  
  attr_reader :style
  attr_reader :styles
  
  # Getter
  def get_property(what_prop)
    prop_value = SPStyleInterface.get_style_prop(@styles, @style, what_prop)
    raise ArgumentError, "Reference to invalid styles (#{@subs_no}), style (#{@style}) or property (#{what_prop})" if prop_value.nil?
    prop_value  
  end
  
  # Setter
  def set_property(what_prop, prop_val)
    ret_val = SPStyleInterface.set_style_prop(@styles, @style, what_prop, prop_val)
    raise ArgumentError, "Reference to invalid styles (#{@subs_no}), style (#{@style}) or property (#{what_prop})" unless ret_val
    prop_val  
  end
  
  ## Properties -----------------------------------------------------------------

  #Resolve empty values from default style
  def resolve?
    get_property(STYLE_RESOLVE)
  end
  
  def resolve= (value)
    set_property(STYLE_RESOLVE, value)
    value
  end
  
  #Is the style local or from subtitles
  def local?
    get_property(STYLE_LOCAL)
  end
  
  def local= (value)
    set_property(STYLE_LOCAL, value)
    value
  end
  
  #Is the style's font embedable
  def embedable?
    get_property(STYLE_EMBEDABLE)
  end
  
  def embedable= (value)
    set_property(STYLE_EMBEDABLE, value)
    value
  end
  
  #Font properties
  def font
    @font
  end
  
  #Name of style (can be used as reference)
  def name
    get_property(STYLE_NAME)
  end
  
  def name= (value)
    set_property(STYLE_NAME, value)
    value
  end
  
  #ASS Angle
  def ass_angle
    get_property(STYLE_ASS_ANGLE)
  end
  
  def ass_angle= (value)
    set_property(STYLE_ASS_ANGLE, value)
    value
  end
  
  #Color 1
  def color_1
    get_property(STYLE_COLOR1)
  end
  
  def color_1= (value)
    set_property(STYLE_COLOR1, value)
    value
  end
  
  #Color 2
  def color_2
    get_property(STYLE_COLOR2)
  end
  
  def color_2= (value)
    set_property(STYLE_COLOR2, value)
    value
  end
  
  #Color 3
  def color_3
    get_property(STYLE_COLOR3)
  end
  
  def color_3= (value)
    set_property(STYLE_COLOR3, value)
    value
  end
  
  #Color S
  def color_s
    get_property(STYLE_COLORS)
  end
  
  def color_s= (value)
    set_property(STYLE_COLORS, value)
    value
  end
  
  #Border style
  def border_style
    get_property(STYLE_BORDER_STYLE)
  end
  
  def border_style= (value)
    set_property(STYLE_BORDER_STYLE, value)
    value
  end
  
  #Outline width
  def outline_width
    get_property(STYLE_OUTLINE_W)
  end
  
  def outline_width= (value)
    set_property(STYLE_OUTLINE_W, value)
    value
  end
  
  #Shadow width
  def shadow_width
    get_property(STYLE_SHADOW_W)
  end
  
  def shadow_width= (value)
    set_property(STYLE_SHADOW_W, value)
    value
  end
  
  #Vertical (top-down) position
  def position
    get_property(STYLE_SUB_POSITION)
  end
  
  def position= (value)
    set_property(STYLE_SUB_POSITION, value)
    value
  end

  #Horizontal (L-R) position
  def align
    get_property(STYLE_ALIGN)
  end
  
  def align= (value)
    set_property(STYLE_ALIGN, value)
    value
  end

  #Left margin
  def margin_l
    get_property(STYLE_MARGIN_L)
  end
  
  def margin_l= (value)
    set_property(STYLE_MARGIN_L, value)
    value
  end

  #Right margin
  def margin_r
    get_property(STYLE_MARGIN_R)
  end
  
  def margin_r= (value)
    set_property(STYLE_MARGIN_R, value)
    value
  end

  #Vertical margin
  def margin_v
    get_property(STYLE_MARGIN_V)
  end
  
  def margin_v= (value)
    set_property(STYLE_MARGIN_V, value)
    value
  end

  #2nd Vertical margin
  def margin_v2
    get_property(STYLE_MARGIN_V2)
  end
  
  def margin_v2= (value)
    set_property(STYLE_MARGIN_V2, value)
    value
  end

  #ASS X axis scale
  def ass_scale_x
    get_property(STYLE_ASS_SCALE_X)
  end
  
  def ass_scale_x= (value)
    set_property(STYLE_ASS_SCALE_X, value)
    value
  end

  #ASS Y axis scale
  def ass_scale_y
    get_property(STYLE_ASS_SCALE_Y)
  end
  
  def ass_scale_y= (value)
    set_property(STYLE_ASS_SCALE_Y, value)
    value
  end

  #ASS spacing
  def ass_spacing
    get_property(STYLE_ASS_SPACING)
  end
  
  def ass_spacing= (value)
    set_property(STYLE_ASS_SPACING, value)
    value
  end

  #Alpha value for Color 1
  def color_1_alpha
    get_property(STYLE_COLOR1_ALPHA)
  end
  
  def color_1_alpha= (value)
    set_property(STYLE_COLOR1_ALPHA, value)
    value
  end

  #Alpha value for Color 2
  def color_2_alpha
    get_property(STYLE_COLOR2_ALPHA)
  end
  
  def color_2_alpha= (value)
    set_property(STYLE_COLOR2_ALPHA, value)
    value
  end

  #Alpha value for Color 3
  def color_3_alpha
    get_property(STYLE_COLOR3_ALPHA)
  end
  
  def color_3_alpha= (value)
    set_property(STYLE_COLOR3_ALPHA, value)
    value
  end

  #Alpha value for Shadow Color 
  def color_s_alpha
    get_property(STYLE_COLORS_ALPHA)
  end
  
  def color_s_alpha= (value)
    set_property(STYLE_COLORS_ALPHA, value)
    value
  end

  #Index of the style in collection
  def index
    get_property(STYLE_INDEX)
  end
  
  ## Methods -----------------------------------------------------------------
  def make_empty
    SPStyleInterface.make_empty(@styles, @style)
  end
  
  def is_empty
    SPStyleInterface.is_empty(@styles, @style)
  end
  
  def compact_default
    SPStyleInterface.compact_default(@styles, @style)
  end
  
  def style_equals(style)
    SPStyleInterface.style_equals(@styles, @style, style.styles, style.style)
  end
end


## ======================================================================== StyleGetter
##Class for getting styles by ID
class StyleGetter
  include SPStylesInterface 
  
  def initialize(styles)
    @styles = styles
  end
  
  # Get style by index or name
  # return style when found, nil otherwise
  def [](id)
    styles_count = SPStylesInterface.get_count(@styles)
    if id.kind_of?(Fixnum)
      return nil if styles_count.nil?
      return nil if (styles_count.nil? or (id < 0) or (id >= styles_count))
    end
    style = Style.new(@styles, id)
    begin
      ind = style.index
    rescue
      style = nil
    end
    style
  end
end


## ----------------------------------------------------------------------- Styles
=begin
==Styles
Class that represents styles collection.
=end
class Styles
  include SPStylesInterface, SPInterface
  
  def initialize(styles)
    @styles_no = styles
    @style_getter = StyleGetter.new(styles)
  end
  
  ## Properties -----------------------------------------------------------------
  
  # Number of styles in collection
  def count
    cnt = SPStylesInterface.get_count(@styles_no)
    return 0 unless cnt.kind_of?(Fixnum)
  end

  # return the styles getter with [] method
  def items
    @style_getter   
  end
  
  # return the default style
  def default_style
    Style.new(@styles_no, 0)
  end
  
  ## Methods -----------------------------------------------------------------

  def add
    SPStylesInterface.add(@styles_no)
  end
  
  def delete(style_id_to_delete)
    SPStylesInterface.delete(@styles_no, style_id_to_delete)
  end
  
  def get_unique_name(base_name)
    SPStylesInterface.get_unique_name(@styles_no, base_name)
  end
  
  def find_compatible_style(style)
    SPStylesInterface.find_compatible_style(@styles_no, style.styles, style.style)
  end
  
  def purge_non_local
    SPStylesInterface.purge_non_local(@styles_no)
  end
  
  def find_by_font_props(f_name, f_b, f_i, f_u, f_s, f_charset)
    SPStylesInterface.find_by_font_props(@styles_no, f_name, f_b, f_i, f_u, f_s, f_charset)
  end
  
  def find_by_font_name(f_name)
    SPStylesInterface.find_by_font_name(@styles_no, f_name)
  end
end



## ----------------------------------------------------------------------- Player
=begin
==Player
Class that represents SP's internal Player. It's only a wrapper class for 
SPPlayerInterface module
=end
class Player
  include SPPlayerInterface
  

  def get_current_time
    SPPlayerInterface.get_current_time
  end
  
  def get_current_frame
    SPPlayerInterface.get_current_frame
  end
  
  def get_current_fps
    SPPlayerInterface.get_current_fps
  end
  
  def get_current_time_mode
    SPPlayerInterface.get_current_time_mode
  end
  
  def get_current_state
    SPPlayerInterface.get_current_state
  end
  
  def get_current_player_mode
    SPPlayerInterface.get_current_player_mode
  end
  
  def play
    SPPlayerInterface.play
  end
  
  def pause
    SPPlayerInterface.pause
  end
  
  def stop
    SPPlayerInterface.stop
  end
  
  def seek_to_frame(frame)
    SPPlayerInterface.seek_to_frame(frame)
  end
  
  def seek_to_time(time)
    seek_to_time(time)
  end
end

## ----------------------------------------------------------------------- Editor
=begin
==Editor
Class that represents SP's internal Editor. It's only a wrapper class for 
SPEditorInterface module
=end
class Editor
  include SPEditorInterface
  
  def get_selected_area
    SPEditorInterface.get_selected_area
  end
  
  def select_by_array(selection)
    SPEditorInterface.select_by_array(selection)
  end
  
  def select_by_index(index)
    SPEditorInterface.select_by_index(index)
  end
  
  def get_edited
    SPEditorInterface.get_edited
  end
end  


## ----------------------------------------------------------------------- UserInterface
=begin
==UserInterface
Class that represents SP's User Interface
=end
class UserInterface
  
=begin
Show a message box
<type> use Message box type constant
<buttons> use Buttons constants
<return> one of Dialog result constants
=end
  def msg_box(caption, type, buttons)
    SPUIInterface.msg_box(caption, type, buttons)
  end

=begin
    * Show a text input dialog
    * caption: Title of the dialog
    * label: Label in the dialog
    * default: Default value that will be set to the edit box
    * wx: width (pixels)
    * wy: height(pixels)
    * memo:
          o true: the edit box will be a memo (multi-line)
          o false: edit box will be single-line
    * read_only: shall the edit box be read-only?
    * return: edited value (OK button) or default value (Cancel button)
=end
  def input_dlg(caption, label, default, wx, wy, memo, read_only)
    SPUIInterface.input_dlg(caption, label, default, wx, wy, memo, read_only)
  end

=begin
This function does not anything except putting a line in the debug log.
=end
  def log(log_value)
    SPUIInterface.log(log_value)
  end

=begin
Get a value of string constant from the language file
<key> The key to identify the constant (see string constants in language file)
=end
  def get_translation(key)
    SPUIInterface.get_translation(key)
  end  
end





##TODO player and editor classes


class SP
  include SPInterfaceC,
          SPPlayerInterfaceC,
          SPSubsInterfaceC,
          SPStylesInterfaceC,
          SPStyleInterfaceC,
          SPUIInterfaceC
          
          #SPSubInterface and SPEditorInterface don't have any globally usable constants
  
  @@subs_first = Subtitles.new(SUBS_FIRST)
  @@subs_second = Subtitles.new(SUBS_SECOND)
  @@styles_main = Styles.new(STYLES_MAIN)
  @@player = Player.new
  @@editor = Editor.new
  @@ui = UserInterface.new
  
  private_class_method :new
  

  # First subtitles
  def SP.subs_first
    @@subs_first
  end
  
  # Second subtitles
  def SP.subs_second
    @@subs_second
  end
  
  # Main styles
  def SP.styles
    @@styles_main
  end
  
  # Player interface
  def SP.player
    @@player
  end
  
  # Editor interface
  def SP.editor
    @@editor
  end
  
  # User Interface
  def SP.ui
    @@ui
  end

=begin
---SP.register_toolbar_script
Register a script as a toolbar button in Editor window (Script toolbar).
caption: caption of the button
    * hint: hint of the button
    * image_index: index of image to use for the button (-1 when no image shall be used)
    * script_file: path to the script file (e.g. c:\script.rb)
    * expression: the exact launch expression that should be called when the script is loaded (e.g. MyCoolClass.my_cool_function(3.14))
=end
  def SP.register_toolbar_script(caption, hint, image_index, script_file, expression)
    SPIntegrationInterface.register_toolbar_script(caption, hint, image_index, script_file, expression)
  end  

=begin
Refresh subtitles display in all windows (Editor, Player, Translator)
=end
  def SP.display_subtitles
    SPInterface.display_subtitles
  end  
 
end


#stl = Style.new(1,1)
#puts stl.font.b?
#puts SP.styles.count
#puts SP.styles.items['aaa']
#puts SP.styles.items[1]
#puts SP.subs_first.title
#sub = Subtitle.new(1,1)
#sub2 = Subtitle.new(1,2)
#sub.swap_content(sub2)
#puts sub.lines[0].text

