/*
 * FormSetFrameRate.cs
 * Copyright (c) 2007-2009 kbinani
 *
 * This file is part of LipSync.
 *
 * LipSync is free software; you can redistribute it and/or
 * modify it under the terms of the BSD License.
 *
 * LipSync 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.
 */
using System;
using System.Drawing;
using System.Windows.Forms;

using Boare.Lib.AppUtil;
using Boare.Lib.Media;

namespace LipSync {

    public partial class FormSetFrameRate : Form, IMultiLanguageControl {
        private uint m_dwRate = 30;
        private uint m_dwScale = 1;
        private bool m_expanded = false;
        private bool m_forbid_text_change = false;

        const int HEIGHT_EXPANDED = 224;
        const int HEIGHT_FOLDED = 160;

        public FormSetFrameRate( uint rate, uint scale ) {
            InitializeComponent();
            ApplyLanguage();
            ApplyFont( AppManager.Config.Font.GetFont() );
            m_expanded = false;
            txtFrameRate.Enabled = !m_expanded;
            txtNumerator.Enabled = m_expanded;
            txtDenominator.Enabled = m_expanded;
            btnImport.Enabled = m_expanded;
            this.Height = HEIGHT_FOLDED;
            m_dwRate = rate;
            m_dwScale = scale;
            txtDenominator.Text = m_dwScale + "";
            txtNumerator.Text = m_dwRate + "";
            m_forbid_text_change = true;  // 最初に約分が発生するのを防ぐ
            txtFrameRate.Text = (float)m_dwRate / (float)m_dwScale + "";
            m_forbid_text_change = false;
        }

        public void ApplyFont( Font font ) {
            this.Font = font;
            foreach ( Control c in this.Controls ) {
                Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font );
            }
        }

        public static string _( string s ) {
            return Messaging.GetMessage( s );
        }

        public void ApplyLanguage() {
            btnExpand.Text = " " + _( "detail" );
            this.Text = _( "configure frame rate" );
            lblFrameRate.Text = _( "Frame rate" );
            btnOK.Text = _( "OK" );
            btnCancel.Text = _( "Cancel" );
            lblDenominator.Text = _( "denominator of frame rate" );
            lblNumerator.Text = _( "numerator of frame rate" );
            btnImport.Text = _( "Import" );
            toolTipImport.SetToolTip( btnImport, _( "import frame rate from AVI file" ) );
        }

        /// <summary>
        /// 有理数で表したフレームレートの分子の値を取得または設定します
        /// </summary>
        public uint DwRate {
            get {
                return m_dwRate;
            }
        }

        /// <summary>
        /// 有理数で表したフレームレートの分母の値を取得または設定します
        /// </summary>
        public uint DwScale {
            get {
                return m_dwScale;
            }
        }

        private void btnExpand_Click( object sender, EventArgs e ) {
            m_expanded = !m_expanded;
            txtFrameRate.Enabled = !m_expanded;
            txtNumerator.Enabled = m_expanded;
            txtDenominator.Enabled = m_expanded;
            btnImport.Enabled = m_expanded;
            if ( m_expanded ) {
                btnExpand.Image = LipSync.Properties.Resources.opened;
                this.Height = HEIGHT_EXPANDED;
            } else {
                btnExpand.Image = LipSync.Properties.Resources.closed;
                this.Height = HEIGHT_FOLDED;
            }
        }

        private void txtFrameRate_TextChanged( object sender, EventArgs e ) {
            if ( m_forbid_text_change ) {
                return;
            }
            if ( !m_expanded ) {
                try {
                    float fps = Math.Abs( float.Parse( txtFrameRate.Text ) );
                    m_dwScale = 1000;
                    m_dwRate = (uint)(fps * m_dwScale);
                    uint gcd = (uint)Common.GetGCD( m_dwRate, m_dwScale );
                    if ( gcd > 1 ) {
                        m_dwScale = m_dwScale / gcd;
                        m_dwRate = m_dwRate / gcd;
                    }
                    txtNumerator.Text = m_dwRate + "";
                    txtDenominator.Text = m_dwScale + "";
                }catch{
                }
            }
        }

        private void txtNumerator_TextChanged( object sender, EventArgs e ) {
            try {
                uint num = uint.Parse( txtNumerator.Text );
                m_dwRate = num;
                m_forbid_text_change = true;
                txtFrameRate.Text = ((float)m_dwRate / (float)m_dwScale) + "";
                m_forbid_text_change = false;
            } catch {
            }
        }

        private void txtDenominator_TextChanged( object sender, EventArgs e ) {
            try {
                uint den = uint.Parse( txtDenominator.Text );
                m_dwScale = den;
                m_forbid_text_change = true;
                txtFrameRate.Text = ((float)m_dwRate / (float)m_dwScale) + "";
                m_forbid_text_change = false;
            } catch {
            }
        }

        private void btnImport_Click( object sender, EventArgs e ) {
            using ( OpenFileDialog dlg = new OpenFileDialog() ) {
                try {
                    dlg.Filter = _( "Avi file(*.avi)|*.avi" ) + "|" + 
                                 _( "All Files(*.*)|*.*" );
                } catch {
                    dlg.Filter = "Avi file(*.avi)|*.avi|All Files(*.*)|*.*";
                }
                if ( dlg.ShowDialog() == DialogResult.OK ) {
                    AviReader ar = new AviReader();
                    try {
                        ar.Open( dlg.FileName );
                        m_dwRate = ar.dwRate;
                        m_dwScale = ar.dwScale;
                        ar.Close();
                        txtNumerator.Text = m_dwRate + "";
                        txtDenominator.Text = m_dwScale + "";
                    } catch {
                        MessageBox.Show(
                            _( "failed getting frame rate" ),
                            _( "Error" ),
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
                        if ( ar.Opened ) {
                            try {
                                ar.Close();
                            } catch {
                            }
                        }
                    }
                }
            }
        }

        private void btnOK_Click( object sender, EventArgs e ) {
            DialogResult = DialogResult.OK;
        }
    }

}
