-
Notifications
You must be signed in to change notification settings - Fork 0
/
TransactionManager.swift
176 lines (117 loc) · 5.28 KB
/
TransactionManager.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//
// EETransactionManager.swift
// galexy
//
// Created by Tony Thomas on 02/05/16.
// Copyright © 2016 Tony Thomas. All rights reserved.
//
import Foundation
//MARK: class oEETransactionManager
/**
This class implements the buisiness logic.
*/
class TransactionManager : ArabicConverter{
//MARK: properties
//The dictionary of galaxy numerals and their face value eg: glob : GalaxyNumeral
var galaxyNumerals = [String:GalaxyNumeral] ()
//Dictionary of metals and their credit per unit quantity eg Gold : 10000
var metalCreditMap = [String:ArabicNumber]()
//Query reult map, this is to display the result corresponding to each query
var queryResultMap = [String : String]()
//The input array of strngs
var inputs = [String]()
//MARK: methods
/*
Processes basic query and extracts the numerals and metal eg : blog proc silver then send it
to nextstep of processing.
- parameter string: input , it can be any thing that follows some basic patern
*/
func addInput(string : String){
inputs.append(string)
}
/*
clear all states for repeated testing of input
*/
func clearState(){
galaxyNumerals = [String:GalaxyNumeral] ()
metalCreditMap = [String:ArabicNumber]()
queryResultMap = [String : String]()
inputs = [String]()
}
/*
Processes basic query and extracts the numerals and metal eg : blog proc silver then send it
to nextstep of processing.
- parameter callback: closure for completion notification, this faclitate a loose coupling
with the user interface
*/
func runTest(resultCallback callback :([String])->()){
//The inputs are processed using regular expressions and finds diffrent patters
//then process each type accordingly
for input in inputs{
let result = StringParser.parseInput(input)
guard result != nil else{
queryResultMap[input] = "I have no idea what you are talking about"
continue
}
switch (result!){
case (.TypeMap , let string):
let galaxyNumeral = GalaxyNumeral(galexyArabicMap: string)
galaxyNumerals[galaxyNumeral.faceName] = galaxyNumeral;
case (.TypeCredit , let string):
processAndStoreCreditDetails(string)
case (.TypeCountMuch , let queryString):
let howMuchQueryAnalyser = QueryAnalyserMuch()
howMuchQueryAnalyser.processQuery(queryString, withTransactionManager: self)
case (.TypeCountMany , let queryString):
let howManyQueryAnalyser = QueryAnalyserMany()
howManyQueryAnalyser.processQuery(queryString, withTransactionManager: self)
}
}
//result is formatted and sent to the view
callback(queryResultMap.map({ $0.0 + "\n" + $0.1 }))
}
/*
Processes a statement with credit details of metals and finds the unit price for each metal.
The reult is kept in a dictionary , eg Silver : 150
- parameter input: a statement of type "glob glob Silver is 34 Credits"
*/
func processAndStoreCreditDetails(input : String){
//input : glob glob Silver is 34 Credits
let formattedInput = StringParser.removePatternFromText(input, pattenOfInterest:
"(is\\s+)|(credits\\s*)")
guard formattedInput != nil else {
Log.print("The credit query could not refine")
return
}
/*
formattedInput : glob glob Silver 34
the components are
1 glob glob ---> convert to GalaxyNumber
2 Silver ---> Metal
3 34 ---> Credits in arabic
*/
let elements = formattedInput!.componentsSeparatedByString(" ").filter { !$0.isEmpty }
guard elements.count > 2 else{
Log.print("The credit query did not contain galaxy numerals")
return
}
let metal = elements[elements.count-2];
let creditsForMetal = Double(elements.last!)
guard creditsForMetal > 0 else {
Log.print("The credit for metal is 0, so the metal is useless")
return
}
var numerals = [GalaxyNumeral]()
for index in 0...elements.count-3 {
let string = elements[index]
if let numeral = galaxyNumerals[string]{
numerals.append(numeral)
}
}
if let countOfMetal = arabicNumberFromGalaxyNumerals(numerals){
let priceOfUnitMetal = creditsForMetal!/countOfMetal.rawValue
metalCreditMap[metal] = ArabicNumber(rawValue: priceOfUnitMetal)
return
}
}
}