using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npgsql;
using NpgsqlTypes;
using skyscraper5.Dvb.Descriptors;
using skyscraper5.Dvb.Descriptors.Extension;
using skyscraper5.Iso14496_1;
using skyscraper5.Iso14496_1.Descriptors;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Mpeg2.Psi.Model;
using skyscraper5.Skyscraper.Scraper.Storage.Utilities;

namespace skyscraper5.Data.PostgreSql
{
    public partial class PostgresqlDataStore
    {
        private HashSet<DatabaseKeyPmtEntry> knownPmts;
        public bool TestForPmtEvent(int currentNetworkId, int currentTransportStreamId, ProgramMapping mapping)
        {
            if (knownPmts == null)
                knownPmts = new HashSet<DatabaseKeyPmtEntry>();
            DatabaseKeyPmtEntry entry = new DatabaseKeyPmtEntry(currentNetworkId, currentTransportStreamId, mapping.ProgramNumber);
            if (knownPmts.Contains(entry))
                return true;

            bool result = false;
            using (NpgsqlConnection connection = new NpgsqlConnection(connectionStringBuilder.ToString()))
            {
                connection.Open();
                NpgsqlCommand command = connection.CreateCommand();
                command.CommandText = "SELECT dateadded FROM dvb_pmt WHERE cnid = @cnid AND ctsid = @ctsid AND program_number = @program_number";
                command.Parameters.AddWithValue("@cnid", NpgsqlDbType.Integer, currentNetworkId);
                command.Parameters.AddWithValue("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
                command.Parameters.AddWithValue("@program_number", NpgsqlDbType.Integer, (int)mapping.ProgramNumber);
                NpgsqlDataReader dataReader = command.ExecuteReader();
                result = dataReader.Read();
                dataReader.Close();
                connection.Close();
            }

            if (result)
                knownPmts.Add(entry);
            return result;
        }

        public bool StorePmtEvent(int currentNetworkId, int currentTransportStreamId, ProgramMapping mapping)
        {
	        DatabaseKeyPmtEntry entry = new DatabaseKeyPmtEntry(currentNetworkId, currentTransportStreamId, mapping.ProgramNumber);
	        EnqueueTask(x => WritePmtEntry(x, currentNetworkId, currentTransportStreamId, mapping));
	        knownPmts.Add(entry);
	        return true;
        }

        private void WritePmtEntry(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ProgramMapping mapping)
        {
	        NpgsqlCommand command = conn.CreateCommand();
			command.CommandText = "SELECT dateadded FROM dvb_pmt WHERE cnid = @cnid AND ctsid = @ctsid AND program_number = @program_number";
            command.Parameters.AddParameter("@cnid", NpgsqlDbType.Integer, currentNetworkId);
            command.Parameters.AddParameter("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
            command.Parameters.AddParameter("@program_number", NpgsqlDbType.Integer, mapping.ProgramNumber);
			NpgsqlDataReader dataReader = command.ExecuteReader();
			bool alreadyKnown = dataReader.Read();
			dataReader.Close();
			command.Dispose();

			if (alreadyKnown)
				return;

			command = conn.CreateCommand();
            command.CommandText =
		        "insert into dvb_pmt (cnid, ctsid, program_number, pcr_pid, maximum_bitrate,multiplex_buffer_utilization_bound_valid_flag, multiplex_ltw_offset_lower_bound,multiplex_ltw_offset_upper_bound, clock_accuracy_exponent, clock_accuracy_integer,\r\n                     external_clock_reference_indicator, sb_leak_rate, sb_size, ca_pid, ca_system_id, ca_private_data,\r\n                     private_data_specifiger, registration_additional_identification_info,\r\n                     registration_format_identifier, new_onid, new_sid, new_tsid, component_tag,\r\n                     metadata_input_leak_rate, metadata_buffer_size, metadata_output_leak_rate, scrambling_mode, es_id,\r\n                     audio_type, iso_639_language_code, scope_of_iod_label, iod_label, private_data_indicator,\r\n                     frame_rate, chroma_format, \"constrained_parameter_flag\", frame_rate_extension_flag, mpeg1_only_flag,\r\n                     multiple_framerate_flag, profile_and_level_indication, still_picture_flag, metadata_program_number,\r\n                     metadata_application_format, metadata_application_format_identifier, metadata_format,\r\n                     metadata_format_identifier, metadata_locator_record, metadata_locator_record_flag,\r\n                     metadata_service_id, mpeg_carriage_flag, metadata_private_data, transport_stream_id,\r\n                     transport_stream_location, free_format, audio_stream_id, layer, variable_rate_audio,\r\n                     copy_control_private_data, alignment_type, hierarchy_type, hierarchy_layer_type, tref_present_flag,hierarchy_channel, no_view_scalability_flag, hierarchy_embedded_layer_index,no_quality_scalability_flag, no_spatial_scalability_flag, no_temporal_scalability_flag)" +
		        "values " +
		        "(@cnid,@ctsid,@program_number,@pcr_pid,@maximum_bitrate,@multiplex_buffer_utilization_bound_valid_flag,@multiplex_ltw_offset_lower_bound,@multiplex_ltw_offset_upper_bound,@clock_accuracy_exponent, @clock_accuracy_integer,@external_clock_reference_indicator, @sb_leak_rate, @sb_size, @ca_pid, @ca_system_id, @ca_private_data,\r\n                     @private_data_specifiger, @registration_additional_identification_info,\r\n                     @registration_format_identifier, @new_onid, @new_sid, @new_tsid, @component_tag,\r\n                     @metadata_input_leak_rate, @metadata_buffer_size, @metadata_output_leak_rate, @scrambling_mode, @es_id,\r\n                     @audio_type, @iso_639_language_code, @scope_of_iod_label, @iod_label, @private_data_indicator,\r\n                     @frame_rate, @chroma_format, @constrained_parameter_flag, @frame_rate_extension_flag, @mpeg1_only_flag,\r\n                     @multiple_framerate_flag, @profile_and_level_indication, @still_picture_flag, @metadata_program_number,\r\n                     @metadata_application_format, @metadata_application_format_identifier, @metadata_format,\r\n                     @metadata_format_identifier, @metadata_locator_record, @metadata_locator_record_flag,\r\n                     @metadata_service_id, @mpeg_carriage_flag, @metadata_private_data, @transport_stream_id,\r\n                     @transport_stream_location, @free_format, @audio_stream_id, @layer, @variable_rate_audio,\r\n                     @copy_control_private_data, @alignment_type, @hierarchy_type, @hierarchy_layer_type, @tref_present_flag,\r\n                     @hierarchy_channel, @no_view_scalability_flag, @hierarchy_embedded_layer_index,@no_quality_scalability_flag, @no_spatial_scalability_flag, @no_temporal_scalability_flag)";
	        command.Parameters.AddParameter("@cnid", NpgsqlDbType.Integer, currentNetworkId);
	        command.Parameters.AddParameter("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
	        command.Parameters.AddParameter("@program_number", NpgsqlDbType.Integer, mapping.ProgramNumber);
	        command.Parameters.AddParameter("@pcr_pid", NpgsqlDbType.Integer, mapping.PcrPid);
	        command.Parameters.AddParameter("@maximum_bitrate", NpgsqlDbType.Bigint, mapping.MaximumBitrate);
	        command.Parameters.AddParameter("@multiplex_buffer_utilization_bound_valid_flag", NpgsqlDbType.Boolean, mapping.MultiplexBufferUtilizationBoundValidFlag);
	        command.Parameters.AddParameter("@multiplex_ltw_offset_lower_bound", NpgsqlDbType.Integer, mapping.MultiplexLtwOffsetLowerBound);
	        command.Parameters.AddParameter("@multiplex_ltw_offset_upper_bound", NpgsqlDbType.Integer, mapping.MultiplexLtwOffsetUpperBound);
	        command.Parameters.AddParameter("@clock_accuracy_exponent", NpgsqlDbType.Integer, mapping.ClockAccuracyExponent);
	        command.Parameters.AddParameter("@clock_accuracy_integer", NpgsqlDbType.Integer, mapping.ClockAccuracyInteger);
	        command.Parameters.AddParameter("@external_clock_reference_indicator", NpgsqlDbType.Boolean, mapping.ExternalClockReferenceIndicator);
			//@sb_leak_rate,@sb_size,@ca_pid,@ca_system_id,@ca_private_data,@private_data_specifiger,@registration_additional_identification_info,@registration_format_identifier,@new_onid,@new_sid,@new_tsid,@component_tag,
			command.Parameters.AddParameter("@sb_leak_rate", NpgsqlDbType.Bigint, mapping.SbLeakRate);
			command.Parameters.AddParameter("@sb_size", NpgsqlDbType.Bigint, mapping.SbSize);
			command.Parameters.AddParameter("@ca_pid", NpgsqlDbType.Integer, mapping.CaPid);
			command.Parameters.AddParameter("@ca_system_id", NpgsqlDbType.Integer, mapping.CaSystemId);
			command.Parameters.AddParameter("@ca_private_data", NpgsqlDbType.Bytea, mapping.CaPrivateData);
			command.Parameters.AddParameter("@private_data_specifiger", NpgsqlDbType.Bigint, mapping.PrivateDataIndicator);
			command.Parameters.AddParameter("@registration_additional_identification_info", NpgsqlDbType.Bytea, mapping.RegistrationAdditionalIdentificationInfo);
			command.Parameters.AddParameter("@registration_format_identifier", NpgsqlDbType.Bigint, mapping.RegistrationFormatIdentifier);
			command.Parameters.AddParameter("@new_onid", NpgsqlDbType.Integer, mapping.NewOriginalNetworkId);
			command.Parameters.AddParameter("@new_sid", NpgsqlDbType.Integer, mapping.NewServiceId);
			command.Parameters.AddParameter("@new_tsid", NpgsqlDbType.Integer, mapping.NewTransportStreamId);
			command.Parameters.AddParameter("@component_tag", NpgsqlDbType.Integer, mapping.ComponentTag);
			//@metadata_input_leak_rate,@metadata_buffer_size,@metadata_output_leak_rate,@scrambling_mode,@es_id,@audio_type,@iso_639_language_code,@scope_of_iod_label,@iod_label,@private_data_indicator,
			command.Parameters.AddParameter("@metadata_input_leak_rate", NpgsqlDbType.Integer, mapping.MetadataInputLeakRate);
			command.Parameters.AddParameter("@metadata_buffer_size", NpgsqlDbType.Integer, mapping.MetadataBufferSize);
			command.Parameters.AddParameter("@metadata_output_leak_rate", NpgsqlDbType.Integer, mapping.MetadataOutputLeakRate);
			command.Parameters.AddParameter("@scrambling_mode", NpgsqlDbType.Integer, mapping.ScramblingMode);
			command.Parameters.AddParameter("@es_id", NpgsqlDbType.Integer, mapping.EsId);
			command.Parameters.AddParameter("@audio_type", NpgsqlDbType.Integer, (int?)mapping.AudioType);
			command.Parameters.AddParameter("@iso_639_language_code", NpgsqlDbType.Varchar, mapping.Iso639LanguageCode);
			command.Parameters.AddParameter("@scope_of_iod_label", NpgsqlDbType.Integer, mapping.ScopeOfIodLabel);
			command.Parameters.AddParameter("@iod_label", NpgsqlDbType.Integer, mapping.IodLabel);
			command.Parameters.AddParameter("@private_data_indicator", NpgsqlDbType.Bigint, mapping.PrivateDataIndicator);
			//@frame_rate,@chroma_format,@constrained_parameter_flag,@frame_rate_extension_flag,@mpeg1_only_flag,@multiple_framerate_flag,@profile_and_level_indication,@still_picture_flag,@metadata_program_number,
			command.Parameters.AddParameter("@frame_rate", NpgsqlDbType.Double, mapping.FrameRate);
			command.Parameters.AddParameter("@chroma_format", NpgsqlDbType.Integer, mapping.ChromaFormat);
			command.Parameters.AddParameter("@constrained_parameter_flag", NpgsqlDbType.Boolean, mapping.ConstrainedParameterFlag);
			command.Parameters.AddParameter("@frame_rate_extension_flag", NpgsqlDbType.Integer, mapping.FrameRateExtensionFlag);
			command.Parameters.AddParameter("@mpeg1_only_flag", NpgsqlDbType.Boolean, mapping.Mpeg1OnlyFlag);
			command.Parameters.AddParameter("@multiple_framerate_flag", NpgsqlDbType.Boolean, mapping.MultipleFramerateFlag);
			command.Parameters.AddParameter("@profile_and_level_indication", NpgsqlDbType.Integer, mapping.ProfileAndLevelIndication);
			command.Parameters.AddParameter("@still_picture_flag", NpgsqlDbType.Boolean, mapping.StillPictureFlag);
			command.Parameters.AddParameter("@metadata_program_number", NpgsqlDbType.Integer, mapping.MetadataProgramNumber);
			//@metadata_application_format,@metadata_application_format_identifier,@metadata_format,@metadata_format_identifier,@metadata_locator_record,@metadata_locator_record_flag,@metadata_service_id,
			command.Parameters.AddParameter("@metadata_application_format", NpgsqlDbType.Integer, mapping.MetadataApplicationFormat);
			command.Parameters.AddParameter("@metadata_application_format_identifier", NpgsqlDbType.Bigint, mapping.MetadataApplicationFormatIdentifier);
			command.Parameters.AddParameter("@metadata_format", NpgsqlDbType.Integer, mapping.MetadataFormat);
			command.Parameters.AddParameter("@metadata_format_identifier", NpgsqlDbType.Bigint, mapping.MetadataFormatIdentifier);
			command.Parameters.AddParameter("@metadata_locator_record", NpgsqlDbType.Bytea, mapping.MetadataLocatorRecord);
			command.Parameters.AddParameter("@metadata_locator_record_flag", NpgsqlDbType.Boolean, mapping.MetadataLocatorRecordFlag);
			command.Parameters.AddParameter("@metadata_service_id", NpgsqlDbType.Integer, mapping.MetadataServiceId);
			//@mpeg_carriage_flag,@metadata_private_data,@transport_stream_id,@transport_stream_location,@free_format,@audio_stream_id,@layer,@variable_rate_audio,@copy_control_private_data,@alignment_type,
			command.Parameters.AddParameter("@mpeg_carriage_flag", NpgsqlDbType.Integer, mapping.MpegCarriageFlag);
			command.Parameters.AddParameter("@metadata_private_data", NpgsqlDbType.Bytea, mapping.MetadataPrivateData);
			command.Parameters.AddParameter("@transport_stream_id", NpgsqlDbType.Integer, mapping.TransportStreamId);
			command.Parameters.AddParameter("@transport_stream_location", NpgsqlDbType.Integer, mapping.TransportStreamLocation);
			command.Parameters.AddParameter("@free_format", NpgsqlDbType.Boolean, mapping.FreeFormat);
			command.Parameters.AddParameter("@audio_stream_id", NpgsqlDbType.Boolean, mapping.AudioStreamId);
			command.Parameters.AddParameter("@layer", NpgsqlDbType.Integer, mapping.Layer);
			command.Parameters.AddParameter("@variable_rate_audio", NpgsqlDbType.Boolean, mapping.VariableRateAudio);
			command.Parameters.AddParameter("@copy_control_private_data", NpgsqlDbType.Bytea, mapping.CopyControlPrivateData);
			command.Parameters.AddParameter("@alignment_type", NpgsqlDbType.Integer, mapping.AlignmentType);
			//@hierarchy_type,@hierarchy_layer_type,@tref_present_flag,@hierarchy_channel,@no_view_scalability_flag,@hierarchy_embedded_layer_index,@no_quality_scalability_flag,@no_spatial_scalability_flag,
			command.Parameters.AddParameter("@hierarchy_type", NpgsqlDbType.Integer, mapping.HierarchyType);
			command.Parameters.AddParameter("@hierarchy_layer_type", NpgsqlDbType.Integer, mapping.HierarchyLayerType);
			command.Parameters.AddParameter("@tref_present_flag", NpgsqlDbType.Boolean, mapping.TrefPresentFlag);
			command.Parameters.AddParameter("@hierarchy_channel", NpgsqlDbType.Integer, mapping.HierarchyChannel);
			command.Parameters.AddParameter("@no_view_scalability_flag", NpgsqlDbType.Boolean, mapping.NoViewScalabilityFlag);
			command.Parameters.AddParameter("@hierarchy_embedded_layer_index", NpgsqlDbType.Integer, mapping.HierarchyEmbeddedLayerIndex);
			command.Parameters.AddParameter("@no_quality_scalability_flag", NpgsqlDbType.Boolean, mapping.NoQualityScalabilityFlag);
			command.Parameters.AddParameter("@no_spatial_scalability_flag", NpgsqlDbType.Boolean, mapping.NoSpatialScalabilityFlag);
			//@no_temporal_scalability_flag)";
			command.Parameters.AddParameter("@no_temporal_scalability_flag", NpgsqlDbType.Boolean, mapping.NoTemporalScalabilityFlag);

			command.Parameters.CheckNulls();
			command.ExecuteNonQuery();

			WritePmtInitialObjectDescriptor(conn, currentNetworkId, currentTransportStreamId, mapping);
			WritePmtStreams(conn, currentNetworkId, currentTransportStreamId, mapping);
        }

        private void WritePmtStreams(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ProgramMapping mapping)
        {
	        if (mapping.Streams == null)
		        return;

			bool[] streamsDone = new bool[0x1fff];
	        foreach (ProgramMappingStream mappingStream in mapping.Streams)
	        {
				if (streamsDone[mappingStream.ElementaryPid])
					continue;

		        WritePmtStream(conn, currentNetworkId, currentTransportStreamId, mapping.ProgramNumber, mappingStream);
				streamsDone[mappingStream.ElementaryPid] = true;
            }
        }

        private void WritePmtStream(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ushort mappingProgramNumber, ProgramMappingStream stream)
        {
	        NpgsqlCommand command = conn.CreateCommand();
	        command.CommandText =
				"insert into dvb_pmt_streams (cnid, ctsid, program_number, stream_type, elementary_pid, component_tag, audio_type, iso_639_language_code, carousel_format_id, carousel_id, data_broadcast_id," +
				" data_broadcast_selector, supplementary_independant_stream, editorial_classification, supplementary_language_code, asvc, bsid, component_type, main_id, frame_rate, mpeg1_only_flag, chroma_format, " +
				"the_constrained_parameter_flag, frame_rate_extension_flag, multiple_framerate_flag, profile_and_level_indication, still_picture_flag, alignment_type, maximum_bitrate, audio_stream_id, free_format, " +
				"layer, variable_rate_audio, constraint_set0_flag, avc_24hour_picture_flag, avc_compatible_flag, avc_still_present, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag, " +
				"constraint_set4_flag, constraint_set5_flag, frame_packing_sei_not_present, level_idc, profile_rdc, ca_pid, ca_system_id, ca_private_data, private_data_specifier, format_identifier, " +
				"additional_identification_info, association_tag_selector, association_tag_transaction_id, association_tag_use, association_tag_private_data, association_tag_timeout, aac_type, " +
				"aac_additional_info, aac_profile_and_level, saoc_de_flag, ancillary_data_identifier, mix_info_exists, substream1, substream2, substream3, copied_44bits, frame_only_constraint_flag, " +
				"hdr_wcg_idc, hevc_24hr_picture_present_flag, hevc_still_present_flag, interlaced_source_flag, non_packed_constraint_flag, profile_compatibility_indication, profile_idc, " +
				"profile_space, progressive_source_flag, sub_pic_hrd_params_not_present_flag, temporal_id_max, tier_flag, temporal_id_min, ac4_channel_mode, ac4_dialog_enhancement, ac4_dsi, " +
				"leak_valid_flag, sb_leak_rate, sb_size, private_data_indicator, \"_90khz_flag\", picture_and_timing_info_present_flag, hdr_management_valid_flag, k, n, num_units_in_tick, " +
				"target_schedule_idx, target_schedule_idx_not_present_flag, adaption_field_data_identifier, fixed_frame_rate_flag, picture_to_display_conversion_flag, temporal_poc_flag, " +
				"mpeg4_audio_profile_and_level, aac_channel_configuration, aac_profile, aac_additional_information, scrambling_mode, related_content_descriptor_present, num_t2mi_streams, " +
				"t2mi_stream_id, pcr_iscr_common_clock_flag, audio_specific_config, audio_profile_level_indication)\r\n " +
				"values\r\n    " +
				"(@cnid,@ctsid,@program_number,@stream_type,@elementary_pid,@component_tag,@audio_type,@iso_639_language_code,@carousel_format_id,@carousel_id,@data_broadcast_id,@data_broadcast_selector,@supplementary_independant_stream, @editorial_classification,\r\n                             @supplementary_language_code, @asvc, @bsid, @component_type, @main_id, @frame_rate,\r\n                             @mpeg1_only_flag, @chroma_format, @constrained_parameter_flag, @frame_rate_extension_flag,\r\n                             @multiple_framerate_flag, @profile_and_level_indication, @still_picture_flag, @alignment_type,\r\n                             @maximum_bitrate, @audio_stream_id, @free_format, @layer, @variable_rate_audio,\r\n                             @constraint_set0_flag, @avc_24hour_picture_flag, @avc_compatible_flag, @avc_still_present,\r\n                             @constraint_set1_flag, @constraint_set2_flag, @constraint_set3_flag, @constraint_set4_flag,\r\n                             @constraint_set5_flag, @frame_packing_sei_not_present, @level_idc, @profile_rdc, @ca_pid,\r\n                             @ca_system_id, @ca_private_data, @private_data_specifier, @format_identifier,\r\n                             @additional_identification_info, @association_tag_selector, @association_tag_transaction_id,\r\n                             @association_tag_use, @association_tag_private_data, @association_tag_timeout, @aac_type,\r\n                             @aac_additional_info, @aac_profile_and_level, @saoc_de_flag, @ancillary_data_identifier,\r\n                             @mix_info_exists, @substream1, @substream2, @substream3, @copied_44bits,\r\n                             @frame_only_constraint_flag, @hdr_wcg_idc, @hevc_24hr_picture_present_flag,\r\n                             @hevc_still_present_flag, @interlaced_source_flag, @non_packed_constraint_flag,\r\n                             @profile_compatibility_indication, @profile_idc, @profile_space, @progressive_source_flag,\r\n                             @sub_pic_hrd_params_not_present_flag, @temporal_id_max, @tier_flag, @temporal_id_min,\r\n                             @ac4_channel_mode, @ac4_dialog_enhancement, @ac4_dsi, @leak_valid_flag, @sb_leak_rate, @sb_size,\r\n                             @private_data_indicator, @_90khz_flag, @picture_and_timing_info_present_flag,\r\n                             @hdr_management_valid_flag, @k, @n, @num_units_in_tick, @target_schedule_idx,\r\n                             @target_schedule_idx_not_present_flag, @adaption_field_data_identifier,\r\n                             @fixed_frame_rate_flag, @picture_to_display_conversion_flag, @temporal_poc_flag,\r\n                             @mpeg4_audio_profile_and_level, @aac_channel_configuration, @aac_profile,\r\n                             @aac_additional_information, @scrambling_mode, @related_content_descriptor_present,\r\n                             @num_t2mi_streams, @t2mi_stream_id, @pcr_iscr_common_clock_flag, @audio_specific_config, @audio_profile_level_indication);";
	        command.Parameters.AddParameter("@cnid", NpgsqlDbType.Integer, currentNetworkId);
	        command.Parameters.AddParameter("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
	        command.Parameters.AddParameter("@program_number", NpgsqlDbType.Integer, mappingProgramNumber);
	        command.Parameters.AddParameter("@stream_type", NpgsqlDbType.Integer, (int)stream.StreamType);
	        command.Parameters.AddParameter("@elementary_pid", NpgsqlDbType.Integer, stream.ElementaryPid);
	        command.Parameters.AddParameter("@component_tag", NpgsqlDbType.Integer, stream.ComponentTag);
	        command.Parameters.AddParameter("@audio_type", NpgsqlDbType.Integer, (int?)stream.AudioType);
	        command.Parameters.AddParameter("@iso_639_language_code", NpgsqlDbType.Varchar, stream.Iso639LanguageCode);
	        command.Parameters.AddParameter("@carousel_format_id", NpgsqlDbType.Integer, stream.CarouselFormatId);
	        command.Parameters.AddParameter("@carousel_id", NpgsqlDbType.Bigint, stream.CarouselId);
	        command.Parameters.AddParameter("@data_broadcast_id", NpgsqlDbType.Integer, stream.DataBroadcastId);
	        command.Parameters.AddParameter("@data_broadcast_selector", NpgsqlDbType.Bytea, stream.DataBroadcastSelector);
			//@supplementary_independant_stream,@editorial_classification,@supplementary_language_code,@asvc,@bsid,@component_type,@main_id,@frame_rate,@mpeg1_only_flag,@chroma_format,@constrained_parameter_flag,
			command.Parameters.AddParameter("@supplementary_independant_stream", NpgsqlDbType.Boolean, stream.SupplementaryIndependantStream);
			command.Parameters.AddParameter("@editorial_classification", NpgsqlDbType.Integer, (int?)stream.EditorialClassification);
			command.Parameters.AddParameter("@supplementary_language_code", NpgsqlDbType.Varchar, stream.SupplementaryLanguageCode);
			command.Parameters.AddParameter("@asvc", NpgsqlDbType.Integer, stream.Asvc);
			command.Parameters.AddParameter("@bsid", NpgsqlDbType.Integer, stream.BSID);
			command.Parameters.AddParameter("@component_type", NpgsqlDbType.Integer, (int?)stream.ComponentType);
			command.Parameters.AddParameter("@main_id", NpgsqlDbType.Integer, stream.MainId);
			command.Parameters.AddParameter("@frame_rate", NpgsqlDbType.Double, stream.FrameRate);
			command.Parameters.AddParameter("@mpeg1_only_flag", NpgsqlDbType.Boolean, stream.Mpeg1OnlyFlag);
			command.Parameters.AddParameter("@chroma_format", NpgsqlDbType.Integer, stream.ChromaFormat);
			command.Parameters.AddParameter("@constrained_parameter_flag", NpgsqlDbType.Boolean, stream.ConstrainedParameterFlag);
			//@frame_rate_extension_flag,@multiple_framerate_flag,@profile_and_level_indication,@still_picture_flag,@alignment_type,@maximum_bitrate,@audio_stream_id,@free_format,@layer,@variable_rate_audio,
			command.Parameters.AddParameter("@frame_rate_extension_flag", NpgsqlDbType.Integer, stream.FrameRateExtensionFlag);
			command.Parameters.AddParameter("@multiple_framerate_flag", NpgsqlDbType.Boolean, stream.MultipleFramerateFlag);
			command.Parameters.AddParameter("@profile_and_level_indication", NpgsqlDbType.Integer, stream.ProfileAndLevelIndication);
			command.Parameters.AddParameter("@still_picture_flag", NpgsqlDbType.Boolean, stream.StillPictureFlag);
			command.Parameters.AddParameter("@alignment_type", NpgsqlDbType.Integer, stream.AlignmentType);
			command.Parameters.AddParameter("@maximum_bitrate", NpgsqlDbType.Bigint, stream.MaximumBitrate);
			command.Parameters.AddParameter("@audio_stream_id", NpgsqlDbType.Boolean, stream.AudioStreamId);
			command.Parameters.AddParameter("@free_format", NpgsqlDbType.Boolean, stream.FreeFormat);
			command.Parameters.AddParameter("@layer", NpgsqlDbType.Integer, stream.Layer);
			command.Parameters.AddParameter("@variable_rate_audio", NpgsqlDbType.Boolean, stream.VariableRateAudio);
			//@constraint_set0_flag,@avc_24hour_picture_flag,@avc_compatible_flag,@avc_still_present,@constraint_set1_flag,@constraint_set2_flag,@constraint_set3_flag,@constraint_set4_flag,@constraint_set5_flag,
			command.Parameters.AddParameter("@constraint_set0_flag", NpgsqlDbType.Boolean, stream.ConstraintSet0Flag);
			command.Parameters.AddParameter("@constraint_set0_flag", NpgsqlDbType.Boolean, stream.ConstraintSet0Flag);
			command.Parameters.AddParameter("@avc_24hour_picture_flag", NpgsqlDbType.Boolean, stream.Avc24HourPictureFlag);
			command.Parameters.AddParameter("@avc_compatible_flag", NpgsqlDbType.Integer, stream.AvcCompatibleFlags);
			command.Parameters.AddParameter("@avc_still_present", NpgsqlDbType.Boolean, stream.AvcStillPresent);
			command.Parameters.AddParameter("@constraint_set1_flag", NpgsqlDbType.Boolean, stream.ConstraintSet1Flag);
			command.Parameters.AddParameter("@constraint_set2_flag", NpgsqlDbType.Boolean, stream.ConstraintSet2Flag);
			command.Parameters.AddParameter("@constraint_set3_flag", NpgsqlDbType.Boolean, stream.ConstraintSet3Flag);
			command.Parameters.AddParameter("@constraint_set4_flag", NpgsqlDbType.Boolean, stream.ConstraintSet4Flag);
			command.Parameters.AddParameter("@constraint_set5_flag", NpgsqlDbType.Boolean, stream.ConstraintSet5Flag);
			//@frame_packing_sei_not_present,@level_idc,@profile_rdc,@ca_pid,@ca_system_id,@ca_private_data,@private_data_specifier,@format_identifier,@additional_identification_info,@association_tag_selector,
			command.Parameters.AddParameter("@frame_packing_sei_not_present", NpgsqlDbType.Boolean, stream.FramePackingSeiNotPresent);
			command.Parameters.AddParameter("@level_idc", NpgsqlDbType.Integer, stream.LevelIdc);
			command.Parameters.AddParameter("@profile_rdc", NpgsqlDbType.Integer, stream.ProfileRdc);
			command.Parameters.AddParameter("@ca_pid", NpgsqlDbType.Integer, stream.CaPid);
			command.Parameters.AddParameter("@ca_system_id", NpgsqlDbType.Integer, stream.CaSystemId);
			command.Parameters.AddParameter("@ca_private_data", NpgsqlDbType.Bytea, stream.CaPrivateData);
			command.Parameters.AddParameter("@private_data_specifier", NpgsqlDbType.Bigint, stream.PrivateDataSpecifier);
			command.Parameters.AddParameter("@format_identifier", NpgsqlDbType.Bigint, stream.FormatIdentifier);
			command.Parameters.AddParameter("@additional_identification_info", NpgsqlDbType.Bytea, stream.AdditionalIdentificationInfo);
			command.Parameters.AddParameter("@association_tag_selector", NpgsqlDbType.Bytea, stream.AssociationTagSelector);
			//@association_tag_transaction_id,@association_tag_use,@association_tag_private_data,@association_tag_timeout,@aac_type,@aac_additional_info,@aac_profile_and_level,@saoc_de_flag,
			command.Parameters.AddParameter("@association_tag_transaction_id", NpgsqlDbType.Bigint, stream.AssociationTagTransactionId);
			command.Parameters.AddParameter("@association_tag_use", NpgsqlDbType.Integer, stream.AssociationTagUse);
			command.Parameters.AddParameter("@association_tag_private_data", NpgsqlDbType.Bytea, stream.AssociationTagPrivateData);
			command.Parameters.AddParameter("@association_tag_timeout", NpgsqlDbType.Bigint, stream.AssociationTagTimeOut);
			command.Parameters.AddParameter("@aac_type", NpgsqlDbType.Integer, stream.AacType);
			command.Parameters.AddParameter("@aac_additional_info", NpgsqlDbType.Bytea, stream.AacAdditionalInfo);
			command.Parameters.AddParameter("@aac_profile_and_level", NpgsqlDbType.Integer, stream.AacProfileAndLevel);
			command.Parameters.AddParameter("@saoc_de_flag", NpgsqlDbType.Boolean, stream.SaocDeFlag);
			//@ancillary_data_identifier,@mix_info_exists,@substream1,@substream2,@substream3,@copied_44bits,@frame_only_constraint_flag,@hdr_wcg_idc,@hevc_24hr_picture_present_flag,@hevc_still_present_flag,
			if (stream.AncillaryDataDescriptor != null)
				command.Parameters.AddParameter("@ancillary_data_identifier", NpgsqlDbType.Integer, stream.AncillaryDataDescriptor.AncillaryDataIdentifier);
			else
				command.Parameters.AddWithValue("@ancillary_data_identifier", NpgsqlDbType.Integer, DBNull.Value);
			command.Parameters.AddParameter("@mix_info_exists", NpgsqlDbType.Boolean, stream.MixInfoExists);
			command.Parameters.AddParameter("@substream1", NpgsqlDbType.Integer, stream.Substream1);
			command.Parameters.AddParameter("@substream2", NpgsqlDbType.Integer, stream.Substream2);
			command.Parameters.AddParameter("@substream3", NpgsqlDbType.Integer, stream.Substream3);
			command.Parameters.AddParameter("@copied_44bits", NpgsqlDbType.Bigint, stream.Copied44bits);
			command.Parameters.AddParameter("@frame_only_constraint_flag", NpgsqlDbType.Boolean, stream.FrameOnlyConstraintFlag);
			command.Parameters.AddParameter("@hdr_wcg_idc", NpgsqlDbType.Integer, stream.HdrWcgIdc);
			command.Parameters.AddParameter("@hevc_24hr_picture_present_flag", NpgsqlDbType.Boolean, stream.Hevc24hrPicturePresentFlag);
			command.Parameters.AddParameter("@hevc_still_present_flag", NpgsqlDbType.Boolean, stream.HevcStillPresentFlag);
			//@interlaced_source_flag,@non_packed_constraint_flag,@profile_compatibility_indication,@profile_idc,@profile_space,@progressive_source_flag,@sub_pic_hrd_params_not_present_flag,@temporal_id_max,
			command.Parameters.AddParameter("@interlaced_source_flag", NpgsqlDbType.Boolean, stream.InterlacedSourceFlag);
			command.Parameters.AddParameter("@non_packed_constraint_flag", NpgsqlDbType.Boolean, stream.NonPackedConstraintFlag);
			command.Parameters.AddParameter("@profile_compatibility_indication", NpgsqlDbType.Bigint, stream.ProfileCompatibilityIndication);
			command.Parameters.AddParameter("@profile_idc", NpgsqlDbType.Bigint, stream.ProfileIdc);
			command.Parameters.AddParameter("@profile_space", NpgsqlDbType.Integer, stream.ProfileSpace);
			command.Parameters.AddParameter("@progressive_source_flag", NpgsqlDbType.Boolean, stream.ProgressiveSourceFlag);
			command.Parameters.AddParameter("@sub_pic_hrd_params_not_present_flag", NpgsqlDbType.Boolean, stream.SubPicHrdParamsNotPresentFlag);
			command.Parameters.AddParameter("@temporal_id_max", NpgsqlDbType.Integer, stream.TemporalIdMax);
			//@tier_flag,@temporal_id_min,@ac4_channel_mode,@ac4_dialog_enhancement,@ac4_dsi,@leak_valid_flag,@sb_leak_rate,@sb_size,@private_data_indicator,@_90khz_flag,@picture_and_timing_info_present_flag,
			command.Parameters.AddParameter("@tier_flag", NpgsqlDbType.Boolean, stream.TierFlag);
			command.Parameters.AddParameter("@temporal_id_min", NpgsqlDbType.Integer, stream.TemporalIdMin);
			command.Parameters.AddParameter("@ac4_channel_mode", NpgsqlDbType.Integer, stream.Ac4ChannelMode);
			command.Parameters.AddParameter("@ac4_dialog_enhancement", NpgsqlDbType.Boolean, stream.Ac4DialogEnhancement);
			command.Parameters.AddParameter("@ac4_dsi", NpgsqlDbType.Bytea, stream.Ac4Dsi);
			command.Parameters.AddParameter("@ac4_dsi", NpgsqlDbType.Bytea, stream.Ac4Dsi);
			command.Parameters.AddParameter("@leak_valid_flag", NpgsqlDbType.Boolean, stream.LeakValidFlag);
			command.Parameters.AddParameter("@sb_leak_rate", NpgsqlDbType.Bigint, stream.SbLeakRate);
			command.Parameters.AddParameter("@sb_size", NpgsqlDbType.Bigint, stream.SbSize);
			command.Parameters.AddParameter("@private_data_indicator", NpgsqlDbType.Bigint, stream.PrivateDataIndicator);
			command.Parameters.AddParameter("@_90khz_flag", NpgsqlDbType.Boolean, stream._90khzFlag);
			command.Parameters.AddParameter("@picture_and_timing_info_present_flag", NpgsqlDbType.Boolean, stream.PictureAndTimingInfoPresentFlag);
			//@hdr_management_valid_flag,@k,@n,@num_units_in_tick,@target_schedule_idx,@target_schedule_idx_not_present_flag,@adaption_field_data_identifier,@fixed_frame_rate_flag,
			command.Parameters.AddParameter("@hdr_management_valid_flag", NpgsqlDbType.Boolean, stream.HdrManagementValidFlag);
			command.Parameters.AddParameter("@k", NpgsqlDbType.Bigint, stream.K);
			command.Parameters.AddParameter("@n", NpgsqlDbType.Bigint, stream.N);
			command.Parameters.AddParameter("@num_units_in_tick", NpgsqlDbType.Bigint, stream.NumUnitsInTick);
			command.Parameters.AddParameter("@target_schedule_idx", NpgsqlDbType.Integer, stream.TargetScheduleIdx);
			command.Parameters.AddParameter("@target_schedule_idx_not_present_flag", NpgsqlDbType.Boolean, stream.TargetScheduleIdxNotPresentFlag);
			command.Parameters.AddParameter("@adaption_field_data_identifier", NpgsqlDbType.Integer, stream.AdaptionFieldDataIdentifier);
			command.Parameters.AddParameter("@fixed_frame_rate_flag", NpgsqlDbType.Boolean, stream.FixedFrameRateFlag);
			//@picture_to_display_conversion_flag,@temporal_poc_flag,@mpeg4_audio_profile_and_level,@aac_channel_configuration,@aac_profile,@aac_additional_information,@scrambling_mode,
			command.Parameters.AddParameter("@picture_to_display_conversion_flag", NpgsqlDbType.Boolean, stream.PictureToDisplayConversionFlag);
			command.Parameters.AddParameter("@temporal_poc_flag", NpgsqlDbType.Boolean, stream.TemporalPocFlag);
			command.Parameters.AddParameter("@mpeg4_audio_profile_and_level", NpgsqlDbType.Integer, stream.Mpeg4AudioProfileAndLevel);
			command.Parameters.AddParameter("@aac_channel_configuration", NpgsqlDbType.Integer, stream.AacChannelConfiguration);
			command.Parameters.AddParameter("@aac_profile", NpgsqlDbType.Integer, stream.AacProfile);
			command.Parameters.AddParameter("@aac_additional_information", NpgsqlDbType.Bytea, stream.AacAdditionalInfo);
			command.Parameters.AddParameter("@scrambling_mode", NpgsqlDbType.Integer, stream.ScramblingMode);
			//@related_content_descriptor_present,@num_t2mi_streams,@t2mi_stream_id,@pcr_iscr_common_clock_flag); ";
			command.Parameters.AddParameter("@related_content_descriptor_present",NpgsqlDbType.Boolean,stream.RelatedContentDescriptorPresent);
			command.Parameters.AddParameter("@num_t2mi_streams", NpgsqlDbType.Integer,stream.NumT2MiStreams);
			command.Parameters.AddParameter("@t2mi_stream_id", NpgsqlDbType.Integer,stream.T2MiStreamId);
			command.Parameters.AddParameter("@pcr_iscr_common_clock_flag", NpgsqlDbType.Boolean,stream.PcrIscrCommonClockFlag);
			//audio_specific_config, audio_profile_level_indication
			command.Parameters.AddParameter("@audio_specific_config", NpgsqlDbType.Bytea, stream.AudioSpecifConfig);
			command.Parameters.AddParameter("@audio_profile_level_indication", NpgsqlDbType.Bytea, stream.AudioProfileLevelIndication);
			command.Parameters.CheckNulls();
			command.ExecuteNonQuery();

			WritePmtStreamApplications(conn, currentNetworkId, currentTransportStreamId, mappingProgramNumber,stream);
			WritePmtStreamAudioPreselections(conn, currentNetworkId, currentTransportStreamId, mappingProgramNumber, stream);
			WritePmtStreamFluxmuxChannels(conn, currentNetworkId, currentTransportStreamId, mappingProgramNumber, stream);
			WritePmtStreamIpMacNotificationInfo(conn, currentNetworkId, currentTransportStreamId, mappingProgramNumber, stream);
			WritePmtStreamSubtitlings(conn, currentNetworkId, currentTransportStreamId, mappingProgramNumber, stream);
			WritePmtStreamTeletexts(conn, currentNetworkId, currentTransportStreamId, mappingProgramNumber, stream, false);
			WritePmtStreamVbiData(conn, currentNetworkId, currentTransportStreamId, mappingProgramNumber, stream);
			WritePmtStreamTeletexts(conn, currentNetworkId, currentTransportStreamId, mappingProgramNumber, stream, true);
		}

        private void WritePmtStreamVbiData(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ushort mappingProgramNumber, ProgramMappingStream stream)
        {
	        if (stream.VbiData == null)
		        return;

	        NpgsqlCommand command = conn.CreateCommand();
	        command.CommandText =
		        "insert into dvb_pmt_streams_vbi_data (cnid, ctsid, program_number, elementary_pid, ordinal, data_service_id, field_parity, line_offset) " +
		        "values (@cnid, @ctsid, @program_number, @elementary_pid, @ordinal, @data_service_id, @field_parity, @line_offset)";
	        command.Parameters.AddWithValue("@cnid", NpgsqlDbType.Integer, currentNetworkId);
	        command.Parameters.AddWithValue("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
	        command.Parameters.AddWithValue("@program_number", NpgsqlDbType.Integer, (int)mappingProgramNumber);
	        command.Parameters.AddWithValue("@elementary_pid", NpgsqlDbType.Integer, stream.ElementaryPid);
	        command.Parameters.Add("@ordinal", NpgsqlDbType.Integer);
	        command.Parameters.Add("@data_service_id", NpgsqlDbType.Integer);
	        command.Parameters.Add("@field_parity", NpgsqlDbType.Boolean);
	        command.Parameters.Add("@line_offset", NpgsqlDbType.Integer);
	        
	        int ordinalIterator = 0;
	        foreach (VbiDataDescriptor.DataService dataService in stream.VbiData)
	        {
		        for (int i = 0; i < dataService.FieldParity.Length; i++)
		        {
			        int ordinal = ordinalIterator++;
			        bool parity = dataService.FieldParity[i];
			        int lineOffset = dataService.LineOffset[i];
			        command.Parameters["@ordinal"].Value = ordinalIterator;
			        command.Parameters["@data_service_id"].Value = dataService.DataServiceId;
			        command.Parameters["@field_parity"].Value = parity;
			        command.Parameters["@line_offset"].Value = lineOffset;
			        command.ExecuteNonQuery();
		        }
	        }
        }

        private void WritePmtStreamTeletexts(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ushort mappingProgramNumber, ProgramMappingStream stream, bool vbi)
        {
	        TeletextDescriptor.TeletextDescriptorTeletext[] teletext;
	        string tableName;

	        if (vbi)
	        {
		        teletext = stream.VbiTeletexts;
		        tableName = "dvb_pmt_streams_vbi_teletexts";
	        }
	        else
	        {
		        teletext = stream.Teletexts;
		        tableName = "dvb_pmt_streams_teletexts";
			}

	        if (teletext == null)
		        return;

	        NpgsqlCommand command = conn.CreateCommand();
	        command.CommandText =
		        String.Format(
			        "insert into {0} (cnid, ctsid, program_number, elementary_pid, ordinal, iso_639_language_code, teletext_type, teletext_magazine_number, teletext_page_number) " +
			        "values " +
			        "(@cnid, @ctsid, @program_number, @elementary_pid, @ordinal, @iso_639_language_code, @teletext_type, @teletext_magazine_number, @teletext_page_number)",
			        tableName);
	        command.Parameters.AddParameter("@cnid", NpgsqlDbType.Integer, currentNetworkId);
	        command.Parameters.AddParameter("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
	        command.Parameters.AddParameter("@program_number", NpgsqlDbType.Integer, (int)mappingProgramNumber);
	        command.Parameters.AddParameter("@elementary_pid", NpgsqlDbType.Integer, (int)stream.ElementaryPid);
	        command.Parameters.Add("@ordinal", NpgsqlDbType.Integer);
	        command.Parameters.Add("@iso_639_language_code", NpgsqlDbType.Varchar);
	        command.Parameters.Add("@teletext_type", NpgsqlDbType.Integer);
	        command.Parameters.Add("@teletext_magazine_number", NpgsqlDbType.Integer);
	        command.Parameters.Add("@teletext_page_number", NpgsqlDbType.Integer);

			for (int i = 0; i < teletext.Length; i++)
			{
				command.Parameters["@ordinal"].Value = i;
				command.Parameters["@iso_639_language_code"].Value = teletext[i].Iso639LanguageCode.Replace("\0", ""); ;
				command.Parameters["@teletext_type"].Value = (int)teletext[i].TeletextType;
				command.Parameters["@teletext_magazine_number"].Value = (int)teletext[i].TeletextMagazineNumber;
				command.Parameters["@teletext_page_number"].Value = (int)teletext[i].TeletextPageNumber;
				command.ExecuteNonQuery();
			}
        }

        private void WritePmtStreamSubtitlings(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ushort mappingProgramNumber, ProgramMappingStream stream)
        {
	        if (stream.Subtitlings == null)
		        return;

	        NpgsqlCommand command = conn.CreateCommand();
	        command.CommandText =
		        "insert into dvb_pmt_streams_subtitlings (cnid, ctsid, program_number, elementary_pid, ordinal, iso_639_language_code, subtitling_type, composition_page_id, ancillary_page_id) " +
		        "values " +
		        "(@cnid, @ctsid, @program_number, @elementary_pid, @ordinal, @iso_639_language_code, @subtitling_type, @composition_page_id, @ancillary_page_id)";
	        command.Parameters.AddParameter("@cnid", NpgsqlDbType.Integer, currentNetworkId);
	        command.Parameters.AddParameter("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
	        command.Parameters.AddParameter("@program_number", NpgsqlDbType.Integer, (int)mappingProgramNumber);
	        command.Parameters.AddParameter("@elementary_pid", NpgsqlDbType.Integer, (int)stream.ElementaryPid);
	        command.Parameters.Add("@ordinal", NpgsqlDbType.Integer);
	        command.Parameters.Add("@iso_639_language_code", NpgsqlDbType.Varchar);
	        command.Parameters.Add("@subtitling_type", NpgsqlDbType.Integer);
	        command.Parameters.Add("@composition_page_id", NpgsqlDbType.Integer);
	        command.Parameters.Add("@ancillary_page_id", NpgsqlDbType.Integer);

			for (int i = 0; i < stream.Subtitlings.Length; i++)
	        {
		        SubtitlingDescriptor.Subtitling subtitling = stream.Subtitlings[i];
		        command.Parameters["@ordinal"].Value = i;
		        command.Parameters["@iso_639_language_code"].Value = subtitling.Iso639LanguageCode;
		        command.Parameters["@subtitling_type"].Value = subtitling.SubtitlingType;
		        command.Parameters["@composition_page_id"].Value = (int)subtitling.CompositionPageId;
		        command.Parameters["@ancillary_page_id"].Value = (int)subtitling.AncillaryPageId;
		        command.ExecuteNonQuery();
	        }
        }

        private void WritePmtStreamIpMacNotificationInfo(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ushort mappingProgramNumber, ProgramMappingStream stream)
        {
	        if (stream.IpMacNotificationInfo == null)
		        return;

			NpgsqlCommand cmd = conn.CreateCommand();
			cmd.CommandText = "insert into dvb_pmt_streams_ip_mac_notification_info (cnid, ctsid, program_number, elementary_pid, platform_id,action_type, int_versioning_flag, int_version) " +
				"values (@cnid, @ctsid, @program_number, @elementary_pid, @platform_id, @action_type, @int_versioning_flag, @int_version)";
			cmd.Parameters.AddWithValue("@cnid",NpgsqlDbType.Integer, currentNetworkId);
            cmd.Parameters.AddWithValue("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
            cmd.Parameters.AddWithValue("@program_number", NpgsqlDbType.Integer, (int)mappingProgramNumber);
			cmd.Parameters.AddWithValue("@elementary_pid", NpgsqlDbType.Integer, stream.ElementaryPid);
			cmd.Parameters.Add("@platform_id", NpgsqlDbType.Integer);
            cmd.Parameters.Add("@action_type", NpgsqlDbType.Integer);
            cmd.Parameters.Add("@int_versioning_flag", NpgsqlDbType.Boolean);
            cmd.Parameters.Add("@int_version", NpgsqlDbType.Integer);

            foreach (DataBroadcastIdDescriptor.IpMacPlatform ipMacPlatform in stream.IpMacNotificationInfo)
	        {
				cmd.Parameters["@platform_id"].Value = (int)ipMacPlatform.PlatformId;
                cmd.Parameters["@action_type"].Value = (int)ipMacPlatform.ActionType;
                cmd.Parameters["@int_versioning_flag"].Value = ipMacPlatform.IntVersioningFlag;
                cmd.Parameters["@int_version"].Value = (int)ipMacPlatform.IntVersion;
				cmd.ExecuteNonQuery();
            }
        }

        private void WritePmtStreamFluxmuxChannels(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ushort mappingProgramNumber, ProgramMappingStream stream)
        {
	        if (stream.FlexMuxChannels == null)
		        return;

	        foreach (FmcDescriptor.Fmc flexMuxChannel in stream.FlexMuxChannels)
	        {
		        throw new NotImplementedException();
	        }
        }

        private void WritePmtStreamAudioPreselections(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ushort mappingProgramNumber, ProgramMappingStream stream)
        {
	        if (stream.AudioPreselection == null)
		        return;

	        NpgsqlCommand command = conn.CreateCommand();
	        command.CommandText =
		        "insert into dvb_pmt_streams_audio_preselections (cnid, ctsid, program_number, elementary_pid, preselection_id, audio_rendering_indication, audio_description, spoken_subtitles, dialogue_enhancement, interactivity_enabled, iso_639_language_code,\r\n                                                 message_id, component_tags, future_extension) " +
		        "values " +
		        "(@cnid,@ctsid,@program_number,@elementary_pid,@preselection_id,@audio_rendering_indication,@audio_description,@spoken_subtitles,@dialogue_enhancement,@interactivity_enabled,@iso_639_language_code,@message_id, @component_tags, @future_extension)";
	        command.Parameters.AddWithValue("@cnid", NpgsqlDbType.Integer, currentNetworkId);
	        command.Parameters.AddWithValue("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
	        command.Parameters.AddWithValue("@program_number", NpgsqlDbType.Integer, (int)mappingProgramNumber);
	        command.Parameters.AddWithValue("@elementary_pid", NpgsqlDbType.Integer, stream.ElementaryPid);
	        command.Parameters.Add("@preselection_id", NpgsqlDbType.Integer);
	        command.Parameters.Add("@audio_rendering_indication", NpgsqlDbType.Integer);
	        command.Parameters.Add("@audio_description", NpgsqlDbType.Boolean);
	        command.Parameters.Add("@spoken_subtitles", NpgsqlDbType.Boolean);
	        command.Parameters.Add("@dialogue_enhancement", NpgsqlDbType.Boolean);
	        command.Parameters.Add("@interactivity_enabled", NpgsqlDbType.Boolean);
	        command.Parameters.Add("@iso_639_language_code", NpgsqlDbType.Varchar);
			//@message_id, @component_tags, @future_extension)";
			command.Parameters.Add("@message_id", NpgsqlDbType.Integer);
			command.Parameters.Add("@component_tags", NpgsqlDbType.Bytea);
			command.Parameters.Add("@future_extension", NpgsqlDbType.Bytea);

			foreach (AudioPreselectionDescriptor.AudioPreselection audioPreselection in stream.AudioPreselection)
			{
				command.Parameters["@preselection_id"].Value = audioPreselection.PreselectionId;
				command.Parameters["@audio_rendering_indication"].Value = (int)audioPreselection.AudioRenderingIndication;
				command.Parameters["@audio_description"].Value = audioPreselection.AudioDescription;
				command.Parameters["@spoken_subtitles"].Value = audioPreselection.SpokenSubtitles;
				command.Parameters["@dialogue_enhancement"].Value = audioPreselection.DialogueEnhancement;
				command.Parameters["@interactivity_enabled"].Value = audioPreselection.InteractivityEnabled;
				command.Parameters["@iso_639_language_code"].Value = audioPreselection.Iso639LangaugeCode;
				command.Parameters["@message_id"].Value = audioPreselection.MessageId;
				command.Parameters["@component_tags"].Value = audioPreselection.ComponentTags;
				command.Parameters["@future_extension"].Value = audioPreselection.FutureExtension;
				command.Parameters.CheckNulls();
				command.ExecuteNonQuery();
			}
        }

        private void WritePmtStreamApplications(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ushort mappingProgramNumber, ProgramMappingStream stream)
        {
	        if (stream.Applications == null)
		        return;

	        NpgsqlCommand command = conn.CreateCommand();
	        command.CommandText =
		        "insert into dvb_pmt_streams_applications (cnid, ctsid, program_number, elementary_pid, ordinal, application_type, ait_version_number) " +
		        "values " +
		        "(@cnid, @ctsid, @program_number, @elementary_pid, @ordinal, @application_type, @ait_version_number);";
	        command.Parameters.AddParameter("@cnid", NpgsqlDbType.Integer, currentNetworkId);
	        command.Parameters.AddParameter("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
	        command.Parameters.AddParameter("@program_number", NpgsqlDbType.Integer, (int)mappingProgramNumber);
	        command.Parameters.AddParameter("@elementary_pid", NpgsqlDbType.Integer, (int)stream.ElementaryPid);
	        command.Parameters.Add("@ordinal", NpgsqlDbType.Integer);
	        command.Parameters.Add("@application_type", NpgsqlDbType.Integer);
	        command.Parameters.Add("@ait_version_number", NpgsqlDbType.Integer);
			for (int i = 0; i < stream.Applications.Count; i++)
	        {
		        ApplicationSignallingDescriptor.ApplicationSignal applicationSignal = stream.Applications[i];
		        command.Parameters["@ordinal"].Value = i;
		        command.Parameters["@application_type"].Value = applicationSignal.ApplicationType;
		        command.Parameters["@ait_version_number"].Value = applicationSignal.AitVersionNumber;
		        command.ExecuteNonQuery();
	        }
        }


        private void WritePmtInitialObjectDescriptor(NpgsqlConnection conn, int currentNetworkId, int currentTransportStreamId, ProgramMapping mapping)
        {
	        if (mapping.InitialObjectDescriptor == null)
		        return;

			InitialObjectDescriptor iod = mapping.InitialObjectDescriptor;
			NpgsqlCommand cmd = conn.CreateCommand();
			cmd.CommandText = "insert into dvb_pmt_initial_object_descriptors (cnid, ctsid, program_number,\r\n                                                graphics_profile_level_indication, visual_profile_level_indication,\r\n                                                audio_profile_level_indication, scene_profile_level_indication,\r\n                                                od_profile_level_indication, url_string,\r\n                                                include_inline_profile_level_flag, url_flag, object_descriptor_id) " +
				"values (@cnid, @ctsid, @program_number, @graphics_profile_level_indication, @visual_profile_level_indication, @audio_profile_level_indication, @scene_profile_level_indication, @od_profile_level_indication, @url_string, @include_inline_profile_level_flag, @url_flag, @object_descriptor_id)";
			cmd.Parameters.AddWithValue("@cnid", NpgsqlDbType.Integer, currentNetworkId);
			cmd.Parameters.AddWithValue("@ctsid", NpgsqlDbType.Integer, currentTransportStreamId);
			cmd.Parameters.AddWithValue("@program_number", NpgsqlDbType.Integer, (int)mapping.ProgramNumber);
			cmd.Parameters.AddWithValue("@graphics_profile_level_indication", NpgsqlDbType.Integer, (int?)iod.GraphicsProfileLevelIndication);
            cmd.Parameters.AddWithValue("@visual_profile_level_indication", NpgsqlDbType.Integer, (int?)iod.VisualProfileLevelIndication);
            cmd.Parameters.AddWithValue("@audio_profile_level_indication", NpgsqlDbType.Integer, (int?)iod.AudioProfileLevelIndication);
            cmd.Parameters.AddWithValue("@scene_profile_level_indication", NpgsqlDbType.Integer, (int?)iod.SceneProfileLevelIndication);
            cmd.Parameters.AddWithValue("@od_profile_level_indication", NpgsqlDbType.Integer, (int?)iod.OdProfileLevelIndication);
			//@url_string, @include_inline_profile_level_flag, @url_flag, @object_descriptor_id)";
			cmd.Parameters.AddWithValue("@url_string", NpgsqlDbType.Text, iod.UrlString);
			cmd.Parameters.AddWithValue("@include_inline_profile_level_flag", NpgsqlDbType.Boolean, iod.IncludeInlineProfileLevelFlag);
            cmd.Parameters.AddWithValue("@url_flag", NpgsqlDbType.Boolean, iod.UrlFlag);
            cmd.Parameters.AddWithValue("@object_descriptor_id", NpgsqlDbType.Integer, iod.ObjectDescriptorId);
			cmd.Parameters.CheckNulls();
			cmd.ExecuteNonQuery();
        }


    }
}
