1 module dscord.types.channel;
2 
3 import std.stdio,
4        std.variant,
5        core.vararg;
6 
7 import dscord.client,
8        dscord.voice.client,
9        dscord.types.all;
10 
11 alias ChannelMap = ModelMap!(Snowflake, Channel);
12 alias PermissionOverwriteMap = ModelMap!(Snowflake, PermissionOverwrite);
13 
14 enum PermissionOverwriteType {
15 	ROLE = 1 << 0,
16 	MEMBER = 1 << 1,
17 }
18 
19 class PermissionOverwrite : IModel {
20   mixin Model;
21 
22 	Snowflake  id;
23   Channel    channel;
24 
25   // Overwrite type
26 	PermissionOverwriteType  type;
27 
28 	// Permissions
29 	Permission  allow;
30 	Permission  deny;
31 
32   this(Channel channel, ref JSON obj) {
33     this.channel = channel;
34     super(channel.client, obj);
35   }
36 
37   override void load(ref JSON obj) {
38     obj.keySwitch!(
39       "id", "allow", "deny", "type"
40     )(
41       { this.id = readSnowflake(obj); },
42       { this.allow = Permission(obj.read!uint); },
43       { this.deny = Permission(obj.read!uint); },
44       { this.type = obj.read!string == "role" ?
45         PermissionOverwriteType.ROLE :
46         PermissionOverwriteType.MEMBER;
47       },
48     );
49   }
50 
51   Snowflake getID() {
52     return this.id;
53   }
54 }
55 
56 class Channel : IModel {
57   mixin Model;
58 
59   Snowflake    id;
60   string       name;
61   string       topic;
62   Guild        guild;
63   Snowflake    lastMessageID;
64   short        position;
65   uint         bitrate;
66   User         recipient;
67   string       type;
68   bool         isPrivate;
69 
70   // Overwrites
71   PermissionOverwriteMap  overwrites;
72 
73   // Voice Connection
74   VoiceClient  vc;
75 
76   this(Client client, ref JSON obj) {
77     super(client, obj);
78   }
79 
80   this(Guild guild, ref JSON obj) {
81     this.guild = guild;
82     super(guild.client, obj);
83   }
84 
85   override void init() {
86     this.overwrites = new PermissionOverwriteMap;
87   }
88 
89   override void load(ref JSON obj) {
90     obj.keySwitch!(
91       "id", "name", "topic", "guild_id", "last_message_id", "position",
92       "bitrate", "is_private", "type", "permission_overwrites",
93     )(
94       { this.id = readSnowflake(obj); },
95       { this.name = obj.read!string; },
96       { this.topic = obj.read!string; },
97       { this.guild = this.client.state.guilds.get(readSnowflake(obj)); },
98       { this.lastMessageID = readSnowflake(obj); },
99       { this.position = obj.read!short; },
100       { this.bitrate = obj.read!uint; },
101       { this.isPrivate = obj.read!bool; },
102       { this.type = obj.read!string; },
103       {
104         loadManyComplex!(Channel, PermissionOverwrite)(this, obj, (p) { this.overwrites[p.id] = p; });
105       },
106     );
107   }
108 
109   Snowflake getID() {
110     return this.id;
111   }
112 
113   void sendMessage(string content, string nonce=null, bool tts=false) {
114     this.client.api.sendMessage(this.id, content, nonce, tts);
115   }
116 
117   @property bool DM() {
118     return this.isPrivate;
119   }
120 
121   @property bool voice() {
122     return this.type == "voice";
123   }
124 
125   @property bool text() {
126     return this.type == "text";
127   }
128 
129   @property auto voiceStates() {
130     return this.guild.voiceStates.filter(c => c.channelID == this.id);
131   }
132 
133   VoiceClient joinVoice() {
134     this.vc = new VoiceClient(this);
135     return this.vc;
136   }
137 }