/*
 * Command.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;

namespace LipSync {

    public class Command {
        public TimeTableType target;
        public CommandType type;
        public TimeTableEntry item;
        public TimeTable table;
        public TimeTableGroup tablegroup;
        public Image image;
        public Point position;
        public int group;
        public int track;
        public int entry;
        public string str;
        public float floatValue;
        public Size size;
        public Telop telop;
        public uint dwRate;
        public uint dwScale;
        public Color color;
        public Command child;
        public object[] args;

        public static Command GCommandChangeBackgroundColor( Color color ){
            Command ret = new Command();
            ret.target = TimeTableType.whole;
            ret.type = CommandType.changeBackgroundColor;
            ret.color = color;
            return ret;
        }

        public static Command GCommandAddTelop( Telop telop ) {
            Command ret = new Command();
            ret.target = TimeTableType.telop;
            ret.type = CommandType.addTelop;
            if ( telop != null ) {
                ret.telop = (Telop)telop.Clone();
            }
            return ret;
        }

        public static Command GCommandAddTelopRange( Telop[] telops ) {
            Command ret = new Command();
            ret.target = TimeTableType.telop;
            ret.type = CommandType.addTelopRange;
            ret.args = new object[1];
            Telop[] add = new Telop[telops.Length];
            for ( int i = 0; i < add.Length; i++ ) {
                add[i] = (Telop)telops[i].Clone();
            }
            ret.args[0] = add;
            return ret;
        }

        public static Command GCommandEditTelop( int id, Telop telop ) {
            Command ret = new Command();
            ret.target = TimeTableType.telop;
            ret.type = CommandType.editTelop;
            ret.entry = id;
            if ( telop != null ) {
                ret.telop = (Telop)telop.Clone();
            }
            return ret;
        }

        public static Command GCommandDeleteTelop( Telop item ) {
            Command ret = new Command();
            ret.target = TimeTableType.telop;
            ret.type = CommandType.deleteTelop;
            ret.telop = (Telop)item.Clone();
            return ret;
        }

        public static Command GCommandDeleteTelopRange( Telop[] items ) {
            Command ret = new Command();
            ret.target = TimeTableType.telop;
            ret.type = CommandType.deleteTelopRange;
            ret.args = new object[1];
            Telop[] items2 = new Telop[items.Length];
            for ( int i = 0; i < items2.Length; i++ ) {
                items2[i] = (Telop)items[i].Clone();
            }
            ret.args[0] = items2;
            return ret;
        }

        public static Command GCommandDeleteTimeTableGroup( TimeTableType target, int group ) {
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.deleteGroup;
            ret.group = group;
            return ret;
        }

        public static Command GCommandDeleteTimeTable( TimeTableType target, int group, int track ) {
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.deleteTimeTable;
            ret.group = group;
            ret.track = track;
            return ret;
        }

        public static Command GCommandSetMp3( string file_name ){
            Command ret = new Command();
            ret.target = TimeTableType.whole;
            ret.type = CommandType.setMP3;
            ret.str = file_name;
            return ret;
        }

        public static Command GCommandChangeVideoSize( Size size ){
            Command ret = new Command();
            ret.target = TimeTableType.whole;
            ret.type = CommandType.changeVideoSize;
            ret.size = size;
            return ret;
        }

        public static Command GCommandShiftTimeTable( TimeTableType target, int track, float floatValue ){
            Command ret = new Command();
            ret.target = target;
            if ( target == TimeTableType.character ) {
                ret.group = track;
            } else {
                ret.track = track;
            }
            ret.type = CommandType.shiftTimeTable;
            ret.floatValue = floatValue;
            return ret;
        }

        public static Command GCommandChangeFps( uint rate, uint scale ){
            Command ret = new Command();
            ret.target = TimeTableType.whole;
            ret.type = CommandType.changeFps;
            ret.dwRate = rate;
            ret.dwScale = scale;
            return ret;
        }

        public static Command GCommandChangeScale( TimeTableType target, int group, int track, float scale ){
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.changeScale;
            ret.group = group;
            ret.track = track;
            ret.floatValue = scale;
            return ret;
        }

        public static Command GCommandChangePluginConfig( int track, string config ) {
            Command ret = new Command();
            ret.target = TimeTableType.whole;
            ret.type = CommandType.changePluginConfig;
            ret.track = track;
            ret.str = config;
            return ret;
        }

        public static Command GCommandSetAvi( int track, string file_name ){
            Command ret = new Command();
            ret.target = TimeTableType.another;
            ret.type = CommandType.setAvi;
            ret.track = track;
            ret.str = file_name;
            return ret;
        }

        public static Command GCommandEditTimeTableEntry( TimeTableType target, int group, int track, int entry, TimeTableEntry item ) {
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.editEntry;
            ret.group = group;
            ret.track = track;
            ret.entry = entry;
            if ( item != null ) {
                ret.item = (TimeTableEntry)item.Clone();
            }
            return ret;
        }

        public static Command GCommandAddTimeTableEntry( TimeTableType target, int group, int track, TimeTableEntry item ) {
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.addEntry;
            ret.group = group;
            ret.track = track;
            if ( item != null ) {
                ret.item = (TimeTableEntry)item.Clone();
            }
            return ret;
        }

        public static Command GCommandDeleteTimeTableEntry( TimeTableType target, int group, int track, TimeTableEntry item ) {
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.deleteEntry;
            ret.group = group;
            ret.track = track;
            if ( item != null ) {
                ret.item = (TimeTableEntry)item.Clone();
            }
            return ret;
        }
        
        public static Command GCommandEditTimeTable( TimeTableType target, int group, int track, TimeTable table ) {
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.editTimeTable;
            ret.group = group;
            ret.track = track;
            if ( table != null ) {
                ret.table = (TimeTable)table.Clone();
            }
            return ret;
        }

        public static Command GCommandAddTimeTable( TimeTableType target, int group, int track, TimeTable table ){
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.addTimeTable;
            ret.group = group;
            ret.track = track;
            if ( table != null ) {
                ret.table = (TimeTable)table.Clone();
            }
            return ret;
        }

        public static Command GCommandEditGroup( TimeTableType target, int group,  TimeTableGroup table_group ) {
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.editGroup;
            ret.group = group;
            ret.tablegroup = (TimeTableGroup)table_group.Clone();
            return ret;
        }

        public static Command GCommandAddGroup( TimeTableType target, int group, TimeTableGroup tablegroup ){
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.addGroup;
            ret.group = group;
            if ( tablegroup != null ) {
                ret.tablegroup = (TimeTableGroup)tablegroup.Clone();
            } else {
                ret.tablegroup = null;
            }
            return ret;
        }

        public static Command GCommandSetImage( int track, Image img ){
            Command ret = new Command();
            ret.target = TimeTableType.another;
            ret.type = CommandType.setImage;
            ret.track = track;
            if ( img != null ) {
                ret.image = (Image)img.Clone();
            } else {
                ret.image = null;
            }
            return ret;
        }
        
        public static Command GCommandSetPosition( TimeTableType target, int group, int track, Point position ){
            Command ret = new Command();
            ret.target = target;
            ret.type = CommandType.setPosition;
            ret.group = group;
            ret.track = track;
            ret.position = position;
            return ret;
        }

        public static Command GCommandNothing() {
            Command ret = new Command();
            ret.target = TimeTableType.none;
            return ret;
        }

        private Command() {
        }

        public override string ToString() {
            string res = "";
            res += target.ToString();
            res += "," + type.ToString();
            res += ",group=" + group + ",track=" + track + ";entry=" + entry;

            if ( item == null ) {
                res += ";item=null";
            } else {
                res += ";item={begin=" + item.begin + ",end=" + item.end + ",body=" + item.body;
            }
            return res;
        }
    }

}
