﻿using System.Collections.Generic;
using jgshort.SqlDom.Expressions;
using jgshort.SqlDom.Objects;

namespace jgshort.SqlDom.From
{

    public partial class Table : jgshort.SqlDom.Expressions.Expression
    {
        public class All : Table
        {
            public All() : base() { }
        }
        public class TableAll : Table
        {
            public TableAll() : base() { }
        }

        /*<table_source> ::= {
                table_or_view_name 
                    [ 
                        [ AS ] table_alias 
                    ] 
                    [ <tablesample_clause> ] 
                    [ WITH ( 
                        < table_hint > [ [ , ]...n ] 
                        ) 
                    ] 
            | rowset_function 
                    [ [ AS ] table_alias ] 
                    [ ( 
                        bulk_column_alias [ ,...n ] 
                        ) 
                    ] 
            | user_defined_function [ [ AS ] table_alias ] ]
            | OPENXML <openxml_clause> 
            | derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ] 
            | <joined_table> 
            | <pivoted_table> 
            | <unpivoted_table>
            | @variable [ [ AS ] table_alias ]
            | @variable.function_call ( expression [ ,...n ] ) [ [ AS ] table_alias ] [ (column_alias [ ,...n ] ) ]
        }*/

        private TableJoin join = null;

        public static Table Default()
        {
            return new Table();
        }
        public static Table Default(string name)
        {
            return new Table(name);
        }
        public static Table Default(string name, string alias)
        {
            return new Table(name, alias);
        }
        public static Table Default(string name, string alias, ClauseTableSample tableSampleClause)
        {
            return new Table(name, alias, tableSampleClause);
        }
        public static Table Default(string name, string alias, ClauseTableSample tableSampleClause, TableHint tableHints)
        {
            return new Table(name, alias, tableSampleClause, tableHints);
        }

        public Table()
        {
            Schema = Schema.Dbo;
        }
        public Table(string name)
            : this(Schema.Dbo, name)
        {
            
        }
        public Table(string name, string alias)
            : this(Schema.Dbo, name, alias)
        {
            //
        }
        public Table(string name, string alias, ClauseTableSample tableSampleClause)
            : this(Schema.Dbo, name, alias, tableSampleClause)
        {
            //
        }
        public Table(string name, string alias, ClauseTableSample tableSampleClause, TableHint tableHints)
            : this(Schema.Dbo, name, alias, tableSampleClause, tableHints)
        {
            //
        }
        public Table(string name, string alias, TableHint tableHints)
            : this(name, alias)
        {
            TableHints = tableHints;
        }
        public Table(Schema schema, string name) 
        {
            Name = name;
            Schema = schema;
        }
        public Table(Schema schema, string name, string alias)
            : this(schema, name)
        {
            Alias = alias;
        }
        public Table(Schema schema, string name, string alias, ClauseTableSample tableSampleClause)
            : this(schema, name, alias)
        {
            SampleClause = tableSampleClause;
        }
        public Table(Schema schema, string name, string alias, ClauseTableSample tableSampleClause, TableHint tableHints)
            : this(schema, name, alias, tableSampleClause)
        {
            TableHints = tableHints;
        }
        public Table(Schema schema, string name, string alias, TableHint tableHints)
            : this(schema, name, alias, null, tableHints)
        {
            //
        }

        public Schema Schema { get; protected set; }
        public string Name { get; protected set; }
        public string Alias { get; protected set; }
        public ClauseTableSample SampleClause { get; protected set; }
        public TableHint TableHints { get; protected set; }
        public TableJoin Join
        {
            get
            {
                if (join == null) join = new TableJoin(this);
                return join;
            }
            protected set
            {
                join = value;
            }
        }

        public Column this[string columnName]
        {
            get
            {
                return new Column(this, columnName);
            }
        }
        public Column Column(string columnName)
        {
            return new Column(this, columnName);
        }

        public static List<Table> List(params Table[] tables)
        {
            return new List<Table>(tables);
        }
    }
}
